Skip to content

Commit 92defb2

Browse files
committed
better go-ls instructions
1 parent 7fe6ed2 commit 92defb2

File tree

1 file changed

+57
-14
lines changed

1 file changed

+57
-14
lines changed

cli-files/README.md

Lines changed: 57 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Objectives:
1313
- Open, read (and close) files from CLI arguments
1414
- Reading directories for files
1515

16-
## Instructions
16+
## Project
1717

1818
You're going to build a command-line application that reads data from your computer's file system.
1919

@@ -61,10 +61,17 @@ And within every dewdrop
6161
A world of struggle.
6262
```
6363

64-
### Steps (notes)
64+
### go-ls
6565

66-
- make sure the working directory is go-ls: `cd go-ls`
67-
- create `go.mod`, `main.go`, `cmd/root.go`
66+
These steps will leave some work for you to do. If something's not clear, search around for to find the answer. If you're stuck for half an hour at most, ask for help. Remember to use Git to store your progress, committing often in small increments with useful descriptions.
67+
68+
A full implementation of this is available on the `impl/go-ls` branch.
69+
70+
The `go-ls` directory is provided for you with some example files in the `assets/` folder.
71+
72+
In your command line/terminal, make sure your working directory is go-ls: `cd go-ls`
73+
74+
Create `go.mod`, `main.go`, `cmd/root.go`. The `touch` command creates files: `touch go.mod`.
6875

6976
```go
7077
// go.mod
@@ -93,18 +100,54 @@ package cmd
93100
func Execute() {}
94101
```
95102

96-
- `go get -u github.com/spf13/cobra@latest`
97-
- follow cobra [user guide](https://github.com/spf13/cobra/blob/master/user_guide.md) to make a root command that prints hello in `cmd/root.go`
98-
- implement basic ls with `os.ReadDir`
99-
- allow the command to take arguments with `cobra.ArbitraryArgs`
100-
- when passed an argument such as `go-ls assets`, read from the passed directory
101-
- ensure that this directory path can be relative: `go-ls ..` and `go-ls ../go-ls` should both work
102-
- handle the error (e.g. `Error: fdopendir go.mod: not a directory` when passing `go-ls` a file argument: `go-ls go.mod`)
103-
- update `go-ls` to match `ls` in terms of how it handles files (hint: `os.Stat`)
104-
- make `go-ls -h` include a helpful description
105-
- bonus: write some tests for `go-ls`
103+
We're going to use the [Cobra][cobra] package to make these commands. It does a lot of magic for you.
104+
105+
Install the Cobra package using the `go get` command: `go get -u github.com/spf13/cobra@latest`
106+
107+
The Cobra [user guide](https://github.com/spf13/cobra/blob/master/user_guide.md) will show you how to make a root command that prints hello in `cmd/root.go`.
108+
109+
To use your command, install and run it: `go install .`
110+
111+
Then run the following so that your command line knows where to look for the executable code that Go is generating: `export PATH=$PATH:$(dirname $(go list -f '{{.Target}}' .))`
112+
113+
You should now be able to run `go-ls`.
114+
115+
Now, when you change your code, install and run it: `go install . && go-ls`
116+
117+
Now you've got something working, we'll speed up the steps. You can do it!
118+
119+
The `ls` command reads a directory, generating a list of files or sub-directories. Go comes with packages for interacting with files built-in, include a package called [os][os], which contains a function called `ReadDir` which will do lots of the work of `ls` for you.
120+
121+
See if you can implement basic `ls` with `os.ReadDir`. It should read the list of files in the current, "working" directory:
122+
123+
```
124+
> go install .
125+
> cd assets
126+
> go-ls
127+
dew.txt
128+
for_you.txt
129+
rain.txt
130+
```
131+
132+
The real `ls` allows you pass a directory to be read: `ls assets`.
133+
134+
Extend your `go-ls` to allow the command to take arguments (look for `cobra.ArbitraryArgs`) and then, when passed an argument such as `go-ls assets`, read from the passed directory.
135+
136+
Make that this directory path can be relative: `go-ls ..` and `go-ls ../go-ls` should both work.
137+
138+
Handle the error `Error: fdopendir go.mod: not a directory` when passing `go-ls` a file argument: `go-ls go.mod`. Think hard about why this is happening before you try to fix it.
139+
140+
Update `go-ls` to match `ls` in terms of how it handles files (hint: `os.Stat`) — it should just output the name of the file.
141+
142+
Make `go-ls -h` include a helpful description.
143+
144+
If you smash through this, here's some fun/tricky extensions:
145+
146+
- Write some tests for `go-ls`
147+
- Extend `go-ls` to support some more features of the real `ls` (for example, `ls -m assets`)
106148

107149
[go]: https://go.dev/
108150
[cat]: https://en.m.wikipedia.org/wiki/Cat_(Unix)
109151
[ls]: https://en.m.wikipedia.org/wiki/Ls
110152
[cobra]: https://github.com/spf13/cobra#overview
153+
[os]: https://pkg.go.dev/os

0 commit comments

Comments
 (0)