160 lines · 5.2 KB · Rust
RawDownload
use std::path::Path; use gix_testtools::Result; #[test]fn extract_interpreter() -> gix_testtools::Result {    let root = gix_testtools::scripted_fixture_read_only("win_path_lookup.sh")?;    assert_eq!(        gix_command::extract_interpreter(&root.join("b").join("exe")),        Some(gix_command::shebang::Data {            interpreter: Path::new("/b/exe").into(),            args: vec![]        })    );    Ok(())} mod shebang {    mod parse {        use gix_command::shebang;         fn parse(input: &str) -> Option<shebang::Data> {            shebang::parse(input.into())        }         fn exe(name: &str) -> Option<shebang::Data> {            shebang::Data {                interpreter: name.into(),                args: Vec::new(),            }            .into()        }         fn exe_args(name: &str, args: &[&str]) -> Option<shebang::Data> {            shebang::Data {                interpreter: name.into(),                args: args.iter().map(Into::into).collect(),            }            .into()        }         #[test]        fn valid() {            assert_eq!(parse("#!/bin/sh"), exe("/bin/sh"));            assert_eq!(parse("#!/bin/sh   "), exe("/bin/sh"), "trim trailing whitespace");            assert_eq!(                parse("#!/bin/sh\t\nother"),                exe("/bin/sh"),                "trimming works for tabs as well"            );            assert_eq!(                parse(r"#!\bin\sh"),                exe(r"\bin\sh"),                "backslashes are recognized as path separator"            );            assert_eq!(                parse("#!C:\\Program Files\\shell.exe\r\nsome stuff"),                exe(r"C:\Program Files\shell.exe"),                "absolute windows paths are fine"            );            assert_eq!(                parse("#!/bin/sh -i -o -u\nunrelated content"),                exe_args("/bin/sh", &["-i", "-o", "-u"]),                "all interpreter options are returned"            );            assert_eq!(                parse("#!/bin/sh  -o\nunrelated content"),                exe_args("/bin/sh", &["-o"]),                "single interpreter options are returned too"            );            assert_eq!(                parse("#!/bin/exe anything goes\nunrelated content"),                exe_args("/bin/exe", &["anything", "goes"]),                "the entire shebang suffix is returned"            );            assert_eq!(                parse("#!/usr/bin/env -S FOO=bar command"),                exe_args("/usr/bin/env", &["-S", "FOO=bar", "command"]),                "assignment-looking arguments are retained"            );            assert_eq!(                parse(r#"#!/usr/bin/env -S "command name" plain"#),                exe_args("/usr/bin/env", &["-S", "command name", "plain"]),                "interpreter arguments use command-line quoting"            );            assert_eq!(                parse("#!/bin/sh O'Brien"),                exe("/bin/sh"),                "malformed interpreter options do not hide a valid interpreter"            );             use bstr::ByteSlice;             #[cfg(unix)]            {                use std::os::unix::ffi::OsStrExt;                 assert_eq!(                    shebang::parse(b"#!/bin/sh   -x \xC3\x28\x41 -y  ".as_bstr()),                    Some(shebang::Data {                        interpreter: "/bin/sh".into(),                        args: vec![                            "-x".into(),                            std::ffi::OsStr::from_bytes(b"\xC3\x28\x41").to_owned(),                            "-y".into(),                        ]                    }),                    "non-UTF-8 interpreter arguments are returned losslessly"                );            }             #[cfg(not(unix))]            assert_eq!(                shebang::parse(b"#!/bin/sh   -x \xC3\x28\x41 -y  ".as_bstr()),                exe("/bin/sh"),                "unrepresentable interpreter arguments do not hide a valid interpreter"            );             #[cfg(unix)]            {                use std::os::unix::ffi::OsStrExt;                 assert_eq!(                    shebang::parse(b"#!/bin/\xC3\x28\x41 ".as_bstr()),                    Some(shebang::Data {                        interpreter: std::ffi::OsStr::from_bytes(b"/bin/\xC3\x28\x41").to_owned().into(),                        args: vec![]                    }),                    "illformed UTF8 in the executable path is fine as well"                );            }             #[cfg(not(unix))]            {                assert_eq!(                    shebang::parse(b"#!/bin/\xC3\x28\x41 ".as_bstr()),                    None,                    "an unrepresentable interpreter invalidates the shebang"                );            }        }         #[test]        fn invalid() {            assert_eq!(parse(""), None);            assert_eq!(parse("missing shebang"), None);            assert_eq!(parse("#!missing-slash"), None);            assert_eq!(                parse("/bin/sh"),                None,                "shebang missing, even though a valid path is given"            );        }    }} mod command_line;mod context;mod prepare;mod spawn;