diff --git a/examples.txt b/examples.txt index 1c62e01..5c22a2a 100644 --- a/examples.txt +++ b/examples.txt @@ -65,6 +65,7 @@ Line Filters File Paths Directories Temporary Files and Directories +Embed Directive Testing and Benchmarking Command-Line Arguments Command-Line Flags diff --git a/examples/embed-directive/embed-directive.go b/examples/embed-directive/embed-directive.go new file mode 100644 index 0000000..d7b1c13 --- /dev/null +++ b/examples/embed-directive/embed-directive.go @@ -0,0 +1,45 @@ +// `//go:embed` is a compiler directive that allows programs to include arbitrary +// files/folders in the binary. Read more about go directive +// [here](https://dave.cheney.net/2018/01/08/gos-hidden-pragmas). +package main + +// If no exported identifiers is directly used from `embed` package, +// you can add an underscore `_` before the package name. In this example, we simply +// import it as we need to use the `embed.FS` type from the package. +import ( + //_ "embed" + "embed" +) + +// Since one file is defined after the directive, the compiler will only include +// this single file, followed by variable `single_file_string` to access as `string` type. +//go:embed example_folder/single_file.txt +var single_file_string string + +// Here is a similar example but include single file as `[]byte`. +//go:embed example_folder/single_file.txt +var single_file_byte []byte + +// We can also embed multiple files or even folders with wildcard. +//go:embed example_folder/single_file.txt +//go:embed example_folder/*.hash +var folder_FS embed.FS + +func main() { + + // Print out content of `example_single_file.txt` as `string`. + print(single_file_string) + + // Now handle `[]byte`. + print(string(single_file_byte)) + + // Retrieve file(s) matching `*.hash` pattern by reading from variable `folder_FS` first, + // then print out. + hash_file1 := "example_folder/multi_file1.hash" + hash_file2 := "example_folder/multi_file2.hash" + hash_content1, _ := folder_FS.ReadFile(hash_file1) + hash_content2, _ := folder_FS.ReadFile(hash_file2) + print(string(hash_content1)) + print(string(hash_content2)) + +} diff --git a/examples/embed-directive/embed-directive.hash b/examples/embed-directive/embed-directive.hash new file mode 100644 index 0000000..bf62e8b --- /dev/null +++ b/examples/embed-directive/embed-directive.hash @@ -0,0 +1,2 @@ +e996755d889f01c99c353616fb2bdeac6c3be6e6 +-EXJc75EbN- diff --git a/examples/embed-directive/embed-directive.sh b/examples/embed-directive/embed-directive.sh new file mode 100644 index 0000000..f6937db --- /dev/null +++ b/examples/embed-directive/embed-directive.sh @@ -0,0 +1,14 @@ +# Use these commands to run the example. +# (Note: due to limitation on go playground, +# this example can only be run on your local machine.) +$ mkdir -p example_folder +$ echo "hello go" > example_folder/single_file.txt +$ echo "123" > example_folder/multi_file1.hash +$ echo "456" > example_folder/multi_file2.hash + +$ go run embed-directive.go +hello go +hello go +123 +456 + diff --git a/examples/embed-directive/example_folder/multi_file1.hash b/examples/embed-directive/example_folder/multi_file1.hash new file mode 100644 index 0000000..190a180 --- /dev/null +++ b/examples/embed-directive/example_folder/multi_file1.hash @@ -0,0 +1 @@ +123 diff --git a/examples/embed-directive/example_folder/multi_file2.hash b/examples/embed-directive/example_folder/multi_file2.hash new file mode 100644 index 0000000..8d38505 --- /dev/null +++ b/examples/embed-directive/example_folder/multi_file2.hash @@ -0,0 +1 @@ +456 diff --git a/examples/embed-directive/example_folder/single_file.txt b/examples/embed-directive/example_folder/single_file.txt new file mode 100644 index 0000000..606d597 --- /dev/null +++ b/examples/embed-directive/example_folder/single_file.txt @@ -0,0 +1 @@ +hello go diff --git a/public/embed-directive b/public/embed-directive new file mode 100644 index 0000000..35536bb --- /dev/null +++ b/public/embed-directive @@ -0,0 +1,226 @@ + + + + + Go by Example: Embed Directive + + + + +
+

Go by Example: Embed Directive

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

//go:embed is a compiler directive that allows programs to include arbitrary +files/folders in the binary. Read more about go directive +here.

+ +
+ +
+package main
+
+
+

If no exported identifiers is directly used from embed package, +you can add an underscore _ before the package name. In this example, we simply +import it as we need to use the embed.FS type from the package.

+ +
+ +
+import (
+    //_ "embed"
+    "embed"
+)
+
+
+

Since one file is defined after the directive, the compiler will only include +this single file, followed by variable single_file_string to access as string type.

+ +
+ +
+//go:embed example_folder/single_file.txt
+var single_file_string string
+
+
+

Here is a similar example but include single file as []byte.

+ +
+ +
+//go:embed example_folder/single_file.txt
+var single_file_byte []byte
+
+
+

We can also embed multiple files or even folders with wildcard.

+ +
+ +
+//go:embed example_folder/single_file.txt
+//go:embed example_folder/*.hash
+var folder_FS embed.FS
+
+
+ + + +
func main() {
+
+
+

Print out content of example_single_file.txt as string.

+ +
+ +
+    print(single_file_string)
+
+
+

Now handle []byte.

+ +
+ +
+    print(string(single_file_byte))
+
+
+

Retrieve file(s) matching *.hash pattern by reading from variable folder_FS first, +then print out.

+ +
+ +
+    hash_file1 := "example_folder/multi_file1.hash"
+    hash_file2 := "example_folder/multi_file2.hash"
+    hash_content1, _ := folder_FS.ReadFile(hash_file1)
+    hash_content2, _ := folder_FS.ReadFile(hash_file2)
+    print(string(hash_content1))
+    print(string(hash_content2))
+
+
+ + + +
}
+
+
+ + + + + + + + + + + + + +
+

Use these commands to run the example. +(Note: due to limitation on go playground, +this example can only be run on your local machine.)

+ +
+ +
+$ mkdir -p example_folder
+$ echo "hello go" > example_folder/single_file.txt
+$ echo "123" > example_folder/multi_file1.hash
+$ echo "456" > example_folder/multi_file2.hash
+
+ + + +
$ go run embed-directive.go
+hello go
+hello go
+123
+456
+
+ + +

+ Next example: Testing and Benchmarking. +

+ + + + +
+ + + + diff --git a/public/index.html b/public/index.html index a0c2e15..83f47ea 100644 --- a/public/index.html +++ b/public/index.html @@ -161,6 +161,8 @@
  • Temporary Files and Directories
  • +
  • Embed Directive
  • +
  • Testing and Benchmarking
  • Command-Line Arguments
  • diff --git a/public/temporary-files-and-directories b/public/temporary-files-and-directories index 91ca3a6..2e8cd85 100644 --- a/public/temporary-files-and-directories +++ b/public/temporary-files-and-directories @@ -14,7 +14,7 @@ if (e.key == "ArrowRight") { - window.location.href = 'testing-and-benchmarking'; + window.location.href = 'embed-directive'; } } @@ -225,7 +225,7 @@ prefixing them with our temporary directory.

    - Next example: Testing and Benchmarking. + Next example: Embed Directive.

    diff --git a/public/testing-and-benchmarking b/public/testing-and-benchmarking index 975dbb2..84918d8 100644 --- a/public/testing-and-benchmarking +++ b/public/testing-and-benchmarking @@ -9,7 +9,7 @@ onkeydown = (e) => { if (e.key == "ArrowLeft") { - window.location.href = 'temporary-files-and-directories'; + window.location.href = 'embed-directive'; } diff --git a/tools/generate.go b/tools/generate.go index 7616c25..fdbe7a0 100644 --- a/tools/generate.go +++ b/tools/generate.go @@ -36,6 +36,11 @@ func check(err error) { } } +func isDir(path string) bool { + fileStat, _ := os.Stat(path) + return fileStat.IsDir() +} + func ensureDir(dir string) { err := os.MkdirAll(dir, 0755) check(err) @@ -275,14 +280,16 @@ func parseExamples() []*Example { example.Segs = make([][]*Seg, 0) sourcePaths := mustGlob("examples/" + exampleID + "/*") for _, sourcePath := range sourcePaths { - if strings.HasSuffix(sourcePath, ".hash") { - example.GoCodeHash, example.URLHash = parseHashFile(sourcePath) - } else { - sourceSegs, filecontents := parseAndRenderSegs(sourcePath) - if filecontents != "" { - example.GoCode = filecontents + if ! isDir(sourcePath) { + if strings.HasSuffix(sourcePath, ".hash") { + example.GoCodeHash, example.URLHash = parseHashFile(sourcePath) + } else { + sourceSegs, filecontents := parseAndRenderSegs(sourcePath) + if filecontents != "" { + example.GoCode = filecontents + } + example.Segs = append(example.Segs, sourceSegs) } - example.Segs = append(example.Segs, sourceSegs) } } newCodeHash := sha1Sum(example.GoCode) diff --git a/tools/measure.go b/tools/measure.go index 7c9d6be..8be80d7 100644 --- a/tools/measure.go +++ b/tools/measure.go @@ -21,6 +21,11 @@ func readLines(path string) []string { return strings.Split(string(srcBytes), "\n") } +func isDir(path string) bool { + fileStat, _ := os.Stat(path) + return fileStat.IsDir() +} + var commentPat = regexp.MustCompile("\\s*\\/\\/") func main() { @@ -29,15 +34,17 @@ func main() { foundLongFile := false for _, sourcePath := range sourcePaths { foundLongLine := false - lines := readLines(sourcePath) - for i, line := range lines { - // Convert tabs to spaces before measuring, so we get an accurate measure - // of how long the output will end up being. - line := strings.Replace(line, "\t", " ", -1) - if !foundLongLine && !commentPat.MatchString(line) && (utf8.RuneCountInString(line) > 58) { - fmt.Printf("measure: %s:%d\n", sourcePath, i+1) - foundLongLine = true - foundLongFile = true + if ! isDir(sourcePath) { + lines := readLines(sourcePath) + for i, line := range lines { + // Convert tabs to spaces before measuring, so we get an accurate measure + // of how long the output will end up being. + line := strings.Replace(line, "\t", " ", -1) + if !foundLongLine && !commentPat.MatchString(line) && (utf8.RuneCountInString(line) > 58) { + fmt.Printf("measure: %s:%d\n", sourcePath, i+1) + foundLongLine = true + foundLongFile = true + } } } }