Skip to content

Commit 0259447

Browse files
authored
refactor docs, add examples (bitfield#94)
refactor docs, add examples
1 parent b95a706 commit 0259447

15 files changed

+609
-864
lines changed

CONTRIBUTING.md

+1-14
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ So you'd like to contribute to the `script` library? Excellent! Thank you very m
44
- [Look for existing issues](#look-for-existing-issues)
55
- [Open a new issue before making a PR](#open-a-new-issue-before-making-a-pr)
66
- [Write a use case](#write-a-use-case)
7-
- [Ideas](#ideas)
87
- [Coding standards](#coding-standards)
98
- [Tests](#tests)
109
- [Use the standard library](#use-the-standard-library)
@@ -54,16 +53,6 @@ A concrete use case also provides a helpful example program that can be included
5453

5554
The final reason is that it's tempting to over-elaborate a design and add all sorts of bells and whistles that nobody actually wants. Simple APIs are best. If you think of an enhancement, but it's not needed for your use case, leave it out. Things can always be enhanced later if necessary.
5655

57-
## Ideas
58-
59-
These are some ideas I've been thinking about. Some of them have existing issues and PRs with active discussion, so check those first.
60-
61-
* `Get()` makes a web request, like `curl`, and pipes the result
62-
* `Net()` makes a network connection to a specified address and port, and reads the connection until it's closed
63-
* `ListFiles()` takes a filesystem path or glob, and pipes the list of matching files
64-
* `Find()` pipes a list of files matching various criteria (name, modified time, and so on)
65-
* `Processes()` pipes the list of running processes, like `ps`.
66-
6756
# Coding standards
6857

6958
A library is easier to use, and easier for contributors to work on, if it has a consistent, unified style, approach, and layout. Here are a few hints on how to make a `script` PR that will be accepted right away.
@@ -157,9 +146,7 @@ This is the _whole_ user manual for your code. It will be included in the autoge
157146

158147
## Update the README
159148

160-
Any change to the `script` API should also be accompanied by an update to the README. If you add a new method, add it in the appropriate place (sources, filters, or sinks), in its correct order alphabetically, and with a suitable (brief) example of its use.
161-
162-
The README has a table of contents that is automatically generated and updated (when I work on it) by the VS Code [Markdown All In One](github.com/yzhang-gh/vscode-markdown) extension. However, you don't need to use this to update the table of contents yourself. The format should be fairly self-explanatory.
149+
Any change to the `script` API should also be accompanied by an update to the README. If you add a new method, add it in the appropriate place (sources, filters, or sinks), in its correct order alphabetically, and with a suitable (brief) description.
163150

164151
# Writing pipe operations
165152

README.md

+105-800
Large diffs are not rendered by default.

examples/visitors/go.mod

-5
This file was deleted.

examples_test.go

+341
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,341 @@
1+
package script_test
2+
3+
import (
4+
"fmt"
5+
"regexp"
6+
"strings"
7+
8+
"github.com/bitfield/script"
9+
)
10+
11+
func ExampleArgs() {
12+
script.Args().Stdout()
13+
// prints command-line arguments
14+
}
15+
16+
func ExampleEcho() {
17+
script.Echo("Hello, world!").Stdout()
18+
// Output:
19+
// Hello, world!
20+
}
21+
22+
func ExampleExec_ok() {
23+
script.Exec("echo Hello, world!").Stdout()
24+
// Output:
25+
// Hello, world!
26+
}
27+
28+
func ExampleExec_exitstatus() {
29+
p := script.Exec("echo")
30+
fmt.Println(p.ExitStatus())
31+
// Output:
32+
// 0
33+
}
34+
35+
func ExampleFile() {
36+
script.File("testdata/hello.txt").Stdout()
37+
// Output:
38+
// hello world
39+
}
40+
41+
func ExampleFindFiles() {
42+
script.FindFiles("testdata/multiple_files_with_subdirectory").Stdout()
43+
// Output:
44+
// testdata/multiple_files_with_subdirectory/1.txt
45+
// testdata/multiple_files_with_subdirectory/2.txt
46+
// testdata/multiple_files_with_subdirectory/3.tar.zip
47+
// testdata/multiple_files_with_subdirectory/dir/.hidden
48+
// testdata/multiple_files_with_subdirectory/dir/1.txt
49+
// testdata/multiple_files_with_subdirectory/dir/2.txt
50+
}
51+
52+
func ExampleIfExists_true() {
53+
script.IfExists("./testdata/hello.txt").Echo("found it").Stdout()
54+
// Output:
55+
// found it
56+
}
57+
58+
func ExampleIfExists_false() {
59+
script.IfExists("doesntexist").Echo("found it").Stdout()
60+
// Output:
61+
//
62+
}
63+
64+
func ExampleListFiles() {
65+
script.ListFiles("testdata/multiple_files_with_subdirectory").Stdout()
66+
// Output:
67+
// testdata/multiple_files_with_subdirectory/1.txt
68+
// testdata/multiple_files_with_subdirectory/2.txt
69+
// testdata/multiple_files_with_subdirectory/3.tar.zip
70+
// testdata/multiple_files_with_subdirectory/dir
71+
}
72+
73+
func ExamplePipe_Basename() {
74+
input := []string{
75+
"",
76+
"/",
77+
"/root",
78+
"/tmp/example.php",
79+
"/var/tmp/",
80+
"./src/filters",
81+
"C:/Program Files",
82+
}
83+
script.Slice(input).Basename().Stdout()
84+
// Output:
85+
// .
86+
// /
87+
// root
88+
// example.php
89+
// tmp
90+
// filters
91+
// Program Files
92+
}
93+
94+
func ExamplePipe_Bytes() {
95+
data, err := script.Echo("hello").Bytes()
96+
if err != nil {
97+
panic(err)
98+
}
99+
fmt.Println(data)
100+
// Output:
101+
// [104 101 108 108 111]
102+
}
103+
104+
func ExamplePipe_Column() {
105+
input := []string{
106+
"PID TT STAT TIME COMMAND",
107+
" 1 ?? Ss 873:17.62 /sbin/launchd",
108+
" 50 ?? Ss 13:18.13 /usr/libexec/UserEventAgent (System)",
109+
" 51 ?? Ss 22:56.75 /usr/sbin/syslogd",
110+
}
111+
script.Slice(input).Column(1).Stdout()
112+
// Output:
113+
// PID
114+
// 1
115+
// 50
116+
// 51
117+
}
118+
119+
func ExamplePipe_Concat() {
120+
input := []string{
121+
"testdata/test.txt",
122+
"testdata/doesntexist.txt",
123+
"testdata/hello.txt",
124+
}
125+
script.Slice(input).Concat().Stdout()
126+
// Output:
127+
// This is the first line in the file.
128+
// Hello, world.
129+
// This is another line in the file.
130+
// hello world
131+
}
132+
133+
func ExamplePipe_CountLines() {
134+
n, err := script.Echo("a\nb\nc\n").CountLines()
135+
if err != nil {
136+
panic(err)
137+
}
138+
fmt.Println(n)
139+
// Output:
140+
// 3
141+
}
142+
143+
func ExamplePipe_Dirname() {
144+
input := []string{
145+
"",
146+
"/",
147+
"/root",
148+
"/tmp/example.php",
149+
"/var/tmp/",
150+
"./src/filters",
151+
"C:/Program Files",
152+
}
153+
script.Slice(input).Dirname().Stdout()
154+
// Output:
155+
// .
156+
// /
157+
// /
158+
// /tmp
159+
// /var
160+
// ./src
161+
// C:
162+
}
163+
164+
func ExamplePipe_EachLine() {
165+
script.File("testdata/test.txt").EachLine(func(line string, out *strings.Builder) {
166+
out.WriteString("> " + line + "\n")
167+
}).Stdout()
168+
// Output:
169+
// > This is the first line in the file.
170+
// > Hello, world.
171+
// > This is another line in the file.
172+
}
173+
174+
func ExamplePipe_Echo() {
175+
script.NewPipe().Echo("Hello, world!").Stdout()
176+
// Output:
177+
// Hello, world!
178+
}
179+
180+
func ExamplePipe_Exec() {
181+
script.Echo("Hello, world!").Exec("tr a-z A-Z").Stdout()
182+
// Output:
183+
// HELLO, WORLD!
184+
}
185+
186+
func ExamplePipe_ExecForEach() {
187+
script.Echo("a\nb\nc\n").ExecForEach("echo {{.}}").Stdout()
188+
// Output:
189+
// a
190+
// b
191+
// c
192+
}
193+
194+
func ExamplePipe_ExitStatus() {
195+
p := script.Exec("echo")
196+
fmt.Println(p.ExitStatus())
197+
// Output:
198+
// 0
199+
}
200+
201+
func ExamplePipe_First() {
202+
script.Echo("a\nb\nc\n").First(2).Stdout()
203+
// Output:
204+
// a
205+
// b
206+
}
207+
208+
func ExamplePipe_Freq() {
209+
script.File("testdata/freq.input.txt").Freq().Stdout()
210+
// Output:
211+
// 10 apple
212+
// 4 banana
213+
// 4 orange
214+
// 1 kumquat
215+
}
216+
217+
func ExamplePipe_Join() {
218+
script.Echo("hello\nworld\n").Join().Stdout()
219+
// Output:
220+
// hello world
221+
}
222+
223+
func ExamplePipe_Last() {
224+
script.Echo("a\nb\nc\n").Last(2).Stdout()
225+
// Output:
226+
// b
227+
// c
228+
}
229+
230+
func ExamplePipe_Match() {
231+
script.Echo("a\nb\nc\n").Match("b").Stdout()
232+
// Output:
233+
// b
234+
}
235+
236+
func ExamplePipe_MatchRegexp() {
237+
re := regexp.MustCompile("w.*d")
238+
script.Echo("hello\nworld\n").MatchRegexp(re).Stdout()
239+
// Output:
240+
// world
241+
}
242+
243+
func ExamplePipe_Read() {
244+
buf := make([]byte, 12)
245+
n, err := script.Echo("hello world\n").Read(buf)
246+
if err != nil {
247+
panic(err)
248+
}
249+
fmt.Println(n)
250+
// Output:
251+
// 12
252+
}
253+
254+
func ExamplePipe_Reject() {
255+
script.Echo("a\nb\nc\n").Reject("b").Stdout()
256+
// Output:
257+
// a
258+
// c
259+
}
260+
261+
func ExamplePipe_RejectRegexp() {
262+
re := regexp.MustCompile("w.*d")
263+
script.Echo("hello\nworld\n").RejectRegexp(re).Stdout()
264+
// Output:
265+
// hello
266+
}
267+
268+
func ExamplePipe_Replace() {
269+
script.Echo("a\nb\nc\n").Replace("b", "replacement").Stdout()
270+
// Output:
271+
// a
272+
// replacement
273+
// c
274+
}
275+
276+
func ExamplePipe_ReplaceRegexp() {
277+
re := regexp.MustCompile("w.*d")
278+
script.Echo("hello\nworld\n").ReplaceRegexp(re, "replacement").Stdout()
279+
// Output:
280+
// hello
281+
// replacement
282+
}
283+
284+
func ExamplePipe_SHA256Sum() {
285+
sum, err := script.Echo("hello world").SHA256Sum()
286+
if err != nil {
287+
panic(err)
288+
}
289+
fmt.Println(sum)
290+
// Output:
291+
// b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9
292+
}
293+
294+
func ExamplePipe_SHA256Sums() {
295+
script.Echo("testdata/test.txt").SHA256Sums().Stdout()
296+
// Output:
297+
// a562c9c95e2ff3403e7ffcd8508c6b54d47d5f251387758d3e63dbaaa8296341
298+
}
299+
300+
func ExamplePipe_Slice() {
301+
s, err := script.Echo("a\nb\nc\n").Slice()
302+
if err != nil {
303+
panic(err)
304+
}
305+
fmt.Println(s)
306+
// Output:
307+
// [a b c]
308+
}
309+
310+
func ExamplePipe_Stdout() {
311+
n, err := script.Echo("a\nb\nc\n").Stdout()
312+
if err != nil {
313+
panic(err)
314+
}
315+
fmt.Println(n)
316+
// Output:
317+
// a
318+
// b
319+
// c
320+
// 6
321+
}
322+
323+
func ExamplePipe_String() {
324+
s, err := script.Echo("hello\nworld").String()
325+
if err != nil {
326+
panic(err)
327+
}
328+
fmt.Println(s)
329+
// Output:
330+
// hello
331+
// world
332+
}
333+
334+
func ExampleSlice() {
335+
input := []string{"1", "2", "3"}
336+
script.Slice(input).Stdout()
337+
// Output:
338+
// 1
339+
// 2
340+
// 3
341+
}

0 commit comments

Comments
 (0)