Skip to main content

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