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