···89## Commands
10- `tlp new <name>`: Creates a new local package with the given name in the current directory and links it.
011- `tlp path <name>`: Get the full path to the local package with the given name (in case you forgot, or need it for other automation)
12- `tlp bump <name> [--major|--patch]`: Increase the version of the local package with the given name.
13 This will create a new git tag for the latest version,
14 then increase said version by modifying the `typst.toml` and renaming the latest-version symlink,
15 and finally add a new `git worktree` for the previously latest version.
01617All commands support the `--package-path` option (also available via the `TYPST_PACKAGE_PATH` env variable),
18which works exactly like it does in `typst` to specify where to look instead of (the equivalent of) `~/.local/share/typst/packages`.
···2324Alternatively, you can compile this program with the `git2` feature;
25Then, it will use `libgit2` instead of invoking `git`, so the `--git` option will have no effect.
00000
···89## Commands
10- `tlp new <name>`: Creates a new local package with the given name in the current directory and links it.
11+- `tlp init`: Creates a new local package with the name from typst.toml in the current directory. Also initializes a git repository, if not one already.
12- `tlp path <name>`: Get the full path to the local package with the given name (in case you forgot, or need it for other automation)
13- `tlp bump <name> [--major|--patch]`: Increase the version of the local package with the given name.
14 This will create a new git tag for the latest version,
15 then increase said version by modifying the `typst.toml` and renaming the latest-version symlink,
16 and finally add a new `git worktree` for the previously latest version.
17+- `tlp rm <name>`: Removes the local package with the given name.
1819All commands support the `--package-path` option (also available via the `TYPST_PACKAGE_PATH` env variable),
20which works exactly like it does in `typst` to specify where to look instead of (the equivalent of) `~/.local/share/typst/packages`.
···2526Alternatively, you can compile this program with the `git2` feature;
27Then, it will use `libgit2` instead of invoking `git`, so the `--git` option will have no effect.
28+29+30+## ToDo
31+- [ ] `tlp init`: Populate a version for each tag
32+- [ ] `tlp init`: Check if there are any `@local/` in the whole code, check if they are available, if not print warnings.
+8
src/args.rs
···20 /// The name of the local package
21 name: String,
22 },
0023 /// Print the path of a local package
24 #[clap(name = "path")]
25 PrintPath {
···36 /// Increase the patch instead of the minor version
37 #[clap(long)]
38 patch: bool,
00000039 },
40}
···20 /// The name of the local package
21 name: String,
22 },
23+ /// Initialize a local package
24+ Init {},
25 /// Print the path of a local package
26 #[clap(name = "path")]
27 PrintPath {
···38 /// Increase the patch instead of the minor version
39 #[clap(long)]
40 patch: bool,
41+ },
42+ /// Remove a local package
43+ #[clap(name = "rm")]
44+ Remove {
45+ /// The name of the local package
46+ name: String,
47 },
48}
+58
src/main.rs
···81 eprintln!("which is linked to {pkg_dir:?}");
82 eprintln!("you can import it with `#import \"@local/{name}:0.1.0\"`");
83 }
0000000000000000000000000084 PrintPath { name } => {
85 verify_name(&name)?;
86 let pkg_dir = packages_local.join(&name);
···155 .whatever_context("failed to commit typst.toml")?;
156 eprintln!("bumped version of local package {name:?} from {old_ver} to {new_ver}.");
157 }
000000000000000158 }
159160 Ok(())
00000000000000000161}
162163fn extract_version(typst_toml: &Path) -> Result<[u32; 3], Whatever> {
···81 eprintln!("which is linked to {pkg_dir:?}");
82 eprintln!("you can import it with `#import \"@local/{name}:0.1.0\"`");
83 }
84+ Init {} => {
85+ println!("The current directory is {}", current_dir.display());
86+ let typst_toml = current_dir.join("typst.toml");
87+ let name = extract_name(&typst_toml).whatever_context("failed to get package name")?;
88+ verify_name(&name)?;
89+ let ver =
90+ extract_version(&typst_toml).whatever_context("failed to get package version")?;
91+ let current_ver = format!("{}.{}.{}", ver[0], ver[1], ver[2]);
92+ let pkg_dir = packages_local.join(&name);
93+ if pkg_dir.exists() {
94+ whatever!("a local package called {name:?} already exists");
95+ }
96+ fs_err::create_dir(&pkg_dir).whatever_context("failed to create package directory")?;
97+ if !current_dir.join(".git").exists() {
98+ eprintln!("Initializing git in the current repo!");
99+ git::init(¤t_dir, &git).whatever_context("failed to create repository")?;
100+ git::commit(¤t_dir, "*", "Initial commit", &git, true)
101+ .whatever_context("failed to create initial commit")?;
102+ }
103+ symlink_dir(¤t_dir, &pkg_dir.join("source"))
104+ .whatever_context("failed to create latest version symlink")?;
105+ symlink_dir(¤t_dir, &pkg_dir.join(¤t_ver))
106+ .whatever_context("failed to create latest version symlink")?;
107+ eprintln!("linked current directory to {pkg_dir:?}");
108+ eprintln!("you can import it with `#import \"@local/{name}:{current_ver}\"`");
109+ }
110 PrintPath { name } => {
111 verify_name(&name)?;
112 let pkg_dir = packages_local.join(&name);
···181 .whatever_context("failed to commit typst.toml")?;
182 eprintln!("bumped version of local package {name:?} from {old_ver} to {new_ver}.");
183 }
184+ Remove { name } => {
185+ verify_name(&name)?;
186+ let pkg_dir = packages_local.join(&name);
187+ if !pkg_dir.exists() {
188+ whatever!("no local package {name:?} found");
189+ }
190+ if !pkg_dir.join("source").is_symlink() {
191+ whatever!(
192+ "could not find the source code! Might not be added by tlp, remove aborted."
193+ )
194+ }
195+ fs_err::remove_dir_all(pkg_dir)
196+ .whatever_context("failed to remove the package directory")?;
197+ println!("Removed local package: {name:?}");
198+ }
199 }
200201 Ok(())
202+}
203+204+fn extract_name(typst_toml: &Path) -> Result<String, Whatever> {
205+ let file = fs_err::read_to_string(typst_toml)
206+ .whatever_context("could not find a typst.toml file the current directory")?;
207+ let pkg = toml::from_str::<toml::Table>(&file).whatever_context("failed to parse file")?;
208+ let name = pkg
209+ .get("package")
210+ .whatever_context("no `[package]` table")?
211+ .as_table()
212+ .whatever_context("`package` is not a table")?
213+ .get("name")
214+ .whatever_context("`[package]` table has no `name` key")?
215+ .as_str()
216+ .whatever_context("`package.name` is not a string")?;
217+ // name.whatever_context("invalid `package.version`")
218+ Ok(name.to_string())
219}
220221fn extract_version(typst_toml: &Path) -> Result<[u32; 3], Whatever> {