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