1use std::{
2 fs::{remove_dir_all, write},
3 path::PathBuf,
4 process::exit,
5};
6
7use alpm_common::MetadataFile;
8use alpm_srcinfo::{SourceInfo, SourceInfoV1};
9use log::warn;
10use serde_json::to_string_pretty;
11use strum::IntoEnumIterator;
12
13use crate::{
14 CacheDir,
15 Error,
16 cli::{CleanCmd, DownloadCmd, TestFilesCmd},
17 consts::{DATABASES_DIR, DOWNLOAD_DIR, PACKAGES_DIR, PKGSRC_DIR},
18 sync::{
19 PackageRepositories,
20 aur::AurDownloader,
21 mirror::MirrorDownloader,
22 pkgsrc::PkgSrcDownloader,
23 },
24 testing::TestRunner,
25};
26
27pub(crate) fn test_files(cmd: TestFilesCmd, cache_dir: CacheDir) -> Result<(), Error> {
35 match cmd {
36 TestFilesCmd::Test {
37 repositories,
38 file_type,
39 } => {
40 let repositories = PackageRepositories::iter()
41 .filter(|v| repositories.clone().is_none_or(|r| r.contains(v)))
42 .collect();
43 let runner = TestRunner {
44 cache_dir,
45 file_type,
46 repositories,
47 };
48 runner.run_tests()?;
49 }
50 TestFilesCmd::Download {
51 repositories,
52 source,
53 } => {
54 let repositories = PackageRepositories::iter()
55 .filter(|v| repositories.clone().is_none_or(|r| r.contains(v)))
56 .collect();
57
58 match source {
59 DownloadCmd::PkgSrcRepositories {} => {
60 let downloader = PkgSrcDownloader { cache_dir };
61 downloader.download_package_source_repositories()?;
62 }
63 DownloadCmd::Aur {} => {
64 let downloader = AurDownloader { cache_dir };
65 downloader.download_packages()?;
66 }
67 DownloadCmd::Databases {
68 mirror,
69 force_extract,
70 } => {
71 let downloader = MirrorDownloader {
72 cache_dir,
73 mirror,
74 repositories,
75 extract_all: force_extract,
76 };
77 warn!(
78 "Beginning database retrieval\nIf the process is unexpectedly halted, rerun with `--force-extract` flag"
79 );
80 downloader.sync_remote_databases()?;
81 }
82 DownloadCmd::Packages {
83 mirror,
84 force_extract,
85 } => {
86 let downloader = MirrorDownloader {
87 cache_dir,
88 mirror,
89 repositories,
90 extract_all: force_extract,
91 };
92 warn!(
93 "Beginning package retrieval\nIf the process is unexpectedly halted, rerun with `--force-extract` flag"
94 );
95 downloader.sync_remote_packages()?;
96 }
97 };
98 }
99 TestFilesCmd::Clean { source } => {
100 let dirs = match source {
101 CleanCmd::PkgSrcRepositories => [
102 cache_dir.as_ref().join(DOWNLOAD_DIR).join(PKGSRC_DIR),
103 cache_dir.as_ref().join(PKGSRC_DIR),
104 ],
105 CleanCmd::Databases => [
106 cache_dir.as_ref().join(DOWNLOAD_DIR).join(DATABASES_DIR),
107 cache_dir.as_ref().join(DATABASES_DIR),
108 ],
109 CleanCmd::Packages => [
110 cache_dir.as_ref().join(DOWNLOAD_DIR).join(PACKAGES_DIR),
111 cache_dir.as_ref().join(PACKAGES_DIR),
112 ],
113 };
114
115 for dir in dirs {
116 remove_dir_all(&dir).map_err(|source| Error::IoPath {
117 path: dir,
118 context: "recursively deleting the directory".to_string(),
119 source,
120 })?;
121 }
122 }
123 }
124
125 Ok(())
126}
127
128pub fn compare_source_info(pkgbuild_path: PathBuf, srcinfo_path: PathBuf) -> Result<(), Error> {
151 let pkgbuild_source_info: SourceInfoV1 = SourceInfoV1::from_pkgbuild(&pkgbuild_path)?;
152
153 let source_info = SourceInfo::from_file_with_schema(srcinfo_path, None)?;
154 let SourceInfo::V1(source_info) = source_info;
155
156 if source_info != pkgbuild_source_info {
157 let pkgbuild_source_info =
158 to_string_pretty(&pkgbuild_source_info).map_err(|source| Error::Json {
159 context: "deserializing a PKGBUILD based SRCINFO as pretty JSON".to_string(),
160 source,
161 })?;
162 let source_info = to_string_pretty(&source_info).map_err(|source| Error::Json {
163 context: "deserializing a SRCINFO as pretty JSON".to_string(),
164 source,
165 })?;
166
167 let pkgbuild_json_path = PathBuf::from("pkgbuild.json");
168 write("pkgbuild.json", pkgbuild_source_info).map_err(|source| Error::IoPath {
169 path: pkgbuild_json_path,
170 context: "writing pkgbuild.json file".to_string(),
171 source,
172 })?;
173 let srcinfo_json_path = PathBuf::from("srcinfo.json");
174 write("srcinfo.json", source_info).map_err(|source| Error::IoPath {
175 path: srcinfo_json_path,
176 context: "writing srcinfo.json file".to_string(),
177 source,
178 })?;
179
180 eprintln!(
181 "SRCINFO data generated from PKGBUILD file differs from the .SRCINFO file read from disk.\n\
182 Compare the two generated files pkgbuild.json and srcinfo.json for details."
183 );
184 exit(1);
185 } else {
186 println!("The generated content matches that read from disk.");
187 }
188
189 Ok(())
190}