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::{
13 PackageRepositories,
14 aur::AurDownloader,
15 mirror::MirrorDownloader,
16 pkgsrc::PkgSrcDownloader,
17 },
18 testing::TestRunner,
19};
20
21pub(crate) fn test_files(cmd: TestFilesCmd) -> Result<()> {
29 match cmd {
30 cli::TestFilesCmd::Test {
31 test_data_dir,
32 repositories,
33 file_type,
34 } => {
35 let test_data_dir = match test_data_dir {
37 Some(test_data_dir) => test_data_dir,
38 None => dirs::cache_dir()
39 .context("Failed to determine home user cache directory.")?
40 .join("alpm/testing"),
41 };
42 let repositories = PackageRepositories::iter()
43 .filter(|v| repositories.clone().is_none_or(|r| r.contains(v)))
44 .collect();
45 let runner = TestRunner {
46 test_data_dir,
47 file_type,
48 repositories,
49 };
50 runner.run_tests()?;
51 }
52 cli::TestFilesCmd::Download {
53 destination,
54 repositories,
55 source,
56 } => {
57 let dest = match destination {
59 Some(dest) => dest,
60 None => dirs::cache_dir()
61 .context("Failed to determine home user cache directory.")?
62 .join("alpm/testing"),
63 };
64 let repositories = PackageRepositories::iter()
65 .filter(|v| repositories.clone().is_none_or(|r| r.contains(v)))
66 .collect();
67
68 match source {
69 cli::DownloadCmd::PkgSrcRepositories {} => {
70 let downloader = PkgSrcDownloader { dest };
71 downloader.download_package_source_repositories()?;
72 }
73 cli::DownloadCmd::Aur {} => {
74 let downloader = AurDownloader { dest };
75 downloader.download_packages()?;
76 }
77 cli::DownloadCmd::Databases {
78 mirror,
79 force_extract,
80 } => {
81 let downloader = MirrorDownloader {
82 dest,
83 mirror,
84 repositories,
85 extract_all: force_extract,
86 };
87 warn!(
88 "Beginning database retrieval\nIf the process is unexpectedly halted, rerun with `--force-extract` flag"
89 );
90 downloader.sync_remote_databases()?;
91 }
92 cli::DownloadCmd::Packages {
93 mirror,
94 force_extract,
95 } => {
96 let downloader = MirrorDownloader {
97 dest,
98 mirror,
99 repositories,
100 extract_all: force_extract,
101 };
102 warn!(
103 "Beginning package retrieval\nIf the process is unexpectedly halted, rerun with `--force-extract` flag"
104 );
105 downloader.sync_remote_packages()?;
106 }
107 };
108 }
109 cli::TestFilesCmd::Clean {
110 destination,
111 source,
112 } => {
113 let dest = match destination {
115 Some(dest) => dest,
116 None => dirs::cache_dir()
117 .context("Failed to determine home user cache directory.")?
118 .join("alpm/testing"),
119 };
120
121 match source {
122 cli::CleanCmd::PkgSrcRepositories => {
123 remove_dir_all(dest.join("download").join("pkgsrc"))?;
124 remove_dir_all(dest.join("pkgsrc"))?;
125 }
126 cli::CleanCmd::Databases => {
127 remove_dir_all(dest.join("download").join("databases"))?;
128 remove_dir_all(dest.join("databases"))?;
129 }
130 cli::CleanCmd::Packages => {
131 remove_dir_all(dest.join("download").join("packages"))?;
132 remove_dir_all(dest.join("packages"))?;
133 }
134 };
135 }
136 }
137
138 Ok(())
139}
140
141pub fn compare_source_info(pkgbuild_path: PathBuf, srcinfo_path: PathBuf) -> Result<()> {
164 let pkgbuild_source_info: SourceInfoV1 = SourceInfoV1::from_pkgbuild(&pkgbuild_path)?;
165
166 let source_info = SourceInfo::from_file_with_schema(srcinfo_path, None)?;
167 let SourceInfo::V1(source_info) = source_info;
168
169 if source_info != pkgbuild_source_info {
170 let pkgbuild_source_info = serde_json::to_string_pretty(&pkgbuild_source_info)?;
171 let source_info = serde_json::to_string_pretty(&source_info)?;
172
173 let pkgbuild_json_path = PathBuf::from("pkgbuild.json");
174 std::fs::write("pkgbuild.json", pkgbuild_source_info).map_err(|source| Error::IoPath {
175 path: pkgbuild_json_path,
176 context: "writing pkgbuild.json file",
177 source,
178 })?;
179 let srcinfo_json_path = PathBuf::from("srcinfo.json");
180 std::fs::write("srcinfo.json", source_info).map_err(|source| Error::IoPath {
181 path: srcinfo_json_path,
182 context: "writing srcinfo.json file",
183 source,
184 })?;
185
186 eprintln!(
187 "SRCINFO data generated from PKGBUILD file differs from the .SRCINFO file read from disk.\n\
188 Compare the two generated files pkgbuild.json and srcinfo.json for details."
189 );
190 std::process::exit(1);
191 } else {
192 println!("The generated content matches that read from disk.");
193 }
194
195 Ok(())
196}