bash-classify 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. bash_classify/__init__.py +14 -0
  2. bash_classify/__main__.py +3 -0
  3. bash_classify/classifier.py +244 -0
  4. bash_classify/cli.py +110 -0
  5. bash_classify/commands/apt.yaml +23 -0
  6. bash_classify/commands/awk.yaml +5 -0
  7. bash_classify/commands/basename.yaml +5 -0
  8. bash_classify/commands/bash.yaml +18 -0
  9. bash_classify/commands/brew.yaml +25 -0
  10. bash_classify/commands/builtin.yaml +6 -0
  11. bash_classify/commands/cargo.yaml +29 -0
  12. bash_classify/commands/cat.yaml +5 -0
  13. bash_classify/commands/chgrp.yaml +8 -0
  14. bash_classify/commands/chmod.yaml +8 -0
  15. bash_classify/commands/chown.yaml +8 -0
  16. bash_classify/commands/column.yaml +5 -0
  17. bash_classify/commands/comm.yaml +5 -0
  18. bash_classify/commands/command.yaml +10 -0
  19. bash_classify/commands/cp.yaml +5 -0
  20. bash_classify/commands/curl.yaml +28 -0
  21. bash_classify/commands/cut.yaml +5 -0
  22. bash_classify/commands/date.yaml +8 -0
  23. bash_classify/commands/df.yaml +5 -0
  24. bash_classify/commands/diff.yaml +5 -0
  25. bash_classify/commands/dig.yaml +5 -0
  26. bash_classify/commands/dirname.yaml +5 -0
  27. bash_classify/commands/docker.yaml +152 -0
  28. bash_classify/commands/du.yaml +5 -0
  29. bash_classify/commands/echo.yaml +5 -0
  30. bash_classify/commands/env.yaml +14 -0
  31. bash_classify/commands/expand.yaml +5 -0
  32. bash_classify/commands/false.yaml +5 -0
  33. bash_classify/commands/file.yaml +5 -0
  34. bash_classify/commands/find.yaml +27 -0
  35. bash_classify/commands/fmt.yaml +5 -0
  36. bash_classify/commands/fold.yaml +5 -0
  37. bash_classify/commands/free.yaml +5 -0
  38. bash_classify/commands/gawk.yaml +5 -0
  39. bash_classify/commands/git.yaml +441 -0
  40. bash_classify/commands/go.yaml +38 -0
  41. bash_classify/commands/grep.yaml +5 -0
  42. bash_classify/commands/groups.yaml +5 -0
  43. bash_classify/commands/gunzip.yaml +5 -0
  44. bash_classify/commands/gzip.yaml +5 -0
  45. bash_classify/commands/head.yaml +5 -0
  46. bash_classify/commands/helm.yaml +127 -0
  47. bash_classify/commands/hostname.yaml +5 -0
  48. bash_classify/commands/id.yaml +5 -0
  49. bash_classify/commands/install.yaml +5 -0
  50. bash_classify/commands/join.yaml +5 -0
  51. bash_classify/commands/journalctl.yaml +12 -0
  52. bash_classify/commands/jq.yaml +5 -0
  53. bash_classify/commands/kill.yaml +5 -0
  54. bash_classify/commands/killall.yaml +5 -0
  55. bash_classify/commands/kubectl.yaml +190 -0
  56. bash_classify/commands/less.yaml +5 -0
  57. bash_classify/commands/ln.yaml +5 -0
  58. bash_classify/commands/ls.yaml +5 -0
  59. bash_classify/commands/make.yaml +19 -0
  60. bash_classify/commands/md5sum.yaml +5 -0
  61. bash_classify/commands/mkdir.yaml +5 -0
  62. bash_classify/commands/more.yaml +5 -0
  63. bash_classify/commands/mv.yaml +5 -0
  64. bash_classify/commands/netstat.yaml +5 -0
  65. bash_classify/commands/nice.yaml +9 -0
  66. bash_classify/commands/nl.yaml +5 -0
  67. bash_classify/commands/node.yaml +5 -0
  68. bash_classify/commands/nohup.yaml +6 -0
  69. bash_classify/commands/npm.yaml +65 -0
  70. bash_classify/commands/nslookup.yaml +5 -0
  71. bash_classify/commands/paste.yaml +5 -0
  72. bash_classify/commands/ping.yaml +5 -0
  73. bash_classify/commands/pip.yaml +29 -0
  74. bash_classify/commands/pip3.yaml +29 -0
  75. bash_classify/commands/pkill.yaml +5 -0
  76. bash_classify/commands/poetry.yaml +74 -0
  77. bash_classify/commands/printenv.yaml +5 -0
  78. bash_classify/commands/printf.yaml +5 -0
  79. bash_classify/commands/ps.yaml +5 -0
  80. bash_classify/commands/pwd.yaml +5 -0
  81. bash_classify/commands/python.yaml +5 -0
  82. bash_classify/commands/python3.yaml +5 -0
  83. bash_classify/commands/read.yaml +5 -0
  84. bash_classify/commands/readlink.yaml +5 -0
  85. bash_classify/commands/realpath.yaml +5 -0
  86. bash_classify/commands/rev.yaml +5 -0
  87. bash_classify/commands/rm.yaml +5 -0
  88. bash_classify/commands/rsync.yaml +10 -0
  89. bash_classify/commands/scp.yaml +5 -0
  90. bash_classify/commands/sed.yaml +12 -0
  91. bash_classify/commands/seq.yaml +5 -0
  92. bash_classify/commands/sh.yaml +12 -0
  93. bash_classify/commands/sha1sum.yaml +5 -0
  94. bash_classify/commands/sha256sum.yaml +5 -0
  95. bash_classify/commands/sort.yaml +8 -0
  96. bash_classify/commands/ss.yaml +5 -0
  97. bash_classify/commands/ssh.yaml +39 -0
  98. bash_classify/commands/stat.yaml +5 -0
  99. bash_classify/commands/strace.yaml +18 -0
  100. bash_classify/commands/sudo.yaml +22 -0
  101. bash_classify/commands/systemctl.yaml +56 -0
  102. bash_classify/commands/tac.yaml +5 -0
  103. bash_classify/commands/tail.yaml +5 -0
  104. bash_classify/commands/tar.yaml +22 -0
  105. bash_classify/commands/tee.yaml +5 -0
  106. bash_classify/commands/terraform.yaml +68 -0
  107. bash_classify/commands/test.yaml +5 -0
  108. bash_classify/commands/time.yaml +6 -0
  109. bash_classify/commands/timeout.yaml +15 -0
  110. bash_classify/commands/top.yaml +5 -0
  111. bash_classify/commands/touch.yaml +5 -0
  112. bash_classify/commands/tr.yaml +5 -0
  113. bash_classify/commands/traceroute.yaml +5 -0
  114. bash_classify/commands/true.yaml +5 -0
  115. bash_classify/commands/type.yaml +5 -0
  116. bash_classify/commands/uname.yaml +5 -0
  117. bash_classify/commands/unexpand.yaml +5 -0
  118. bash_classify/commands/uniq.yaml +5 -0
  119. bash_classify/commands/unzip.yaml +7 -0
  120. bash_classify/commands/uptime.yaml +5 -0
  121. bash_classify/commands/uv.yaml +117 -0
  122. bash_classify/commands/wc.yaml +5 -0
  123. bash_classify/commands/wget.yaml +5 -0
  124. bash_classify/commands/whereis.yaml +5 -0
  125. bash_classify/commands/which.yaml +5 -0
  126. bash_classify/commands/whoami.yaml +5 -0
  127. bash_classify/commands/xargs.yaml +25 -0
  128. bash_classify/commands/xmllint.yaml +5 -0
  129. bash_classify/commands/yes.yaml +5 -0
  130. bash_classify/commands/yq.yaml +8 -0
  131. bash_classify/commands/zip.yaml +5 -0
  132. bash_classify/commands/zsh.yaml +12 -0
  133. bash_classify/database.py +257 -0
  134. bash_classify/matcher.py +702 -0
  135. bash_classify/models.py +148 -0
  136. bash_classify/parser.py +525 -0
  137. bash_classify/py.typed +0 -0
  138. bash_classify-0.1.0.dist-info/METADATA +147 -0
  139. bash_classify-0.1.0.dist-info/RECORD +142 -0
  140. bash_classify-0.1.0.dist-info/WHEEL +4 -0
  141. bash_classify-0.1.0.dist-info/entry_points.txt +2 -0
  142. bash_classify-0.1.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,14 @@
1
+ """bash-classify: Classify bash expressions by their side-effect risk level."""
2
+
3
+ from bash_classify.classifier import classify_expression
4
+ from bash_classify.database import CommandDatabase, load_database
5
+ from bash_classify.models import Classification, CommandResult, ExpressionResult
6
+
7
+ __all__ = [
8
+ "classify_expression",
9
+ "load_database",
10
+ "CommandDatabase",
11
+ "Classification",
12
+ "ExpressionResult",
13
+ "CommandResult",
14
+ ]
@@ -0,0 +1,3 @@
1
+ from bash_classify.cli import main
2
+
3
+ main()
@@ -0,0 +1,244 @@
1
+ """Top-level classifier orchestrating parsing, matching, and classification."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ from collections.abc import Mapping
7
+
8
+ from .database import load_database
9
+ from .matcher import match_command
10
+ from .models import (
11
+ Classification,
12
+ CommandDef,
13
+ CommandResult,
14
+ ExpressionResult,
15
+ InnerCommandResult,
16
+ Redirect,
17
+ )
18
+ from .parser import parse_expression
19
+
20
+ _SYSTEM_DIRS = (
21
+ "/etc",
22
+ "/lib",
23
+ "/lib64",
24
+ "/usr",
25
+ "/bin",
26
+ "/sbin",
27
+ "/boot",
28
+ "/sys",
29
+ "/proc",
30
+ "/run",
31
+ "/srv",
32
+ "/root",
33
+ "/opt",
34
+ "/var",
35
+ "/dev",
36
+ )
37
+ _SAFE_PREFIXES = (
38
+ "/tmp",
39
+ "/var/tmp",
40
+ "/home",
41
+ "/dev/null",
42
+ "/dev/stdin",
43
+ "/dev/stdout",
44
+ "/dev/stderr",
45
+ "/dev/fd",
46
+ "/dev/tcp",
47
+ "/dev/udp",
48
+ )
49
+
50
+
51
+ def _is_system_path(path: str) -> bool:
52
+ """Check if a path is a system directory that should trigger DANGEROUS when written to."""
53
+ if not path.startswith("/"):
54
+ return False
55
+ # Check safe prefixes first (more specific)
56
+ for safe in _SAFE_PREFIXES:
57
+ if path == safe or path.startswith(safe + "/"):
58
+ return False
59
+ # Check system dirs
60
+ return any(path == sysdir or path.startswith(sysdir + "/") for sysdir in _SYSTEM_DIRS)
61
+
62
+
63
+ def classify_expression(
64
+ expression: str,
65
+ database: Mapping[str, CommandDef] | None = None,
66
+ ) -> ExpressionResult:
67
+ """Classify a bash expression.
68
+
69
+ Parses the expression, matches each command against the database,
70
+ and returns a composite classification result.
71
+
72
+ Args:
73
+ expression: A bash expression string.
74
+ database: Optional pre-loaded command database. If None, loads the default.
75
+
76
+ Returns:
77
+ An ExpressionResult with the overall classification and per-command details.
78
+ """
79
+ # Step 1: Load database if not provided
80
+ if database is None:
81
+ database = load_database()
82
+
83
+ # Step 2: Parse the expression
84
+ invocations, parse_warnings = parse_expression(expression)
85
+
86
+ # Step 3: Match each command invocation
87
+ command_results: list[CommandResult] = []
88
+ all_redirects: list[Redirect] = []
89
+
90
+ for invocation in invocations:
91
+ # Check for variable expansion in command position
92
+ if invocation.argv and invocation.argv[0].startswith("$"):
93
+ result = CommandResult(
94
+ command=[invocation.argv[0]],
95
+ argv=list(invocation.argv),
96
+ classification=Classification.DANGEROUS,
97
+ matched_rule=None,
98
+ inner_commands=[],
99
+ classification_reason="variable expansion in command position",
100
+ )
101
+ else:
102
+ result = match_command(invocation, database)
103
+
104
+ # Step 4: Apply redirect classification
105
+ for redirect in invocation.redirects:
106
+ if redirect.affects_classification:
107
+ elevated = Classification.max_severity(result.classification, Classification.WRITE)
108
+ if elevated != result.classification:
109
+ result.classification = elevated
110
+ result.classification_reason = (
111
+ f"{result.classification_reason}; elevated by output redirect"
112
+ if result.classification_reason
113
+ else "elevated by output redirect"
114
+ )
115
+ # /dev/tcp and /dev/udp redirects are network access -> DANGEROUS
116
+ if redirect.target.startswith("/dev/tcp/") or redirect.target.startswith("/dev/udp/"):
117
+ elevated = Classification.max_severity(result.classification, Classification.DANGEROUS)
118
+ if elevated != result.classification:
119
+ result.classification = elevated
120
+ result.classification_reason = "elevated to DANGEROUS: /dev/tcp or /dev/udp access detected"
121
+
122
+ # Step 4b: Check for /dev/tcp and /dev/udp in command arguments
123
+ for arg in invocation.argv:
124
+ if arg.startswith("/dev/tcp/") or arg.startswith("/dev/udp/"):
125
+ elevated = Classification.max_severity(result.classification, Classification.DANGEROUS)
126
+ if elevated != result.classification:
127
+ result.classification = elevated
128
+ result.classification_reason = "elevated to DANGEROUS: /dev/tcp or /dev/udp access detected"
129
+
130
+ # Step 5: Apply backgrounding
131
+ if invocation.is_background:
132
+ elevated = Classification.max_severity(result.classification, Classification.WRITE)
133
+ if elevated != result.classification:
134
+ result.classification = elevated
135
+ result.classification_reason = (
136
+ f"{result.classification_reason}; elevated by backgrounding"
137
+ if result.classification_reason
138
+ else "elevated by backgrounding"
139
+ )
140
+
141
+ # Step 6: Elevate to DANGEROUS when writing to system directories
142
+ if result.classification.severity() >= Classification.WRITE.severity():
143
+ system_paths_found = []
144
+ # Check argv tokens
145
+ for token in invocation.argv:
146
+ if _is_system_path(token):
147
+ system_paths_found.append(token)
148
+ # Check redirect targets
149
+ for redirect in invocation.redirects:
150
+ if _is_system_path(redirect.target):
151
+ system_paths_found.append(redirect.target)
152
+
153
+ if system_paths_found and result.classification != Classification.DANGEROUS:
154
+ result.classification = Classification.DANGEROUS
155
+ result.classification_reason = (
156
+ result.classification_reason or ""
157
+ ) + f"; elevated to DANGEROUS: system path {system_paths_found[0]}"
158
+
159
+ command_results.append(result)
160
+ all_redirects.extend(invocation.redirects)
161
+
162
+ # Step 7: Collect directories
163
+ directories = _collect_directories(command_results)
164
+
165
+ # Step 8: Compute composite classification
166
+ if not command_results and parse_warnings:
167
+ overall = Classification.UNKNOWN
168
+ elif command_results:
169
+ overall = Classification.max_severity(*(r.classification for r in command_results))
170
+ else:
171
+ overall = Classification.READONLY # empty input
172
+
173
+ return ExpressionResult(
174
+ expression=expression,
175
+ classification=overall,
176
+ directories=directories,
177
+ commands=command_results,
178
+ redirects=all_redirects,
179
+ parse_warnings=parse_warnings,
180
+ )
181
+
182
+
183
+ def _extract_directories_from_argv(command: list[str], argv: list[str]) -> list[str]:
184
+ """Extract directories from a command's argv based on well-known command patterns.
185
+
186
+ Handles find, ls (first positional arg is a directory) and
187
+ cat/head/tail/less/more (dirname of first positional arg containing /).
188
+ """
189
+ if not command or len(argv) <= 1:
190
+ return []
191
+
192
+ binary = command[0]
193
+
194
+ # find and ls: first positional (non-option) arg is typically the directory
195
+ if binary in ("find", "ls"):
196
+ for arg in argv[1:]:
197
+ if not arg.startswith("-"):
198
+ return [arg]
199
+ return []
200
+
201
+ # File-reading commands: extract dirname from first positional arg containing /
202
+ if binary in ("cat", "head", "tail", "less", "more"):
203
+ for arg in argv[1:]:
204
+ if not arg.startswith("-") and "/" in arg:
205
+ dirname = os.path.dirname(arg)
206
+ if dirname:
207
+ return [dirname]
208
+ return []
209
+ return []
210
+
211
+ return []
212
+
213
+
214
+ def _collect_directories(results: list[CommandResult]) -> list[str]:
215
+ """Collect directories from command results, including inner commands."""
216
+ directories: list[str] = []
217
+
218
+ for result in results:
219
+ # Directory builtins: cd, pushd, popd
220
+ if result.command and result.command[0] in ("cd", "pushd") and len(result.argv) > 1:
221
+ directories.append(result.argv[1])
222
+
223
+ # Directories captured from global options (e.g., git -C /path)
224
+ if result.directories:
225
+ directories.extend(result.directories)
226
+
227
+ # Well-known commands that take directory arguments
228
+ directories.extend(_extract_directories_from_argv(result.command, result.argv))
229
+
230
+ # Collect directories from inner commands recursively
231
+ directories.extend(_collect_inner_directories(result.inner_commands))
232
+
233
+ return directories
234
+
235
+
236
+ def _collect_inner_directories(results: list[InnerCommandResult]) -> list[str]:
237
+ """Collect directories from inner command results recursively."""
238
+ directories: list[str] = []
239
+
240
+ for result in results:
241
+ directories.extend(_extract_directories_from_argv(result.command, result.argv))
242
+ directories.extend(_collect_inner_directories(result.inner_commands))
243
+
244
+ return directories
bash_classify/cli.py ADDED
@@ -0,0 +1,110 @@
1
+ """CLI entry point for bash-classify."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import sys
7
+
8
+ from .classifier import classify_expression
9
+ from .models import (
10
+ CommandResult,
11
+ ExpressionResult,
12
+ InnerCommandResult,
13
+ Redirect,
14
+ )
15
+
16
+
17
+ def _inner_command_to_dict(result: InnerCommandResult) -> dict:
18
+ """Convert an InnerCommandResult to a JSON-serializable dict."""
19
+ d: dict = {
20
+ "delegation_mode": result.delegation_mode,
21
+ "delegation_source": result.delegation_source,
22
+ "command": result.command,
23
+ "argv": result.argv,
24
+ "classification": result.classification.value,
25
+ "matched_rule": result.matched_rule,
26
+ }
27
+
28
+ if result.ignored_options:
29
+ d["ignored_options"] = result.ignored_options
30
+ if result.remaining_options:
31
+ d["remaining_options"] = result.remaining_options
32
+ if result.overriding_option is not None:
33
+ d["overriding_option"] = result.overriding_option
34
+
35
+ d["inner_commands"] = [_inner_command_to_dict(ic) for ic in result.inner_commands]
36
+
37
+ return d
38
+
39
+
40
+ def _command_to_dict(result: CommandResult) -> dict:
41
+ """Convert a CommandResult to a JSON-serializable dict."""
42
+ d: dict = {
43
+ "command": result.command,
44
+ "argv": result.argv,
45
+ "classification": result.classification.value,
46
+ "matched_rule": result.matched_rule,
47
+ }
48
+
49
+ if result.ignored_options:
50
+ d["ignored_options"] = result.ignored_options
51
+ if result.remaining_options:
52
+ d["remaining_options"] = result.remaining_options
53
+ if result.classification_reason is not None:
54
+ d["classification_reason"] = result.classification_reason
55
+ if result.overriding_option is not None:
56
+ d["overriding_option"] = result.overriding_option
57
+
58
+ d["inner_commands"] = [_inner_command_to_dict(ic) for ic in result.inner_commands]
59
+
60
+ return d
61
+
62
+
63
+ def _redirect_to_dict(redirect: Redirect) -> dict:
64
+ """Convert a Redirect to a JSON-serializable dict."""
65
+ return {
66
+ "operator": redirect.operator,
67
+ "target": redirect.target,
68
+ "affects_classification": redirect.affects_classification,
69
+ }
70
+
71
+
72
+ def _result_to_dict(result: ExpressionResult) -> dict:
73
+ """Convert an ExpressionResult to a JSON-serializable dict."""
74
+ d: dict = {
75
+ "expression": result.expression,
76
+ "classification": result.classification.value,
77
+ "directories": result.directories,
78
+ "commands": [_command_to_dict(cmd) for cmd in result.commands],
79
+ }
80
+
81
+ if result.redirects:
82
+ d["redirects"] = [_redirect_to_dict(r) for r in result.redirects]
83
+
84
+ if result.parse_warnings:
85
+ d["parse_warnings"] = result.parse_warnings
86
+
87
+ return d
88
+
89
+
90
+ def main() -> None:
91
+ """Read bash expressions from stdin, classify, and output JSON.
92
+
93
+ Exit codes:
94
+ 0 - successfully classified
95
+ 1 - parse error (invalid bash syntax)
96
+ 2 - internal error
97
+ """
98
+ try:
99
+ expression = sys.stdin.read().strip()
100
+ if not expression:
101
+ sys.exit(1)
102
+
103
+ result = classify_expression(expression)
104
+ output = _result_to_dict(result)
105
+ json.dump(output, sys.stdout, indent=2)
106
+ sys.stdout.write("\n")
107
+ sys.exit(0)
108
+ except Exception as e:
109
+ print(f"bash-classify: internal error: {e}", file=sys.stderr)
110
+ sys.exit(2)
@@ -0,0 +1,23 @@
1
+ # $schema: ../../../schemas/command.schema.json
2
+ command: apt
3
+ description: "Debian package management tool"
4
+ strict: false
5
+ subcommands:
6
+ list:
7
+ classification: READONLY
8
+ show:
9
+ classification: READONLY
10
+ search:
11
+ classification: READONLY
12
+ install:
13
+ classification: DANGEROUS
14
+ remove:
15
+ classification: DANGEROUS
16
+ purge:
17
+ classification: DANGEROUS
18
+ update:
19
+ classification: WRITE
20
+ upgrade:
21
+ classification: DANGEROUS
22
+ autoremove:
23
+ classification: DANGEROUS
@@ -0,0 +1,5 @@
1
+ # $schema: ../../../schemas/command.schema.json
2
+ command: awk
3
+ description: "Pattern scanning and text processing language"
4
+ classification: READONLY
5
+ strict: false
@@ -0,0 +1,5 @@
1
+ # $schema: ../../../schemas/command.schema.json
2
+ command: basename
3
+ description: "Strip directory and suffix from filenames"
4
+ classification: READONLY
5
+ strict: false
@@ -0,0 +1,18 @@
1
+ # $schema: ../../../schemas/command.schema.json
2
+ command: bash
3
+ description: "GNU Bourne-Again SHell"
4
+ classification: DANGEROUS
5
+ strict: false
6
+ delegates_to:
7
+ mode: flag_value_is_expression
8
+ flag: -c
9
+ options:
10
+ -c: {takes_value: true}
11
+ -e: {}
12
+ -x: {}
13
+ -i: {}
14
+ --norc: {}
15
+ --noprofile: {}
16
+ -l: {}
17
+ --login: {aliases: [-l]}
18
+ -n: {}
@@ -0,0 +1,25 @@
1
+ # $schema: ../../../schemas/command.schema.json
2
+ command: brew
3
+ description: "macOS and Linux package manager"
4
+ strict: false
5
+ subcommands:
6
+ list:
7
+ classification: READONLY
8
+ info:
9
+ classification: READONLY
10
+ search:
11
+ classification: READONLY
12
+ install:
13
+ classification: WRITE
14
+ uninstall:
15
+ classification: WRITE
16
+ update:
17
+ classification: WRITE
18
+ upgrade:
19
+ classification: WRITE
20
+ cleanup:
21
+ classification: WRITE
22
+ doctor:
23
+ classification: READONLY
24
+ config:
25
+ classification: READONLY
@@ -0,0 +1,6 @@
1
+ # $schema: ../../../schemas/command.schema.json
2
+ command: builtin
3
+ description: "Execute a shell builtin command"
4
+ classification: READONLY
5
+ delegates_to:
6
+ mode: rest_are_argv
@@ -0,0 +1,29 @@
1
+ # $schema: ../../../schemas/command.schema.json
2
+ command: cargo
3
+ description: "Rust package manager and build tool"
4
+ strict: false
5
+ subcommands:
6
+ build:
7
+ classification: WRITE
8
+ test:
9
+ classification: WRITE
10
+ run:
11
+ classification: DANGEROUS
12
+ check:
13
+ classification: READONLY
14
+ clippy:
15
+ classification: READONLY
16
+ options:
17
+ --fix: {overrides: WRITE}
18
+ fmt:
19
+ classification: WRITE
20
+ doc:
21
+ classification: WRITE
22
+ publish:
23
+ classification: DANGEROUS
24
+ install:
25
+ classification: WRITE
26
+ clean:
27
+ classification: WRITE
28
+ update:
29
+ classification: WRITE
@@ -0,0 +1,5 @@
1
+ # $schema: ../../../schemas/command.schema.json
2
+ command: cat
3
+ description: "Concatenate and print files"
4
+ classification: READONLY
5
+ strict: false
@@ -0,0 +1,8 @@
1
+ # $schema: ../../../schemas/command.schema.json
2
+ command: chgrp
3
+ description: "Change group ownership of files"
4
+ classification: WRITE
5
+ strict: false
6
+ options:
7
+ -R: {overrides: DANGEROUS}
8
+ --recursive: {overrides: DANGEROUS, aliases: [-R]}
@@ -0,0 +1,8 @@
1
+ # $schema: ../../../schemas/command.schema.json
2
+ command: chmod
3
+ description: "Change file mode bits"
4
+ classification: WRITE
5
+ strict: false
6
+ options:
7
+ -R: {overrides: DANGEROUS}
8
+ --recursive: {overrides: DANGEROUS, aliases: [-R]}
@@ -0,0 +1,8 @@
1
+ # $schema: ../../../schemas/command.schema.json
2
+ command: chown
3
+ description: "Change file owner and group"
4
+ classification: WRITE
5
+ strict: false
6
+ options:
7
+ -R: {overrides: DANGEROUS}
8
+ --recursive: {overrides: DANGEROUS, aliases: [-R]}
@@ -0,0 +1,5 @@
1
+ # $schema: ../../../schemas/command.schema.json
2
+ command: column
3
+ description: "Format input into multiple columns"
4
+ classification: READONLY
5
+ strict: false
@@ -0,0 +1,5 @@
1
+ # $schema: ../../../schemas/command.schema.json
2
+ command: comm
3
+ description: "Compare two sorted files line by line"
4
+ classification: READONLY
5
+ strict: false
@@ -0,0 +1,10 @@
1
+ # $schema: ../../../schemas/command.schema.json
2
+ command: command
3
+ description: "Execute a command or display command info"
4
+ classification: READONLY
5
+ delegates_to:
6
+ mode: rest_are_argv
7
+ options:
8
+ -v: {}
9
+ -V: {}
10
+ -p: {}
@@ -0,0 +1,5 @@
1
+ # $schema: ../../../schemas/command.schema.json
2
+ command: cp
3
+ description: "Copy files and directories"
4
+ classification: WRITE
5
+ strict: false
@@ -0,0 +1,28 @@
1
+ # $schema: ../../../schemas/command.schema.json
2
+ command: curl
3
+ description: "Transfer data from or to a server"
4
+ classification: WRITE
5
+ strict: false
6
+ options:
7
+ -o: {takes_value: true, overrides: WRITE}
8
+ --output: {takes_value: true, overrides: WRITE, aliases: [-o]}
9
+ -O: {overrides: WRITE}
10
+ --remote-name: {overrides: WRITE, aliases: [-O]}
11
+ -T: {takes_value: true, overrides: WRITE}
12
+ --upload-file: {takes_value: true, overrides: WRITE, aliases: [-T]}
13
+ -X: {takes_value: true}
14
+ --request: {takes_value: true, aliases: [-X]}
15
+ -d: {takes_value: true, overrides: WRITE}
16
+ --data: {takes_value: true, overrides: WRITE, aliases: [-d]}
17
+ -F: {takes_value: true, overrides: WRITE}
18
+ --form: {takes_value: true, overrides: WRITE, aliases: [-F]}
19
+ -H: {takes_value: true}
20
+ --header: {takes_value: true, aliases: [-H]}
21
+ -s: {}
22
+ --silent: {aliases: [-s]}
23
+ -f: {}
24
+ --fail: {aliases: [-f]}
25
+ -L: {}
26
+ --location: {aliases: [-L]}
27
+ -k: {}
28
+ --insecure: {aliases: [-k]}
@@ -0,0 +1,5 @@
1
+ # $schema: ../../../schemas/command.schema.json
2
+ command: cut
3
+ description: "Remove sections from each line of files"
4
+ classification: READONLY
5
+ strict: false
@@ -0,0 +1,8 @@
1
+ # $schema: ../../../schemas/command.schema.json
2
+ command: date
3
+ description: "Display or set the system date and time"
4
+ classification: READONLY
5
+ strict: true
6
+ options:
7
+ -s: {takes_value: true, overrides: DANGEROUS}
8
+ --set: {takes_value: true, overrides: DANGEROUS, aliases: [-s]}
@@ -0,0 +1,5 @@
1
+ # $schema: ../../../schemas/command.schema.json
2
+ command: df
3
+ description: "Report file system disk space usage"
4
+ classification: READONLY
5
+ strict: false
@@ -0,0 +1,5 @@
1
+ # $schema: ../../../schemas/command.schema.json
2
+ command: diff
3
+ description: "Compare files line by line"
4
+ classification: READONLY
5
+ strict: false
@@ -0,0 +1,5 @@
1
+ # $schema: ../../../schemas/command.schema.json
2
+ command: dig
3
+ description: "DNS lookup utility"
4
+ classification: READONLY
5
+ strict: false
@@ -0,0 +1,5 @@
1
+ # $schema: ../../../schemas/command.schema.json
2
+ command: dirname
3
+ description: "Strip last component from file name"
4
+ classification: READONLY
5
+ strict: false