github.com/bayrepo/bayzr@v0.0.0-20240308125417-466ee1dfea8d/go-bindata/src/config.go (about) 1 // This work is subject to the CC0 1.0 Universal (CC0 1.0) Public Domain Dedication 2 // license. Its contents can be found at: 3 // http://creativecommons.org/publicdomain/zero/1.0/ 4 5 package bindata 6 7 import ( 8 "fmt" 9 "os" 10 "path/filepath" 11 "regexp" 12 ) 13 14 // InputConfig defines options on a asset directory to be convert. 15 type InputConfig struct { 16 // Path defines a directory containing asset files to be included 17 // in the generated output. 18 Path string 19 20 // Recusive defines whether subdirectories of Path 21 // should be recursively included in the conversion. 22 Recursive bool 23 } 24 25 // Config defines a set of options for the asset conversion. 26 type Config struct { 27 // Name of the package to use. Defaults to 'main'. 28 Package string 29 30 // Tags specify a set of optional build tags, which should be 31 // included in the generated output. The tags are appended to a 32 // `// +build` line in the beginning of the output file 33 // and must follow the build tags syntax specified by the go tool. 34 Tags string 35 36 // Input defines the directory path, containing all asset files as 37 // well as whether to recursively process assets in any sub directories. 38 Input []InputConfig 39 40 // Output defines the output file for the generated code. 41 // If left empty, this defaults to 'bindata.go' in the current 42 // working directory. 43 Output string 44 45 // Prefix defines a path prefix which should be stripped from all 46 // file names when generating the keys in the table of contents. 47 // For example, running without the `-prefix` flag, we get: 48 // 49 // $ go-bindata /path/to/templates 50 // go_bindata["/path/to/templates/foo.html"] = _path_to_templates_foo_html 51 // 52 // Running with the `-prefix` flag, we get: 53 // 54 // $ go-bindata -prefix "/path/to/" /path/to/templates/foo.html 55 // go_bindata["templates/foo.html"] = templates_foo_html 56 Prefix string 57 58 // NoMemCopy will alter the way the output file is generated. 59 // 60 // It will employ a hack that allows us to read the file data directly from 61 // the compiled program's `.rodata` section. This ensures that when we call 62 // call our generated function, we omit unnecessary mem copies. 63 // 64 // The downside of this, is that it requires dependencies on the `reflect` and 65 // `unsafe` packages. These may be restricted on platforms like AppEngine and 66 // thus prevent you from using this mode. 67 // 68 // Another disadvantage is that the byte slice we create, is strictly read-only. 69 // For most use-cases this is not a problem, but if you ever try to alter the 70 // returned byte slice, a runtime panic is thrown. Use this mode only on target 71 // platforms where memory constraints are an issue. 72 // 73 // The default behaviour is to use the old code generation method. This 74 // prevents the two previously mentioned issues, but will employ at least one 75 // extra memcopy and thus increase memory requirements. 76 // 77 // For instance, consider the following two examples: 78 // 79 // This would be the default mode, using an extra memcopy but gives a safe 80 // implementation without dependencies on `reflect` and `unsafe`: 81 // 82 // func myfile() []byte { 83 // return []byte{0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a} 84 // } 85 // 86 // Here is the same functionality, but uses the `.rodata` hack. 87 // The byte slice returned from this example can not be written to without 88 // generating a runtime error. 89 // 90 // var _myfile = "\x89\x50\x4e\x47\x0d\x0a\x1a" 91 // 92 // func myfile() []byte { 93 // var empty [0]byte 94 // sx := (*reflect.StringHeader)(unsafe.Pointer(&_myfile)) 95 // b := empty[:] 96 // bx := (*reflect.SliceHeader)(unsafe.Pointer(&b)) 97 // bx.Data = sx.Data 98 // bx.Len = len(_myfile) 99 // bx.Cap = bx.Len 100 // return b 101 // } 102 NoMemCopy bool 103 104 // NoCompress means the assets are /not/ GZIP compressed before being turned 105 // into Go code. The generated function will automatically unzip 106 // the file data when called. Defaults to false. 107 NoCompress bool 108 109 // Perform a debug build. This generates an asset file, which 110 // loads the asset contents directly from disk at their original 111 // location, instead of embedding the contents in the code. 112 // 113 // This is mostly useful if you anticipate that the assets are 114 // going to change during your development cycle. You will always 115 // want your code to access the latest version of the asset. 116 // Only in release mode, will the assets actually be embedded 117 // in the code. The default behaviour is Release mode. 118 Debug bool 119 120 // Perform a dev build, which is nearly identical to the debug option. The 121 // only difference is that instead of absolute file paths in generated code, 122 // it expects a variable, `rootDir`, to be set in the generated code's 123 // package (the author needs to do this manually), which it then prepends to 124 // an asset's name to construct the file path on disk. 125 // 126 // This is mainly so you can push the generated code file to a shared 127 // repository. 128 Dev bool 129 130 // When true, size, mode and modtime are not preserved from files 131 NoMetadata bool 132 // When nonzero, use this as mode for all files. 133 Mode uint 134 // When nonzero, use this as unix timestamp for all files. 135 ModTime int64 136 137 // Ignores any filenames matching the regex pattern specified, e.g. 138 // path/to/file.ext will ignore only that file, or \\.gitignore 139 // will match any .gitignore file. 140 // 141 // This parameter can be provided multiple times. 142 Ignore []*regexp.Regexp 143 } 144 145 // NewConfig returns a default configuration struct. 146 func NewConfig() *Config { 147 c := new(Config) 148 c.Package = "main" 149 c.NoMemCopy = false 150 c.NoCompress = false 151 c.Debug = false 152 c.Output = "./bindata.go" 153 c.Ignore = make([]*regexp.Regexp, 0) 154 return c 155 } 156 157 // validate ensures the config has sane values. 158 // Part of which means checking if certain file/directory paths exist. 159 func (c *Config) validate() error { 160 if len(c.Package) == 0 { 161 return fmt.Errorf("Missing package name") 162 } 163 164 for _, input := range c.Input { 165 _, err := os.Lstat(input.Path) 166 if err != nil { 167 return fmt.Errorf("Failed to stat input path '%s': %v", input.Path, err) 168 } 169 } 170 171 if len(c.Output) == 0 { 172 cwd, err := os.Getwd() 173 if err != nil { 174 return fmt.Errorf("Unable to determine current working directory.") 175 } 176 177 c.Output = filepath.Join(cwd, "bindata.go") 178 } 179 180 stat, err := os.Lstat(c.Output) 181 if err != nil { 182 if !os.IsNotExist(err) { 183 return fmt.Errorf("Output path: %v", err) 184 } 185 186 // File does not exist. This is fine, just make 187 // sure the directory it is to be in exists. 188 dir, _ := filepath.Split(c.Output) 189 if dir != "" { 190 err = os.MkdirAll(dir, 0744) 191 192 if err != nil { 193 return fmt.Errorf("Create output directory: %v", err) 194 } 195 } 196 } 197 198 if stat != nil && stat.IsDir() { 199 return fmt.Errorf("Output path is a directory.") 200 } 201 202 return nil 203 }