dev_scripts/cli.rs
1use std::{fmt::Display, path::PathBuf};
2
3use alpm_types::{MetadataFileName, PKGBUILD_FILE_NAME, SRCINFO_FILE_NAME};
4use clap::{Parser, ValueEnum};
5
6use crate::sync::PackageRepositories;
7
8#[derive(Debug, Parser)]
9#[clap(name = "dev-scripts", about = "Dev scripts for the ALPM project")]
10pub struct Cli {
11 /// Log verbosity level
12 #[command(flatten)]
13 pub verbose: clap_verbosity_flag::Verbosity,
14
15 #[clap(subcommand)]
16 pub cmd: Command,
17}
18
19#[derive(Debug, Parser)]
20pub enum Command {
21 /// Tests file formats with real-world files from official repositories.
22 TestFiles {
23 #[clap(subcommand)]
24 cmd: TestFilesCmd,
25
26 #[arg(
27 help = "The directory to use for download and test artifacts",
28 long,
29 long_help = r#"The directory to use for download and test artifacts.
30
31If unset, defaults to "$XDG_CACHE_HOME/alpm/testing/".
32If "$XDG_CACHE_HOME" is unset, falls back to "~/.cache/alpm/testing/"."#,
33 short,
34 value_name = "DIR"
35 )]
36 cache_dir: Option<PathBuf>,
37 },
38
39 /// Run the `alpm-pkgbuild srcinfo format` command on a PKGBUILD and compare its output with a
40 /// given .SRCINFO file.
41 CompareSrcinfo {
42 /// Path to the PKGBUILD file.
43 #[arg(
44 short,
45 long = "pkgbuild",
46 value_name = "PKGBUILD_PATH",
47 default_value = format!("./{PKGBUILD_FILE_NAME}")
48 )]
49 pkgbuild_path: PathBuf,
50
51 /// Path to the .SRCINFO file.
52 #[arg(
53 short,
54 long = "srcinfo",
55 value_name = "SRCINFO_PATH",
56 default_value = format!("./{SRCINFO_FILE_NAME}")
57 )]
58 srcinfo_path: PathBuf,
59 },
60}
61
62#[derive(Clone, Copy, Debug, Eq, Parser, PartialEq, ValueEnum)]
63pub enum TestFileType {
64 BuildInfo,
65 SrcInfo,
66 PackageInfo,
67 MTree,
68 RemoteDesc,
69 RemoteFiles,
70 LocalDesc,
71 LocalFiles,
72 Signatures,
73}
74
75impl Display for TestFileType {
76 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
77 write!(
78 f,
79 "{}",
80 match self {
81 Self::BuildInfo => MetadataFileName::BuildInfo.as_ref(),
82 Self::PackageInfo => MetadataFileName::PackageInfo.as_ref(),
83 Self::SrcInfo => SRCINFO_FILE_NAME,
84 Self::MTree => MetadataFileName::Mtree.as_ref(),
85 Self::RemoteDesc | Self::LocalDesc => "desc",
86 Self::RemoteFiles | Self::LocalFiles => "files",
87 Self::Signatures => "sig",
88 }
89 )
90 }
91}
92
93#[derive(Debug, Parser)]
94pub enum TestFilesCmd {
95 /// Run tests against a specific file type.
96 ///
97 /// The required data needs to be downloaded up front using "dev-scripts test-files download".
98 Test {
99 /// Package repositories to test.
100 ///
101 /// If not set, all official repositories are tested.
102 #[arg(short, long)]
103 repositories: Option<Vec<PackageRepositories>>,
104
105 /// The type of file that should be tested.
106 file_type: TestFileType,
107 },
108
109 /// Download/synchronize files for testing to this machine.
110 ///
111 /// Each type of file can be downloaded individually.
112 Download {
113 /// Package repositories to download.
114 ///
115 /// If not set, all official repositories are downloaded.
116 #[arg(short, long)]
117 repositories: Option<Vec<PackageRepositories>>,
118
119 #[clap(subcommand)]
120 source: DownloadCmd,
121 },
122
123 /// Remove or clean downloaded local testing files.
124 Clean {
125 #[clap(subcommand)]
126 source: CleanCmd,
127 },
128}
129
130#[derive(Debug, Parser)]
131pub enum DownloadCmd {
132 /// Download all official package source repositories
133 ///
134 /// This is done by querying all active repositories via the arch web API
135 /// (<https://archlinux.org/packages/pkgbase-maintainer>) and cloning the respective
136 /// package source repositories via git.
137 ///
138 /// This command differs from `pkgctl repo clone --universe` in so far that it
139 /// also updates git repositories and removes repositories that're no longer used.
140 ///
141 /// The repositories contain the following file types for each package.
142 /// - .SRCINFO
143 PkgSrcRepositories {},
144
145 /// Download all AUR packages metadata.
146 ///
147 /// AUR uses a monorepo that holds each package in a separate branch.
148 /// This command first fetches a list of all packages from aurweb and clones aur.git mirror.
149 /// The `.SRCINFO` and `PKGBUILD` files are then extracted from the git branches.
150 Aur {},
151
152 /// Create a copy of a mirror's pacman database.
153 ///
154 /// The database contains the following file types for each package.
155 /// - `files`
156 /// - `desc`
157 Databases {
158 /// The domain + base path under which the mirror can be found.
159 ///
160 /// The mirror must support the `rsync` protocol
161 #[arg(short, long, env, default_value = "mirror.pseudoform.org/packages")]
162 mirror: String,
163
164 /// Force re-extraction of the files regardless of reported changes.
165 ///
166 /// This is useful for if the download is cancelled halfway, in which case
167 /// `rsync` will not report changes for files that it downloaded last time.
168 #[arg(short, long, default_value_t = false)]
169 force_extract: bool,
170 },
171 /// The packages contain the following file types for each package.
172 /// - `.INSTALL`
173 /// - `.BUILDINFO`
174 /// - `.MTREE`
175 /// - `.PKGINFO`
176 Packages {
177 /// The domain + base path under which the mirror can be found.
178 ///
179 /// The mirror must support the `rsync` protocol
180 #[arg(short, long, env, default_value = "mirror.pseudoform.org/packages")]
181 mirror: String,
182
183 /// Force re-extraction of the files regardless of reported changes.
184 ///
185 /// This is useful for if the download is cancelled halfway, in which case
186 /// `rsync` will not report changes for files that it downloaded last time.
187 #[arg(short, long, default_value_t = false)]
188 force_extract: bool,
189 },
190}
191
192#[derive(Debug, Parser)]
193pub enum CleanCmd {
194 /// Remove all package source repositories and .SRCINFO files
195 PkgSrcRepositories,
196
197 /// Remove extracted repository sync database files and tarballs.
198 Databases,
199
200 /// Remove all downloaded packages and any other files extracted from them.
201 Packages,
202}