Skip to content
/ statics Public

The purpose of Statics is to make it dead simple to embed external files into a Go binary. By default, it takes all of the files in your ./include folder and embeds them as byte arrays in map called files in a separate .go file called files.go.

Notifications You must be signed in to change notification settings

efskap/statics

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

25 Commits
 
 
 
 

Repository files navigation

Statics
The purpose of Statics is to make it dead simple to embed external files into a Go binary.
By default, it takes all of the files in your ./include folder and embeds them as byte arrays in map called files in a separate .go file called files.go.

Install
go get github.com/jerblack/statics

This will create a file called statics[.exe] in GOPATH/bin.

Usage
Statics is intended to do the right thing by default so you can just run statics and assuming you have a folder called ./include with files inside, a new ./files.go will be generated (or overwritten).
However, the default behavior can be changed. Run statics -h to see the available options.
My build script usually starts with something like statics && go build.

-h Help Output

Statics is a Go tool intended to let you to easily embed static files into your compiled Go binary, 
so all of your resource files can be read directly from the binary without needing to write them to disk first.

By default, statics takes all of the files in your "./include" folder and embeds them as byte arrays 
in a map called "files" in a separate .go file called "files.go" that is part of the "main" package. 
All of this can be customized.

The following items are customizable using the switches described below:

- Output file name
- Package name
- Name of the file map
- Set one or more folders with files to import
- Store the file names with their path hierarchy preserved, 
   or flatten the path and just store the file names.
- Exclude files or subfolders from the chosen import folders by path or filename. 
- Include only specific files from the chosen import folders, 
    which will make Statics include only the specified files.
- Use wildcards for both the exclude and include folder list.
- Set build tags to enable OS and architecture specific compilation.
- Set aliases for file names so you can store the file in the file map with a different name than the actual file name.
- For all arguments that accept multiple files or folders, you can either use a pipe-separated list 
   surrounded by quotes or just set the argument multiple times, once for each file.
      -arg "item1 | item2 | item3"   -or-   -arg item1 -arg item2 -arg item3 

Be sure to re-run 'statics' after adding or modifying any files in your './include' folder.  

Usage:

  statics [-p=./include] [-out=files.go] [-pkg=main] [-v]
   [-map=files] [-bt="// +build !windows,!darwin"] [-a "filename | alias"] [-f]
   [-x="file1 | file[1-4].* | include/img?/*png | file3"] [-i="file1 | file[1-4].* | include/img?/*png | file3"] 

Flags:  
-p      Import path[s]  
        Folder path or paths with files to import relative to current working directory.  
        Specify multiple import paths with either a pipe-separated list   
        or by specifying this argument multiple times.  
            -p "dir1 | dir2 | dir3"    -or-    -p dir1 -p dir2 -p dir3  
        Files stored in map will use path starting with specified import folder.  
        (default "-p ./include")  
-o      Output go file. If go extension is not specified, it will be added.  
        (default "-o files.go")  
-pkg    package name of the go file 
        (default "-pkg main")
-map    Name of the generated files map 
        (default "-map files")
-f      Flatten path, stripping folders and just using base file names as keys in the file map.
        File will be stored as files["filename"] instead of the default files["importfolder/dirname/filename"].
-a	    Store file in the file map with a name other than it's original filename.
        Call this argument multiple times to set multiple aliases.
        The parameter should look like "original name | alias"
        Aliased files will be stored in the same folder as the original file unless alias is a path
           -a "filename1 | alias1" 
            ./importfolder/filename1 --> files["importfolder/alias1"] 
           -a "filename1 | dir/alias1" 	
            ./importfolder/filename1 --> files["dir/alias1"] 
           -f -a "filename1 | alias1" 
            ./importfolder/filename1 --> files["alias1"]
           Explicitly setting an alias with a path ignores flatten, 
            allowing you to flatten everything but the aliased file.
           -f -a "filename1 | dir/alias1"
            ./importfolder/filename1 --> files["dir/alias1"] 
-bt     Specify build tags to put at the top of the .go file.
        Can be any of the following:
            Single line
                -bt "// +build !windows,!darwin"
            Two lines joined with \n newline character
                -bt "// +build !windows,!darwin\n// +build amd64"
            Pipe-separated list
                -bt "// +build !windows,!darwin | // +build amd64"
            Same argument called multiple times
                -bt "// +build !windows,!darwin" -bt "// +build amd64"
        Go requires an additional line break after your build tags, which will be inserted automatically.
        No validation is performed and anything you specify here will be inserted at the top of the file.
-x      Specify files or folders in the import paths to exclude. 
        Can be any of the following:
            File name
                -x file1
            Path to file name beginning from import folder
                -x "importfolder/dir1/file1"
            Pipe-separated list of files or paths in import folders to exclude.
                -x "file1 | file[1-4].* | include/img?/*png | file3"
            You can also specify this argument multiple times to exclude multiple files.
                -x file1 -x "file[1-4].*" -x "include/img?/*png" -x file3
        Specifying a filename without the path will match that file anywhere in the import folder hierarchy.
        Wildcard expressions are supported. Use wildcards to exclude a whole folder: "include/folder/*"
-i      Specify files in the import paths to include. If set, only the specified files will be included.
        Can be any of the following:
            File name
                -i file1
            Path to file name beginning from import folder
                -i "importfolder/dir1/file1"
            Pipe-separated list of files or paths in import folders to exclude.
                -i "file1 | file[1-4].* | include/img?/*png | file3"
            You can also specify this argument multiple times to exclude multiple files.
                -i file1 -i "file[1-4].*" -i "include/img?/*png" -i file3
        Specifying a filename without the path will match that file anywhere in the import folder hierarchy.
        Wildcard expressions are supported. Use wildcards to include a whole folder: "include/folder/*"
-v      Verbose

Wildcards:
-x and -i both support wildcard expressions. 
Filenames with wilcards will be matched in any subfolder in the include path.
If specifying a path with wildcards, the wildcards will not include anything beyond the current file or folder name.
 The entire path starting from the import folder must be accounted for.
    To include all the pngs in the import folder and it's subfolders:
        -i "*png"
    To include all the pngs in the subfolders ending with a number from 1 to 3 in an import folder called include:
        -i "include/img[1-3]/*png"

Matching follows the pattern defined in https://golang.org/pkg/path/filepath/#Match
pattern:
        { term }
term:
        '*'         matches any sequence of non-Separator characters
        '?'         matches any single non-Separator character
        '[' [ '^' ] { character-range } ']'
                    character class (must be non-empty)
        c           matches character c (c != '*', '?', '\\', '[')
        '\\' c      matches character c

character-range:
        c           matches character c (c != '\\', '-', ']')
        '\\' c      matches character c
        lo '-' hi   matches character c for lo <= c <= hi

Example
A typical generated files.go will look something like this.

package main

var files = map[string][]byte{

	"index.htm": []byte{108, 101, 116, ...},

	"favicon.png": []byte{137, 80, 78, ...},

	"code.js": []byte{60, 33, 68, 79, ...},

	"style.css": []byte{104, 116, 109, ...},
}

The example below shows how it can be used.

func main() {
    http.HandleFunc("/", serveFiles)
	log.Fatal(http.ListenAndServe(":80", nil))
}

func serveFiles(w http.ResponseWriter, r *http.Request) {
	p := r.URL.Path
	var fName string
	switch {
	case p == "/":
		fName = "index.html"
	case p == "/favicon.ico":
		fName = "favicon.png"
	case strings.HasPrefix(p, "/static"):
		fName = strings.TrimPrefix(p, "/static/")
	default:
		http.Error(w, http.StatusText(http.StatusNotFound),
			http.StatusNotFound)
		return
	}
	f, ok := files[fName]  // <- the files map is what is provided by statics
	if !ok {
		http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
		return
	}
	ext := filepath.Ext(fName)
	mimeType := mime.TypeByExtension(ext)
	w.Header().Set("Content-Type", mimeType)
	_, err := w.Write(f)
	if err != nil {
		fmt.Println(err.Error())
	}
}

About

The purpose of Statics is to make it dead simple to embed external files into a Go binary. By default, it takes all of the files in your ./include folder and embeds them as byte arrays in map called files in a separate .go file called files.go.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •  

Languages