Skip to content

Commit dd1e0d4

Browse files
committed
claude changes + Cmd manual changes
1 parent 3c5f29f commit dd1e0d4

32 files changed

Lines changed: 835 additions & 498 deletions

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ repository = "https://github.com/roc-lang/basic-cli"
3939

4040
[workspace.dependencies]
4141
# Core Roc types
42-
# roc-nightly: 2026-02-09
43-
roc_std_new = { git = "https://github.com/roc-lang/roc", rev = "a6e81e8a8ce50bbb3f00e7a553d08f2bb919e8e0" }
42+
# roc-nightly: 2026-02-20
43+
roc_std_new = { git = "https://github.com/roc-lang/roc", rev = "c5d87ef595fdc1c8b28dfdb6ebbe5b44ddea966f" }
4444

4545
# Internal crates
4646
roc_io_error = { path = "crates/roc_io_error" }

ci/all_tests.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ echo ""
182182
echo "=== Checking examples ==="
183183
for example in "${MIGRATED_EXAMPLES[@]}"; do
184184
echo "Checking: ${example}.roc"
185-
roc check "examples/${example}.roc"
185+
roc check --no-cache "examples/${example}.roc"
186186
done
187187

188188
# roc build migrated examples
@@ -194,7 +194,7 @@ else
194194
fi
195195
for example in "${MIGRATED_EXAMPLES[@]}"; do
196196
echo "Building: ${example}.roc"
197-
roc build "examples/${example}.roc"
197+
roc build --no-cache "examples/${example}.roc"
198198
mv "./${example}" "examples/"
199199
done
200200

examples/bytes-stdin-stdout.roc

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,12 @@ app [main!] { pf: platform "../platform/main.roc" }
33
import pf.Stdin
44
import pf.Stdout
55
import pf.Stderr
6-
import pf.Arg exposing [Arg]
76

87
# To run this example: check the README.md in this folder
98

10-
main! : List Arg => Result {} _
11-
main! = |_args|
9+
main! = |_args| {
1210
data = Stdin.bytes!({})?
1311
Stderr.write_bytes!(data)?
1412
Stdout.write_bytes!(data)?
15-
Ok {}
13+
Ok({})
14+
}

examples/command-line-args.roc

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,15 @@ app [main!] { pf: platform "../platform/main.roc" }
22

33
import pf.Stdout
44

5-
main! : List(Str) => Try({}, [Exit(I32)])
65
main! = |args| {
76
# Skip first arg (executable path), get the remaining args
87
match args.drop_first(1) {
98
[first_arg, ..] => {
10-
Stdout.line!("received argument: ${first_arg}")
9+
Stdout.line!("received argument: ${first_arg}")?
1110
Ok({})
1211
}
1312
[] => {
14-
Stdout.line!("Error: I expected one argument, but got none.")
13+
Stdout.line!("Error: I expected one argument, but got none.")?
1514
Err(Exit(1))
1615
}
1716
}

examples/command.roc

Lines changed: 40 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -6,45 +6,44 @@ import pf.Cmd
66
# Different ways to run commands like you do in a terminal.
77

88
main! = |_args| {
9-
# Simplest way to execute a command (prints to your terminal).
10-
exec_result = Cmd.exec!("echo", ["Hello"])
11-
match exec_result {
12-
Ok({}) => {}
13-
Err(_) => Stdout.line!("Error running echo")
14-
}
15-
16-
# To execute and capture the output (stdout and stderr) without inheriting your terminal.
17-
output_result = Cmd.exec_output!(Cmd.args(Cmd.new("echo"), ["Hi"]))
18-
match output_result {
19-
Ok(cmd_output) => Stdout.line!("{stderr_utf8_lossy: \"${cmd_output.stderr_utf8_lossy}\", stdout_utf8: \"${cmd_output.stdout_utf8}\"}")
20-
Err(_) => Stdout.line!("Error capturing output")
21-
}
22-
23-
# To run a command with environment variables.
24-
env_cmd = Cmd.args(
25-
Cmd.envs(
26-
Cmd.env(
27-
Cmd.clear_envs(Cmd.new("env")),
28-
"FOO",
29-
"BAR",
30-
),
31-
[("BAZ", "DUCK"), ("XYZ", "ABC")],
32-
),
33-
["-v"],
34-
)
35-
env_result = Cmd.exec_cmd!(env_cmd)
36-
match env_result {
37-
Ok({}) => {}
38-
Err(_) => Stdout.line!("Error running env")
39-
}
40-
41-
# To execute and just get the exit code (prints to your terminal).
42-
# Prefer using `exec!` or `exec_cmd!`.
43-
exit_result = Cmd.exec_exit_code!(Cmd.args(Cmd.new("cat"), ["non_existent.txt"]))
44-
match exit_result {
45-
Ok(exit_code) => Stdout.line!("Exit code: ${exit_code.to_str()}")
46-
Err(_) => Stdout.line!("Error getting exit code")
47-
}
48-
49-
Ok({})
9+
# Simplest way to execute a command (prints to your terminal).
10+
Cmd.exec!("echo", ["Hello"])?
11+
12+
# To execute and capture the output (stdout and stderr) without inheriting your terminal.
13+
cmd_output =
14+
Cmd.new("echo")
15+
.args(["Hi"])
16+
.exec_output!()?
17+
18+
Stdout.line!("${Str.inspect(cmd_output)}")?
19+
20+
# To run a command with environment variables.
21+
Cmd.new("env")
22+
.clear_envs() # You probably don't need to clear all other environment variables, this is just an example.
23+
.env("FOO", "BAR")
24+
.envs([("BAZ", "DUCK"), ("XYZ", "ABC")]) # Set multiple environment variables at once with `envs`
25+
.args(["-v"])
26+
.exec_cmd!()?
27+
28+
# To execute and just get the exit code (prints to your terminal).
29+
# Prefer using `exec!` or `exec_cmd!`.
30+
exit_code =
31+
Cmd.new("cat")
32+
.args(["non_existent.txt"])
33+
.exec_exit_code!()?
34+
35+
Stdout.line!("Exit code: ${exit_code.to_str()}")?
36+
37+
# TODO add exec_output_bytes
38+
39+
# To execute and capture the output (stdout and stderr) in the original form as bytes without inheriting your terminal.
40+
# Prefer using `exec_output!`.
41+
#cmd_output_bytes =
42+
# Cmd.new("echo")
43+
# .args(["Hi"])
44+
# .exec_output_bytes!()?
45+
46+
#Stdout.line!("${Str.inspect(cmd_output_bytes)}")?
47+
48+
Ok({})
5049
}

examples/dir.roc

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,40 @@ import pf.Dir
66
# Demo of all Dir functions.
77

88
main! = |_args| {
9-
# Create a directory
10-
Dir.create!("empty-dir")?
9+
dir_result = {
10+
# Create a directory
11+
Dir.create!("empty-dir")?
1112

12-
# Create a directory and its parents
13-
Dir.create_all!("nested-dir/a/b/c")?
13+
# Create a directory and its parents
14+
Dir.create_all!("nested-dir/a/b/c")?
1415

15-
# Create a child directory
16-
Dir.create!("nested-dir/child")?
16+
# Create a child directory
17+
Dir.create!("nested-dir/child")?
1718

18-
# List the contents of a directory
19-
paths = Dir.list!("nested-dir")?
19+
# List the contents of a directory
20+
paths = Dir.list!("nested-dir")?
2021

21-
# Check the contents of the directory
22-
expect List.len(paths) == 2
23-
expect List.contains(paths, "nested-dir/a")
24-
expect List.contains(paths, "nested-dir/child")
22+
# Check the contents of the directory
23+
expect List.len(paths) == 2
24+
expect List.contains(paths, "nested-dir/a")
25+
expect List.contains(paths, "nested-dir/child")
2526

26-
# Delete an empty directory
27-
Dir.delete_empty!("empty-dir")?
27+
# Delete an empty directory
28+
Dir.delete_empty!("empty-dir")?
2829

29-
# Delete all directories recursively
30-
Dir.delete_all!("nested-dir")?
30+
# Delete all directories recursively
31+
Dir.delete_all!("nested-dir")?
3132

32-
Stdout.line!("Success!")
33+
_r = Stdout.line!("Success!")
3334

34-
Ok({})
35+
Ok({})
36+
}
37+
38+
match dir_result {
39+
Ok({}) => Ok({})
40+
Err(_) => {
41+
_r = Stdout.line!("Error during directory operations")
42+
Err(Exit(1))
43+
}
44+
}
3545
}

examples/env-var.roc

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,17 @@ import pf.Env
55

66
# How to read environment variables with Env.var!
77

8-
main! : List(Str) => Try({}, [Exit(I32)])
98
main! = |_args| {
10-
editor = Env.var!("EDITOR")
9+
result = Env.var!("EDITOR")
1110

12-
if Str.is_empty(editor) {
13-
Stdout.line!("EDITOR is not set")
14-
} else {
15-
Stdout.line!("Your favorite editor is ${editor}!")
11+
match result {
12+
Ok(editor) => {
13+
_r = Stdout.line!("Your favorite editor is ${editor}!")
14+
Ok({})
15+
}
16+
Err(VarNotFound(name)) => {
17+
_r = Stdout.line!("${name} is not set")
18+
Ok({})
19+
}
1620
}
17-
18-
Ok({})
1921
}

examples/error-handling.roc

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,41 @@ main! = |_args| {
1111
# Try to read a file that doesn't exist - should error
1212
result = File.read_utf8!("nonexistent-file.txt")
1313
match result {
14-
Ok(content) => Stdout.line!("Unexpected success: ${content}")
15-
Err(FileErr(NotFound)) => Stdout.line!("Expected error: File not found (NotFound)")
16-
Err(FileErr(PermissionDenied)) => Stdout.line!("Error: Permission denied")
17-
Err(FileErr(Other(msg))) => Stdout.line!("Error: ${msg}")
18-
Err(_) => Stdout.line!("Error: Other file error")
14+
Ok(content) => {
15+
_r = Stdout.line!("Unexpected success: ${content}")
16+
}
17+
Err(FileErr(NotFound)) => {
18+
_r = Stdout.line!("Expected error: File not found (NotFound)")
19+
}
20+
Err(FileErr(PermissionDenied)) => {
21+
_r = Stdout.line!("Error: Permission denied")
22+
}
23+
Err(FileErr(Other(msg))) => {
24+
_r = Stdout.line!("Error: ${msg}")
25+
}
26+
Err(_) => {
27+
_r = Stdout.line!("Error: Other file error")
28+
}
1929
}
2030
2131
# Now demonstrate success path - create, read, then cleanup
22-
# Using ? operator to propagate errors (works with open tag unions)
23-
File.write_utf8!(file_name, "Hello from error-handling example!")?
32+
file_result = {
33+
File.write_utf8!(file_name, "Hello from error-handling example!")?
2434
25-
content = File.read_utf8!(file_name)?
26-
Stdout.line!("${file_name} contains: ${content}")
35+
content = File.read_utf8!(file_name)?
36+
_r = Stdout.line!("${file_name} contains: ${content}")
2737
28-
# Cleanup
29-
File.delete!(file_name)?
38+
# Cleanup
39+
File.delete!(file_name)?
3040
31-
Ok({})
41+
Ok({})
42+
}
43+
44+
match file_result {
45+
Ok({}) => Ok({})
46+
Err(_) => {
47+
_r = Stdout.line!("Error during file operations")
48+
Err(Exit(1))
49+
}
50+
}
3251
}

examples/file-read-write.roc

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,26 @@ import pf.File
88
main! = |_args| {
99
out_file = "out.txt"
1010

11-
Stdout.line!("Writing a string to out.txt")
11+
_r = Stdout.line!("Writing a string to out.txt")
1212
13-
File.write_utf8!(out_file, "a string!")?
13+
result = {
14+
File.write_utf8!(out_file, "a string!")?
1415
15-
contents = File.read_utf8!(out_file)?
16+
contents = File.read_utf8!(out_file)?
1617
17-
Stdout.line!("I read the file back. Its contents are: \"${contents}\"")
18+
_r = Stdout.line!("I read the file back. Its contents are: \"${contents}\"")
1819

19-
# Cleanup
20-
File.delete!(out_file)?
20+
# Cleanup
21+
File.delete!(out_file)?
2122

22-
Ok({})
23+
Ok({})
24+
}
25+
26+
match result {
27+
Ok({}) => Ok({})
28+
Err(_) => {
29+
_r = Stdout.line!("Error during file operations")
30+
Err(Exit(1))
31+
}
32+
}
2333
}

0 commit comments

Comments
 (0)