aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe/src/command/script_alias_command.rs
blob: c5bacc4ef67ca2192949e7d4f73598e0e49e7b5b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
//! ref: composer/src/Composer/Command/ScriptAliasCommand.php

use crate::command::base_command::BaseCommand;
use crate::console::input::input_argument::InputArgument;
use crate::console::input::input_option::InputOption;
use crate::util::platform::Platform;
use anyhow::Result;
use shirabe_external_packages::composer::pcre::preg::Preg;
use shirabe_external_packages::symfony::console::input::input_interface::InputInterface;
use shirabe_external_packages::symfony::console::output::output_interface::OutputInterface;
use shirabe_php_shim::{InvalidArgumentException, LogicException, PhpMixed, is_string};

pub struct ScriptAliasCommand {
    inner: BaseCommand,
    script: String,
    description: String,
    aliases: Vec<String>,
}

impl ScriptAliasCommand {
    pub fn new(script: String, description: Option<String>, aliases: Vec<String>) -> Result<Self> {
        let description = description
            .unwrap_or_else(|| format!("Runs the {} script as defined in composer.json", script));

        for alias in &aliases {
            if !is_string(&PhpMixed::String(alias.clone())) {
                return Err(InvalidArgumentException {
                    message:
                        r#""scripts-aliases" element array values should contain only strings"#
                            .to_string(),
                    code: 0,
                }
                .into());
            }
        }

        let mut inner = BaseCommand::new();
        inner.ignore_validation_errors();

        Ok(Self {
            inner,
            script,
            description,
            aliases,
        })
    }

    pub fn configure(&mut self) {
        self.inner
            .set_name(&self.script)
            .set_description(&self.description)
            .set_aliases(self.aliases.clone())
            .set_definition(vec![
                InputOption::new(
                    "dev",
                    None,
                    Some(InputOption::VALUE_NONE),
                    "Sets the dev mode.",
                    None,
                    vec![],
                ),
                InputOption::new(
                    "no-dev",
                    None,
                    Some(InputOption::VALUE_NONE),
                    "Disables the dev mode.",
                    None,
                    vec![],
                ),
                InputArgument::new(
                    "args",
                    Some(InputArgument::IS_ARRAY | InputArgument::OPTIONAL),
                    "",
                    None,
                    vec![],
                ),
            ])
            .set_help(
                "The <info>run-script</info> command runs scripts defined in composer.json:\n\n\
                <info>php composer.phar run-script post-update-cmd</info>\n\n\
                Read more at https://getcomposer.org/doc/03-cli.md#run-script-run",
            );
    }

    pub fn execute(
        &mut self,
        input: &dyn InputInterface,
        _output: &dyn OutputInterface,
    ) -> Result<i64> {
        let composer = self.inner.require_composer()?;

        let args = input.get_arguments();

        // TODO remove for Symfony 6+ as it is then in the interface
        if !input.has_to_string() {
            return Err(LogicException {
                message: format!(
                    "Expected an Input instance that is stringable, got {}",
                    input.get_class_name()
                ),
                code: 0,
            }
            .into());
        }

        let dev_mode = input.get_option("dev").as_bool().unwrap_or(false)
            || !input.get_option("no-dev").as_bool().unwrap_or(false);

        Platform::put_env("COMPOSER_DEV_MODE", if dev_mode { "1" } else { "0" });

        let script_alias_input = Preg::replace_limit(r"^\S+ ?", "", &input.to_string(), 1);
        let mut flags = indexmap::IndexMap::new();
        flags.insert(
            "script-alias-input".to_string(),
            PhpMixed::String(script_alias_input),
        );

        let args_value = args.get("args").cloned().unwrap_or(PhpMixed::Null);

        Ok(composer.get_event_dispatcher().dispatch_script(
            &self.script,
            dev_mode,
            args_value,
            flags,
        )?)
    }
}