1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
(* src/package_manager/package_types.ml *)
(* Types for T package and project metadata *)
(** A dependency on another T package *)
type dependency = {
dep_name : string;
git_url : string;
tag : string;
}
(** Package metadata parsed from DESCRIPTION.toml *)
type package_config = {
name : string;
version : string;
description : string;
authors : string list;
license : string;
homepage : string;
repository : string;
dependencies : dependency list;
min_t_version : string;
additional_tools : string list;
latex_packages : string list;
}
(** Project metadata parsed from tproject.toml *)
type project_config = {
proj_name : string;
proj_description : string;
proj_dependencies : dependency list;
proj_r_dependencies : string list;
proj_py_dependencies : string list;
proj_py_version : string;
proj_visualization_tool : string;
proj_min_t_version : string;
proj_nixpkgs_date : string;
proj_additional_tools : string list;
proj_latex_packages : string list;
}
(** CLI options for scaffolding commands *)
type scaffold_options = {
target_name : string;
author : string;
license : string;
nixpkgs_date : string;
no_git : bool;
force : bool;
interactive : bool;
agent_context : string;
}
(** Default scaffold options *)
let default_options name =
let t = Unix.gmtime (Unix.gettimeofday ()) in
let today = Printf.sprintf "%04d-%02d-%02d" (1900 + t.Unix.tm_year) (t.Unix.tm_mon + 1) t.Unix.tm_mday in
{
target_name = name;
author = "Your Name <email@example.com>";
license = "EUPL-1.2";
nixpkgs_date = today;
no_git = false;
force = false;
interactive = false;
agent_context = "medium";
}
(** Default package config *)
let default_package_config name = {
name;
version = "0.1.0";
description = "A T package";
authors = ["Your Name <email@example.com>"];
license = "EUPL-1.2";
homepage = "";
repository = "";
dependencies = [];
min_t_version = Version.version;
additional_tools = [];
latex_packages = [];
}
(** Default project config *)
let default_project_config name = {
proj_name = name;
proj_description = "A T data analysis project";
proj_dependencies = [];
proj_r_dependencies = [];
proj_py_dependencies = [];
proj_py_version = "python314";
proj_visualization_tool = "";
proj_min_t_version = Version.version;
proj_nixpkgs_date = (let t = Unix.gmtime (Unix.gettimeofday ()) in
Printf.sprintf "%04d-%02d-%02d" (1900 + t.Unix.tm_year) (t.Unix.tm_mon + 1) t.Unix.tm_mday);
proj_additional_tools = [];
proj_latex_packages = [];
}
(** Validate a package/project name: lowercase, alphanumeric, hyphens only *)
let validate_name name =
let len = String.length name in
if len = 0 then Error "Name cannot be empty"
else if len > 64 then Error "Name cannot exceed 64 characters"
else
let valid = ref true in
for i = 0 to len - 1 do
let c = name.[i] in
if not (c >= 'a' && c <= 'z' || c >= '0' && c <= '9' || c = '-' || c = '_') then
valid := false
done;
if name.[0] = '-' || name.[0] = '_' then
Error "Name must start with a letter or digit"
else if not !valid then
Error "Name must contain only lowercase letters, digits, hyphens, or underscores"
else
Ok name