Skip to content

Commit c8498c2

Browse files
committed
air -h will be document of air
1 parent 785da24 commit c8498c2

File tree

3 files changed

+82
-58
lines changed

3 files changed

+82
-58
lines changed

runner/config.go

+38-38
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ const (
2323

2424
// Config is the main configuration structure for Air.
2525
type Config struct {
26-
Root string `toml:"root"`
27-
TmpDir string `toml:"tmp_dir"`
26+
Root string `toml:"root" usage:"Working directory, . or absolute path, please note that the directories following must be under root"`
27+
TmpDir string `toml:"tmp_dir" usage:"Temporary directory for air"`
2828
TestDataDir string `toml:"testdata_dir"`
2929
Build cfgBuild `toml:"build"`
3030
Color cfgColor `toml:"color"`
@@ -35,29 +35,29 @@ type Config struct {
3535
}
3636

3737
type cfgBuild struct {
38-
PreCmd []string `toml:"pre_cmd"`
39-
Cmd string `toml:"cmd"`
40-
PostCmd []string `toml:"post_cmd"`
41-
Bin string `toml:"bin"`
42-
FullBin string `toml:"full_bin"`
43-
ArgsBin []string `toml:"args_bin"`
44-
Log string `toml:"log"`
45-
IncludeExt []string `toml:"include_ext"`
46-
ExcludeDir []string `toml:"exclude_dir"`
47-
IncludeDir []string `toml:"include_dir"`
48-
ExcludeFile []string `toml:"exclude_file"`
49-
IncludeFile []string `toml:"include_file"`
50-
ExcludeRegex []string `toml:"exclude_regex"`
51-
ExcludeUnchanged bool `toml:"exclude_unchanged"`
52-
FollowSymlink bool `toml:"follow_symlink"`
53-
Poll bool `toml:"poll"`
54-
PollInterval int `toml:"poll_interval"`
55-
Delay int `toml:"delay"`
56-
StopOnError bool `toml:"stop_on_error"`
57-
SendInterrupt bool `toml:"send_interrupt"`
58-
KillDelay time.Duration `toml:"kill_delay"`
59-
Rerun bool `toml:"rerun"`
60-
RerunDelay int `toml:"rerun_delay"`
38+
PreCmd []string `toml:"pre_cmd" usage:"Array of commands to run before each build"`
39+
Cmd string `toml:"cmd" usage:"Just plain old shell command. You could use 'make' as well"`
40+
PostCmd []string `toml:"post_cmd" usage:"Array of commands to run after ^C"`
41+
Bin string `toml:"bin" usage:"Binary file yields from 'cmd'"`
42+
FullBin string `toml:"full_bin" usage:"Customize binary, can setup environment variables when run your app"`
43+
ArgsBin []string `toml:"args_bin" usage:"Add additional arguments when running binary (bin/full_bin)."`
44+
Log string `toml:"log" usage:"This log file is placed in your tmp_dir"`
45+
IncludeExt []string `toml:"include_ext" usage:"Watch these filename extensions"`
46+
ExcludeDir []string `toml:"exclude_dir" usage:"Ignore these filename extensions or directories"`
47+
IncludeDir []string `toml:"include_dir" usage:"Watch these directories if you specified"`
48+
ExcludeFile []string `toml:"exclude_file" usage:"Exclude files"`
49+
IncludeFile []string `toml:"include_file" usage:"Watch these files"`
50+
ExcludeRegex []string `toml:"exclude_regex" usage:"Exclude specific regular expressions"`
51+
ExcludeUnchanged bool `toml:"exclude_unchanged" usage:"Exclude unchanged files"`
52+
FollowSymlink bool `toml:"follow_symlink" usage:"Follow symlink for directories"`
53+
Poll bool `toml:"poll" usage:"Poll files for changes instead of using fsnotify"`
54+
PollInterval int `toml:"poll_interval" usage:"Poll interval (defaults to the minimum interval of 500ms)"`
55+
Delay int `toml:"delay" usage:"It's not necessary to trigger build each time file changes if it's too frequent"`
56+
StopOnError bool `toml:"stop_on_error" usage:"Stop running old binary when build errors occur"`
57+
SendInterrupt bool `toml:"send_interrupt" usage:"Send Interrupt signal before killing process (windows does not support this feature)"`
58+
KillDelay time.Duration `toml:"kill_delay" usage:"Delay after sending Interrupt signal"`
59+
Rerun bool `toml:"rerun" usage:"Rerun binary or not"`
60+
RerunDelay int `toml:"rerun_delay" usage:"Delay after each execution"`
6161
regexCompiled []*regexp.Regexp
6262
}
6363

@@ -66,32 +66,32 @@ func (c *cfgBuild) RegexCompiled() ([]*regexp.Regexp, error) {
6666
}
6767

6868
type cfgLog struct {
69-
AddTime bool `toml:"time"`
70-
MainOnly bool `toml:"main_only"`
71-
Silent bool `toml:"silent"`
69+
AddTime bool `toml:"time" usage:"Show log time"`
70+
MainOnly bool `toml:"main_only" usage:"Only show main log (silences watcher, build, runner)"`
71+
Silent bool `toml:"silent" usage:"silence all logs produced by air"`
7272
}
7373

7474
type cfgColor struct {
75-
Main string `toml:"main"`
76-
Watcher string `toml:"watcher"`
77-
Build string `toml:"build"`
78-
Runner string `toml:"runner"`
75+
Main string `toml:"main" usage:"Customize main part's color. If no color found, use the raw app log"`
76+
Watcher string `toml:"watcher" usage:"Customize watcher part's color"`
77+
Build string `toml:"build" usage:"Customize build part's color"`
78+
Runner string `toml:"runner" usage:"Customize runner part's color"`
7979
App string `toml:"app"`
8080
}
8181

8282
type cfgMisc struct {
83-
CleanOnExit bool `toml:"clean_on_exit"`
83+
CleanOnExit bool `toml:"clean_on_exit" usage:"Delete tmp directory on exit"`
8484
}
8585

8686
type cfgScreen struct {
87-
ClearOnRebuild bool `toml:"clear_on_rebuild"`
88-
KeepScroll bool `toml:"keep_scroll"`
87+
ClearOnRebuild bool `toml:"clear_on_rebuild" usage:"Clear screen on rebuild"`
88+
KeepScroll bool `toml:"keep_scroll" usage:"Keep scroll position after rebuild"`
8989
}
9090

9191
type cfgProxy struct {
92-
Enabled bool `toml:"enabled"`
93-
ProxyPort int `toml:"proxy_port"`
94-
AppPort int `toml:"app_port"`
92+
Enabled bool `toml:"enabled" usage:"Enable live-reloading on the browser"`
93+
ProxyPort int `toml:"proxy_port" usage:"Port for proxy server"`
94+
AppPort int `toml:"app_port" usage:"Port for your app"`
9595
}
9696

9797
type sliceTransformer struct{}

runner/flag.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ const unsetDefault = "DEFAULT"
88

99
// ParseConfigFlag parse toml information for flag
1010
func ParseConfigFlag(f *flag.FlagSet) map[string]TomlInfo {
11-
c := Config{}
11+
c := defaultConfig()
1212
m := flatConfig(c)
1313
for k, v := range m {
14-
f.StringVar(v.Value, k, unsetDefault, "")
14+
f.StringVar(v.Value, k, v.fieldValue, v.usage)
1515
}
1616
return m
1717
}

runner/util.go

+42-18
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"crypto/sha256"
55
"encoding/hex"
66
"errors"
7+
"fmt"
78
"log"
89
"os"
910
"path/filepath"
@@ -315,9 +316,11 @@ func (a *checksumMap) updateFileChecksum(filename, newChecksum string) (ok bool)
315316

316317
// TomlInfo is a struct for toml config file
317318
type TomlInfo struct {
318-
fieldPath string
319-
field reflect.StructField
320-
Value *string
319+
fieldPath string
320+
field reflect.StructField
321+
Value *string
322+
fieldValue string
323+
usage string
321324
}
322325

323326
func setValue2Struct(v reflect.Value, fieldName string, value string) {
@@ -372,29 +375,50 @@ func setValue2Struct(v reflect.Value, fieldName string, value string) {
372375
func flatConfig(stut interface{}) map[string]TomlInfo {
373376
m := make(map[string]TomlInfo)
374377
t := reflect.TypeOf(stut)
375-
setTage2Map("", t, m, "")
378+
v := reflect.ValueOf(stut)
379+
setTage2Map("", t, v, m, "")
376380
return m
377381
}
378382

379-
func setTage2Map(root string, t reflect.Type, m map[string]TomlInfo, fieldPath string) {
383+
func getFieldValueString(fieldValue reflect.Value) string {
384+
switch fieldValue.Kind() {
385+
case reflect.Slice:
386+
sliceLen := fieldValue.Len()
387+
strSlice := make([]string, sliceLen)
388+
for j := 0; j < sliceLen; j++ {
389+
strSlice[j] = fmt.Sprintf("%v", fieldValue.Index(j).Interface())
390+
}
391+
return strings.Join(strSlice, ",")
392+
default:
393+
return fmt.Sprintf("%v", fieldValue.Interface())
394+
}
395+
}
396+
397+
func setTage2Map(root string, t reflect.Type, v reflect.Value, m map[string]TomlInfo, fieldPath string) {
380398
for i := 0; i < t.NumField(); i++ {
381399
field := t.Field(i)
400+
fieldValue := v.Field(i)
382401
tomlVal := field.Tag.Get("toml")
383-
switch field.Type.Kind() {
384-
case reflect.Struct:
402+
403+
if field.Type.Kind() == reflect.Struct {
385404
path := fieldPath + field.Name + "."
386-
setTage2Map(root+tomlVal+".", field.Type, m, path)
387-
default:
388-
if tomlVal == "" {
389-
continue
390-
}
391-
tomlPath := root + tomlVal
392-
path := fieldPath + field.Name
393-
var v *string
394-
str := ""
395-
v = &str
396-
m[tomlPath] = TomlInfo{field: field, Value: v, fieldPath: path}
405+
setTage2Map(root+tomlVal+".", field.Type, fieldValue, m, path)
406+
continue
407+
}
408+
409+
if tomlVal == "" {
410+
continue
397411
}
412+
413+
tomlPath := root + tomlVal
414+
path := fieldPath + field.Name
415+
var v *string
416+
str := ""
417+
v = &str
418+
419+
fieldValueStr := getFieldValueString(fieldValue)
420+
usage := field.Tag.Get("usage")
421+
m[tomlPath] = TomlInfo{field: field, Value: v, fieldPath: path, fieldValue: fieldValueStr, usage: usage}
398422
}
399423
}
400424

0 commit comments

Comments
 (0)