File: help.rs

package info (click to toggle)
rust-cargo 0.86.0-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 16,088 kB
  • sloc: javascript: 408; sh: 306; python: 87; xml: 21; makefile: 6
file content (159 lines) | stat: -rw-r--r-- 4,713 bytes parent folder | download | duplicates (5)
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
//! Tests for cargo's help output.

use std::fs;
use std::path::Path;
use std::str::from_utf8;

use cargo_test_support::prelude::*;
use cargo_test_support::registry::Package;
use cargo_test_support::str;
use cargo_test_support::{basic_manifest, cargo_process, paths, project};

#[cargo_test]
fn help() {
    cargo_process("").run();
    cargo_process("help").run();
    cargo_process("-h").run();
    cargo_process("help build").run();
    cargo_process("build -h").run();
    cargo_process("help help").run();
}

#[cargo_test]
fn help_external_subcommand() {
    // Check that `help external-subcommand` forwards the --help flag to the
    // given subcommand.
    Package::new("cargo-fake-help", "1.0.0")
        .file(
            "src/main.rs",
            r#"
            fn main() {
                if ::std::env::args().nth(2) == Some(String::from("--help")) {
                    println!("fancy help output");
                }
            }
            "#,
        )
        .publish();
    cargo_process("install cargo-fake-help").run();
    cargo_process("help fake-help")
        .with_stdout_data(str![[r#"
fancy help output

"#]])
        .run();
}

fn help_with_man(display_command: &str) {
    // Build a "man" process that just echoes the contents.
    let p = project()
        .at(display_command)
        .file("Cargo.toml", &basic_manifest(display_command, "1.0.0"))
        .file(
            "src/main.rs",
            &r#"
                fn main() {
                    eprintln!("custom __COMMAND__");
                    let path = std::env::args().skip(1).next().unwrap();
                    let mut f = std::fs::File::open(path).unwrap();
                    std::io::copy(&mut f, &mut std::io::stdout()).unwrap();
                }
            "#
            .replace("__COMMAND__", display_command),
        )
        .build();
    p.cargo("build").run();

    help_with_man_and_path(display_command, "build", "build", &p.target_debug_dir());
}

fn help_with_man_and_path(
    display_command: &str,
    subcommand: &str,
    actual_subcommand: &str,
    path: &Path,
) {
    let contents = if display_command == "man" {
        fs::read_to_string(format!("src/etc/man/cargo-{}.1", actual_subcommand)).unwrap()
    } else {
        fs::read_to_string(format!(
            "src/doc/man/generated_txt/cargo-{}.txt",
            actual_subcommand
        ))
        .unwrap()
    };

    let output = cargo_process(&format!("help {subcommand}"))
        .env("PATH", path)
        .run();
    let stderr = from_utf8(&output.stderr).unwrap();
    if display_command.is_empty() {
        assert_eq!(stderr, "");
    } else {
        assert_eq!(stderr, format!("custom {}\n", display_command));
    }
    let stdout = from_utf8(&output.stdout).unwrap();
    assert_eq!(stdout, contents);
}

fn help_with_stdout_and_path(subcommand: &str, path: &Path) -> String {
    let output = cargo_process(&format!("help {subcommand}"))
        .env("PATH", path)
        .run();
    let stderr = from_utf8(&output.stderr).unwrap();
    assert_eq!(stderr, "");
    let stdout = from_utf8(&output.stdout).unwrap();
    stdout.to_string()
}

#[cargo_test]
fn help_man() {
    // Checks that `help command` displays the man page using the given command.
    help_with_man("man");
    help_with_man("less");
    help_with_man("more");

    // Check with no commands in PATH.
    help_with_man_and_path("", "build", "build", Path::new(""));
}

#[cargo_test]
fn help_alias() {
    // Check that `help some_alias` will resolve.
    help_with_man_and_path("", "b", "build", Path::new(""));

    let config = paths::root().join(".cargo/config.toml");
    fs::create_dir_all(config.parent().unwrap()).unwrap();
    fs::write(
        config,
        r#"
            [alias]
            empty-alias   = ""
            simple-alias  = "build"
            complex-alias = ["build", "--release"]
        "#,
    )
    .unwrap();

    // The `empty-alias` returns an error.
    cargo_process("help empty-alias")
        .env("PATH", Path::new(""))
        .with_status(101)
        .with_stderr_data(str![[r#"
[ERROR] no such command: `empty-alias`

	Did you mean `empty-alias`?

	View all installed commands with `cargo --list`
	Find a package to install `empty-alias` with `cargo search cargo-empty-alias`

"#]])
        .run();

    // Because `simple-alias` aliases a subcommand with no arguments, help shows the manpage.
    help_with_man_and_path("", "simple-alias", "build", Path::new(""));

    // Help for `complex-alias` displays the full alias command.
    let out = help_with_stdout_and_path("complex-alias", Path::new(""));
    assert_eq!(out, "`complex-alias` is aliased to `build --release`\n");
}