ooni-probe-cli/internal/tutorial/generator/main.go
Simone Basso 9ef4d9df7d
doc: add tutorial on how to use netxlite (#519)
The main tutorial will be the one at https://github.com/ooni/probe-cli/pull/506, but
it's useful to also document the primitives used by measurex.

So, here's the companion tutorial, which explains how to use the
features in netxlite to perform measurements.

This work is part of https://github.com/ooni/ooni.org/issues/361.
2021-09-28 18:15:38 +02:00

109 lines
2.8 KiB
Go

// 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")
}
// gennetxlite generates the netxlite chapters.
func gennetxlite() {
prefix := path.Join(".", "netxlite")
gen(path.Join(prefix, "chapter01"), "main.go")
gen(path.Join(prefix, "chapter02"), "main.go")
gen(path.Join(prefix, "chapter03"), "main.go")
gen(path.Join(prefix, "chapter04"), "main.go")
gen(path.Join(prefix, "chapter05"), "main.go")
gen(path.Join(prefix, "chapter06"), "main.go")
gen(path.Join(prefix, "chapter07"), "main.go")
gen(path.Join(prefix, "chapter08"), "main.go")
}
func main() {
gentorsf()
gennetxlite()
}