Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement link util #180

Merged
merged 6 commits into from
Nov 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ count below and mark it as done in this README.md. Thanks!
GNU coreutils. They are not 100% compatiable. If you encounter different behaviors,
compare against the true GNU coreutils version on the Linux-based tests first.

## Completed (73/109) - 67% done!
## Completed (74/109) - 68% done!

| Done | Cmd | Descripton | Windows |
| :-----: | --------- | ------------------------------------------------ | ------- |
Expand Down Expand Up @@ -94,7 +94,7 @@ compare against the true GNU coreutils version on the Linux-based tests first.
| | install | Copy files and set attributes | |
| | join | Join lines on a common field | ✓ |
| | kill | Send a signal to processes | ✓ |
| | link | Make a hard link via the link syscall | ✓ |
| ✓ | link | Make a hard link via the link syscall | ✓ |
| ✓ | ln | Make links between files | ✓ |
| ✓ | logname | Print current login name | ✓ |
| ✓ | ls | List directory contents | |
Expand Down Expand Up @@ -129,7 +129,7 @@ compare against the true GNU coreutils version on the Linux-based tests first.
| ✓ | sha256sum | Print or check SHA-2 256 bit digests | ✓ |
| ✓ | sha384sum | Print or check SHA-2 384 bit digests | ✓ |
| ✓ | sha512sum | Print or check SHA-2 512 bit digests | ✓ |
| | shred | Remove files more securely | ✓ |
| ✓ | shred | Remove files more securely | ✓ |
| ✓ | shuf | Shuffling text | ✓ |
| ✓ | sleep | Delay for a specified time | ✓ |
| ✓ | sort | Sort text files | ✓ |
Expand Down
2 changes: 1 addition & 1 deletion common/testing/testing.v
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ pub fn same_results(cmd1 string, cmd2 string) bool {
return cmd1_res.exit_code == cmd2_res.exit_code && noutput1 == noutput2
}

fn normalise(s string) string {
pub fn normalise(s string) string {
return s.replace_each(['‘', "'", '’', "'"]).replace(' ', ' ').replace(' ', ' ').replace(' ',
' ').replace(', ', ' ').split_into_lines().join('\n').trim_space()
}
Expand Down
Empty file removed src/id/delete.me
Empty file.
Empty file removed src/link/delete.me
Empty file.
42 changes: 42 additions & 0 deletions src/link/link.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
module main

import common
import os

const app = common.CoreutilInfo{
name: 'link'
description: 'Call the link function to create a link named FILE2 to an existing FILE1.'
}

struct Settings {
mut:
files []string
}

fn args() Settings {
mut fp := app.make_flag_parser(os.args)
mut st := Settings{}
st.files = fp.remaining_parameters()
match st.files.len {
0 { app.quit(message: 'missing operand') }
1 { app.quit(message: "missing operand after '${st.files[0]}'", show_help_advice: true) }
2 {}
else { app.quit(message: "extra operand '${st.files[2]}'", show_help_advice: true) }
}

return st
}

fn link(settings Settings) !int {
mut exit_code := 0
os.link(settings.files[0], settings.files[1]) or {
app.quit(
message: "cannot create link '${settings.files[1]}' to '${settings.files[0]}': ${err.msg()}"
)
}
return exit_code
}

fn main() {
exit(link(args()) or { common.err_programming_error })
}
67 changes: 67 additions & 0 deletions src/link/link_test.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
module main

import common.testing
import os

const rig = testing.prepare_rig(util: 'link')

fn testsuite_begin() {
}

fn testsuite_end() {
}

fn test_help_and_version() {
rig.assert_help_and_version_options_work()
}

fn test_compare() {
$if windows {
// The coreutils used on Windows does not produce the exact
// same error messages
rig.assert_same_exit_code('a')
rig.assert_same_exit_code('a b')
rig.assert_same_exit_code('a b c')
rig.assert_same_exit_code('a b c d e f')
os.mkdir('d')!
rig.assert_same_exit_code('d e')
os.rmdir('d')!
} $else {
rig.assert_same_results('a')
rig.assert_same_results('a b')
rig.assert_same_results('a b c')
rig.assert_same_results('a b c d e f')
os.mkdir('d')!
rig.assert_same_results('d e')
os.rmdir('d')!
}

// We can't use assert_same_results here because the hard link will already
// exist when the second util is called
os.write_file('a', '12345')!
cmd1_res := rig.call_orig('a b')
assert os.is_file('a')
assert os.is_file('b')
assert os.read_file('b') or { '' } == '12345'
mut f := os.open_append('b')!
f.write_string('67890')!
f.close()
assert os.read_file('a') or { '' } == '1234567890'
os.rm('b')!
os.rm('a')!

os.write_file('a', '12345')!
cmd2_res := rig.call_new('a b')
assert os.is_file('a')
assert os.is_file('b')
assert os.read_file('b') or { '' } == '12345'
f = os.open_append('b')!
f.write_string('67890')!
f.close()
assert os.read_file('a') or { '' } == '1234567890'
os.rm('b')!
os.rm('a')!

assert cmd1_res.exit_code == cmd2_res.exit_code
assert testing.normalise(cmd1_res.output) == testing.normalise(cmd2_res.output)
}
Loading