pkgcraft/shell/commands/
doinitd.rs1use camino::Utf8PathBuf;
2use itertools::Either;
3use scallop::ExecStatus;
4
5use crate::eapi::Feature::ConsistentFileOpts;
6use crate::shell::get_build_mut;
7
8use super::{TryParseArgs, make_builtin};
9
10#[derive(clap::Parser, Debug)]
11#[command(
12 name = "doinitd",
13 long_about = "Install init scripts into /etc/init.d/."
14)]
15struct Command {
16 #[arg(required = true, value_name = "PATH")]
17 paths: Vec<Utf8PathBuf>,
18}
19
20pub(crate) fn run(args: &[&str]) -> scallop::Result<ExecStatus> {
21 let cmd = Command::try_parse_args(args)?;
22 let build = get_build_mut();
23 let dest = "/etc/init.d";
24 let opts = if build.eapi().has(ConsistentFileOpts) {
25 Either::Left(["-m0755"].into_iter())
26 } else {
27 Either::Right(build.exeopts.iter().map(|s| s.as_str()))
28 };
29 build
30 .install()
31 .dest(dest)?
32 .file_options(opts)
33 .files(&cmd.paths)?;
34 Ok(ExecStatus::Success)
35}
36
37make_builtin!("doinitd", doinitd_builtin);
38
39#[cfg(test)]
40mod tests {
41 use std::fs;
42
43 use crate::eapi::EAPIS_OFFICIAL;
44 use crate::shell::BuildData;
45 use crate::shell::test::FileTree;
46 use crate::test::assert_err_re;
47
48 use super::super::{
49 assert_invalid_cmd, cmd_scope_tests,
50 functions::{doinitd, exeopts},
51 };
52 use super::*;
53
54 cmd_scope_tests!("doinitd path/to/init/file");
55
56 #[test]
57 fn invalid_args() {
58 assert_invalid_cmd(doinitd, &[0]);
59
60 let _file_tree = FileTree::new();
61
62 let r = doinitd(&["nonexistent"]);
64 assert_err_re!(r, "^invalid file: nonexistent: No such file or directory .*$");
65 }
66
67 #[test]
68 fn creation() {
69 let file_tree = FileTree::new();
70 let default_mode = 0o100755;
71 let custom_mode = 0o100777;
72
73 fs::File::create("pkgcraft").unwrap();
74 doinitd(&["pkgcraft"]).unwrap();
75 file_tree.assert(format!(
76 r#"
77 [[files]]
78 path = "/etc/init.d/pkgcraft"
79 mode = {default_mode}
80 "#
81 ));
82
83 for eapi in &*EAPIS_OFFICIAL {
85 BuildData::empty(eapi);
86 exeopts(&["-m0777"]).unwrap();
87 doinitd(&["pkgcraft"]).unwrap();
88 let mode = if eapi.has(ConsistentFileOpts) {
89 default_mode
90 } else {
91 custom_mode
92 };
93 file_tree.assert(format!(
94 r#"
95 [[files]]
96 path = "/etc/init.d/pkgcraft"
97 mode = {mode}
98 "#
99 ));
100 }
101 }
102}