• Stars
    star
    980
  • Rank 44,824 (Top 1.0 %)
  • Language
    Go
  • License
    MIT License
  • Created almost 9 years ago
  • Updated 5 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Takes an input http.FileSystem (likely at go generate time) and generates Go code that statically implements it.

vfsgen

Go Reference

Package vfsgen takes an http.FileSystem (likely at go generate time) and generates Go code that statically implements the provided http.FileSystem.

Features:

  • Efficient generated code without unneccessary overhead.

  • Uses gzip compression internally (selectively, only for files that compress well).

  • Enables direct access to internal gzip compressed bytes via an optional interface.

  • Outputs gofmted Go code.

Installation

go get github.com/shurcooL/vfsgen

Usage

Package vfsgen is a Go code generator library. It has a Generate function that takes an input filesystem (as a http.FileSystem type), and generates a Go code file that statically implements the contents of the input filesystem.

For example, we can use http.Dir as a http.FileSystem implementation that uses the contents of the /path/to/assets directory:

var fs http.FileSystem = http.Dir("/path/to/assets")

Now, when you execute the following code:

err := vfsgen.Generate(fs, vfsgen.Options{})
if err != nil {
	log.Fatalln(err)
}

An assets_vfsdata.go file will be generated in the current directory:

// Code generated by vfsgen; DO NOT EDIT.

package main

import ...

// assets statically implements the virtual filesystem provided to vfsgen.Generate.
var assets http.FileSystem = ...

Then, in your program, you can use assets as any other http.FileSystem, for example:

file, err := assets.Open("/some/file.txt")
if err != nil {
	return err
}
defer file.Close()
http.Handle("/assets/", http.FileServer(assets))

vfsgen can be more useful when combined with build tags and go generate directives. This is described below.

go generate Usage

vfsgen is great to use with go generate directives. The code invoking vfsgen.Generate can go in an assets_generate.go file, which can then be invoked via "//go:generate go run assets_generate.go". The input virtual filesystem can read directly from disk, or it can be more involved.

By using build tags, you can create a development mode where assets are loaded directly from disk via http.Dir, but then statically implemented for final releases.

For example, suppose your source filesystem is defined in a package with import path "example.com/project/data" as:

//go:build dev

package data

import "net/http"

// Assets contains project assets.
var Assets http.FileSystem = http.Dir("assets")

When built with the "dev" build tag, accessing data.Assets will read from disk directly via http.Dir.

A generate helper file assets_generate.go can be invoked via "//go:generate go run -tags=dev assets_generate.go" directive:

//go:build ignore

package main

import (
	"log"

	"example.com/project/data"
	"github.com/shurcooL/vfsgen"
)

func main() {
	err := vfsgen.Generate(data.Assets, vfsgen.Options{
		PackageName:  "data",
		BuildTags:    "!dev",
		VariableName: "Assets",
	})
	if err != nil {
		log.Fatalln(err)
	}
}

Note that "dev" build tag is used to access the source filesystem, and the output file will contain "!dev" build tag. That way, the statically implemented version will be used during normal builds and go get, when custom builds tags are not specified.

vfsgendev Usage

vfsgendev is a binary that can be used to replace the need for the assets_generate.go file.

Make sure it's installed and available in your PATH.

go get -u github.com/shurcooL/vfsgen/cmd/vfsgendev

Then the "//go:generate go run -tags=dev assets_generate.go" directive can be replaced with:

//go:generate vfsgendev -source="example.com/project/data".Assets

vfsgendev accesses the source variable using "dev" build tag, and generates an output file with "!dev" build tag.

Additional Embedded Information

All compressed files implement httpgzip.GzipByter interface for efficient direct access to the internal compressed bytes:

// GzipByter is implemented by compressed files for
// efficient direct access to the internal compressed bytes.
type GzipByter interface {
	// GzipBytes returns gzip compressed contents of the file.
	GzipBytes() []byte
}

Files that have been determined to not be worth gzip compressing (their compressed size is larger than original) implement httpgzip.NotWorthGzipCompressing interface:

// NotWorthGzipCompressing is implemented by files that were determined
// not to be worth gzip compressing (the file size did not decrease as a result).
type NotWorthGzipCompressing interface {
	// NotWorthGzipCompressing is a noop. It's implemented in order to indicate
	// the file is not worth gzip compressing.
	NotWorthGzipCompressing()
}

Comparison

vfsgen aims to be conceptually simple to use. The http.FileSystem abstraction is central to vfsgen. It's used as both input for code generation, and as output in the generated code.

That enables great flexibility through orthogonality, since helpers and wrappers can operate on http.FileSystem without knowing about vfsgen. If you want, you can perform pre-processing, minifying assets, merging folders, filtering out files and otherwise modifying input via generic http.FileSystem middleware.

It avoids unneccessary overhead by merging what was previously done with two distinct packages into a single package.

It strives to be the best in its class in terms of code quality and efficiency of generated code. However, if your use goals are different, there are other similar packages that may fit your needs better.

Alternatives

  • embed - Package embed provides access to files embedded in the running Go program.
  • go-bindata - Reads from disk, generates Go code that provides access to data via a custom API.
  • go-bindata-assetfs - Takes output of go-bindata and provides a wrapper that implements http.FileSystem interface (the same as what vfsgen outputs directly).
  • becky - Embeds assets as string literals in Go source.
  • statik - Embeds a directory of static files to be accessed via http.FileSystem interface (sounds very similar to vfsgen); implementation sourced from camlistore.
  • go.rice - Makes working with resources such as HTML, JS, CSS, images and templates very easy.
  • esc - Embeds files into Go programs and provides http.FileSystem interfaces to them.
  • staticfiles - Allows you to embed a directory of files into your Go binary.
  • togo - Generates a Go source file with a []byte var containing the given file's contents.
  • fileb0x - Simple customizable tool to embed files in Go.
  • embedfiles - Simple tool for embedding files in Go code as a map.
  • packr - Simple solution for bundling static assets inside of Go binaries.
  • rsrc - Tool for embedding .ico & manifest resources in Go programs for Windows.

Attribution

This package was originally based on the excellent work by @jteeuwen on go-bindata and @elazarl on go-bindata-assetfs.

Directories

Path Synopsis
cmd/vfsgendev vfsgendev is a convenience tool for using vfsgen in a common development configuration.

License

More Repositories

1

githubv4

Package githubv4 is a client library for accessing GitHub GraphQL API v4 (https://docs.github.com/en/graphql).
Go
1,081
star
2

Go-Package-Store

An app that displays updates for the Go packages in your GOPATH.
Go
898
star
3

markdownfmt

Like gofmt, but for Markdown.
Go
786
star
4

graphql

Package graphql provides a GraphQL client implementation.
Go
687
star
5

goexec

A command line tool to execute Go functions.
Go
361
star
6

gostatus

A command line tool that shows the status of Go repositories.
Go
242
star
7

github_flavored_markdown

GitHub Flavored Markdown renderer with fenced code block highlighting, clickable header anchor links.
Go
156
star
8

binstale

binstale tells you whether the binaries in your GOPATH/bin are stale or up to date.
Go
145
star
9

go

Common Go code.
Go
125
star
10

home

home is Dmitri Shuralyov's personal website.
Go
75
star
11

httpfs

Collection of Go packages for working with the http.FileSystem interface.
Go
60
star
12

Hover

A work-in-progress source port of Hover.
C++
58
star
13

eX0

Unfinished multiplayer tactical 2D shooter indie game.
C++
49
star
14

git-branches

git-branches prints the commit behind/ahead counts for branches.
Go
41
star
15

play

Short experimental programs for playing with and learning new things. No importable Go packages here.
JavaScript
38
star
16

gtdo

The source for gotools.org.
Go
36
star
17

tictactoe

Package tictactoe defines the game of tic-tac-toe.
Go
31
star
18

sanitized_anchor_name

Package sanitized_anchor_name provides a func to create sanitized anchor names.
Go
27
star
19

httpgzip

Package httpgzip provides net/http-like primitives that use gzip compression when serving HTTP requests.
Go
24
star
20

issuesapp

Package issuesapp is a web frontend for an issues service.
Go
23
star
21

godecl

A godecl experiment. Like cdecl, but for Go.
Go
20
star
22

cmd

Various small command-line utilities.
Go
18
star
23

frontend

Common frontend code.
HTML
13
star
24

notifications

Package notifications provides a notifications service definition.
Go
11
star
25

issues

Package issues provides an issues service definition.
Go
11
star
26

resume

resume is Dmitri Shuralyov's rΓ©sumΓ©.
Go
9
star
27

highlight_go

Syntax highlighter for Go, using go/scanner.
Go
8
star
28

octicon

Package octicon provides GitHub Octicons.
Go
8
star
29

webdavfs

Collection of Go packages for working with the webdav.FileSystem interface.
Go
8
star
30

notificationsapp

Package notificationsapp is a web frontend for a notifications service.
Go
8
star
31

events

Package events provides an events service definition.
Go
7
star
32

ivybrowser

A port of Rob Pike's ivy that runs in the browser.
Go
7
star
33

SLA

Service-level agreement for Go packages.
6
star
34

gofontwoff

Package gofontwoff provides the Go font family in Web Open Font Format.
CSS
5
star
35

vcsstate

Package vcsstate allows getting the state of version control system repositories.
Go
5
star
36

htmlg

Package for generating and rendering HTML nodes with context-aware escaping.
Go
5
star
37

reactions

Package reactions provides a reactions service definition.
HTML
3
star
38

users

Package users provides a users service definition.
Go
2
star
39

highlight_diff

Syntax highlighter for diff format, with inner diff highlighting.
Go
2
star
40

httperror

Package httperror provides common basic building blocks for custom HTTP frameworks.
Go
1
star