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
//! What:
//! Recognize the four top-level spellings after which the wrapper says it is not plain Git
//! (`--version`, `-v`, `--help`, `-h`),
//! and build the text it prints once Git has answered.
//! Why:
//! A caller who types `git --version` should be able to tell that a policy wrapper sits in front of Git,
//! without the wrapper changing a single byte of what Git itself printed.
//! Every other query (`--exec-path`, `--html-path`, ...) stays an exact process replacement.
//!
//! In TS you'd write (pseudocode):
//! ```ts
//! // const query = announcedQuery(args, globalLayout(args));
//! // after the child exits: if (outcome === { exited: 0 }) process.stdout.write(announcement(query, version, realGit));
//! ```
/// What:
/// How a child ended,
/// which decides whether the wrapper adds text.
/// Why:
/// Only a child that ended with exit code 0 answered the question.
use crateChildOutcome;
/// The result of the global-option scan that says where the query token sits.
use crate;
/// Native argument storage;
/// no lossy UTF-8 conversion occurs.
use OsString;
/// Borrowed filesystem path of raw OS bytes.
use Path;
/// What:
/// The crate version printed in the banner.
/// `env!` reads a Cargo-provided environment variable while compiling.
/// Why:
/// The banner must name the wrapper build that answered,
/// and the manifest is the one place that version lives.
///
/// In TS you'd write (pseudocode):
/// ```ts
/// const WRAPPER_VERSION = packageJson.version;
/// ```
pub const WRAPPER_VERSION: &str = env!;
/// Which announced query an invocation is.
/// What:
/// Say whether the query token of an invocation is one of the four announced spellings.
/// `Option<AnnouncedQuery>` is "the query, or nothing".
/// Why:
/// The layout already told the caller this is a query and where it sits;
/// only the exact token separates `--version` from `--exec-path`.
/// Nothing else is read, so commands that are not queries pay one comparison.
///
/// In TS you'd write (pseudocode):
/// ```ts
/// function announcedQuery(args: string[], layout: GlobalLayout): 'version' | 'help' | undefined;
/// ```
/// What:
/// Build the text printed after Git's own answer.
/// `&str` borrows the version;
/// `&Path` borrows the resolved real Git path;
/// the result is owned, line-terminated text.
/// Why:
/// The banner states which wrapper build and which Git answered;
/// the help section also says what the wrapper adds.
/// Building it from plain values keeps it testable without a process.
/// A path that is not UTF-8 prints with replacement characters, because the text is for people.
///
/// In TS you'd write (pseudocode):
/// ```ts
/// function announcement(query: AnnouncedQuery, version: string, realGit: string): string;
/// ```
/// What:
/// The part of the announcement to print for a finished child.
/// The result borrows from `text`.
/// Why:
/// Git that failed or was killed did not answer,
/// so the caller sees Git's status and Git's own diagnostics unchanged.
///
/// In TS you'd write (pseudocode):
/// ```ts
/// function printableAfter(outcome: ChildOutcome, text: string): string { return outcome.exited === 0 ? text : ''; }
/// ```
/// Layout, text and status controls stay out of the release executable.