feat: tutorial on how to write the torsf experiment (#390)
Original tracking issue for Sprint 41: https://github.com/ooni/probe/issues/1507 Follow-up work in Sprint 42 tracked by: https://github.com/ooni/probe/issues/1689
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
// Command generator generates or re-generates the tutorial chapters. You
|
||||
// should run this command like `go run ./generator`.
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// writeString writes a string on the given writer. If there
|
||||
// is a write error, this function will call log.Fatal.
|
||||
func writeString(w io.Writer, s string) {
|
||||
if _, err := io.WriteString(w, s); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// gen1 generates a single file within a chapter.
|
||||
func gen1(destfile io.Writer, filepath string) {
|
||||
srcfile, err := os.Open(filepath)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer srcfile.Close()
|
||||
scanner := bufio.NewScanner(srcfile)
|
||||
var started bool
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
trimmed := strings.Trim(line, " \t\r\n")
|
||||
if trimmed == "// -=-=- StopHere -=-=-" {
|
||||
started = false
|
||||
continue
|
||||
}
|
||||
if trimmed == "// -=-=- StartHere -=-=-" {
|
||||
started = true
|
||||
continue
|
||||
}
|
||||
if !started {
|
||||
continue
|
||||
}
|
||||
if strings.HasPrefix(trimmed, "//") {
|
||||
if strings.HasPrefix(trimmed, "// ") {
|
||||
trimmed = trimmed[3:]
|
||||
} else {
|
||||
trimmed = trimmed[2:]
|
||||
}
|
||||
writeString(destfile, trimmed+"\n")
|
||||
continue
|
||||
}
|
||||
writeString(destfile, line+"\n")
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// gen generates or re-generates a chapter. The dirpath argument
|
||||
// is the path to the directory that contains a chapter. The files
|
||||
// arguments contains the source file names to process. We will process
|
||||
// files using the specified order. Note that files names are not
|
||||
// paths, just file names, e.g.,
|
||||
//
|
||||
// gen("./experiment/torsf/chapter01", "main.go")
|
||||
func gen(dirpath string, files ...string) {
|
||||
readme := path.Join(dirpath, "README.md")
|
||||
destfile, err := os.Create(path.Join(readme))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer func() {
|
||||
if err := destfile.Close(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}()
|
||||
for _, file := range files {
|
||||
gen1(destfile, path.Join(dirpath, file))
|
||||
}
|
||||
}
|
||||
|
||||
// gentorsf generates the torsf chapters.
|
||||
func gentorsf() {
|
||||
prefix := path.Join(".", "experiment", "torsf")
|
||||
gen(path.Join(prefix, "chapter01"), "main.go")
|
||||
gen(path.Join(prefix, "chapter02"), "main.go", "torsf.go")
|
||||
gen(path.Join(prefix, "chapter03"), "torsf.go")
|
||||
gen(path.Join(prefix, "chapter04"), "torsf.go")
|
||||
}
|
||||
|
||||
func main() {
|
||||
gentorsf()
|
||||
}
|
||||
Reference in New Issue
Block a user