Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support air --help #491

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 24 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package main

import (
_ "embed"
"flag"
"fmt"

Check failure on line 6 in main.go

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

undefined: Println

Check failure on line 6 in main.go

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

undefined: Println

Check failure on line 6 in main.go

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

undefined: Println

Check failure on line 6 in main.go

View workflow job for this annotation

GitHub Actions / build (macos-latest)

undefined: Println

Check failure on line 6 in main.go

View workflow job for this annotation

GitHub Actions / build (macos-latest)

undefined: Println

Check failure on line 6 in main.go

View workflow job for this annotation

GitHub Actions / build (macos-latest)

undefined: Println
"log"
"os"
"os/signal"
Expand All @@ -11,16 +12,21 @@
"syscall"

"github.com/cosmtrek/air/runner"
"github.com/pelletier/go-toml"
)

var (
cfgPath string
debugMode bool
showVersion bool
help bool
cmdArgs map[string]runner.TomlInfo

//go:embed air_example.toml
airExampleToml string
)

func helpMessage() {
func usage() {
fmt.Fprintf(flag.CommandLine.Output(), "Usage of %s:\n\n", os.Args[0])
fmt.Printf("If no command is provided %s will start the runner with the provided flags\n\n", os.Args[0])
fmt.Println("Commands:")
Expand All @@ -35,10 +41,11 @@
}

func parseFlag(args []string) {
flag.Usage = helpMessage
flag.Usage = usage
flag.StringVar(&cfgPath, "c", "", "config path")
flag.BoolVar(&debugMode, "d", false, "debug mode")
flag.BoolVar(&showVersion, "v", false, "show version")
flag.BoolVar(&help, "h", false, "help")
cmd := flag.CommandLine
cmdArgs = runner.ParseConfigFlag(cmd)
if err := flag.CommandLine.Parse(args); err != nil {
Expand Down Expand Up @@ -70,6 +77,17 @@
}
}

func helpMessage() {
var cfg runner.Config
err := toml.Unmarshal([]byte(airExampleToml), &cfg)
if err != nil {
log.Fatal(err)
}
fmt.Printf("cfg: %+v\n", cfg)
m := runner.FlatConfig(cfg)
fmt.Printf("m: %+v\n", m)
}

func main() {
versionInfo := GetVersionInfo()
fmt.Printf(`
Expand All @@ -82,6 +100,10 @@
if showVersion {
return
}
if help {
helpMessage()
return
}

if debugMode {
fmt.Println("[debug] mode")
Expand Down
94 changes: 47 additions & 47 deletions runner/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"time"

"dario.cat/mergo"
"github.com/pelletier/go-toml"

Check failure on line 15 in runner/config.go

View workflow job for this annotation

GitHub Actions / smoke_test_macos / smoke_test

github.com/pelletier/go-toml@v1.9.5: Get "https://proxy.golang.org/github.com/pelletier/go-toml/@v/v1.9.5.zip": EOF
)

const (
Expand All @@ -23,8 +23,8 @@

// Config is the main configuration structure for Air.
type Config struct {
Root string `toml:"root"`
TmpDir string `toml:"tmp_dir"`
Root string `toml:"root" comment:". or absolute path, please note that the directories following must be under root."`
TmpDir string `toml:"tmp_dir" comment:"Temporary directory."`
TestDataDir string `toml:"testdata_dir"`
Build cfgBuild `toml:"build"`
Color cfgColor `toml:"color"`
Expand All @@ -34,32 +34,54 @@
}

type cfgBuild struct {
PreCmd []string `toml:"pre_cmd"`
Cmd string `toml:"cmd"`
PostCmd []string `toml:"post_cmd"`
Bin string `toml:"bin"`
FullBin string `toml:"full_bin"`
ArgsBin []string `toml:"args_bin"`
Log string `toml:"log"`
IncludeExt []string `toml:"include_ext"`
ExcludeDir []string `toml:"exclude_dir"`
IncludeDir []string `toml:"include_dir"`
ExcludeFile []string `toml:"exclude_file"`
IncludeFile []string `toml:"include_file"`
ExcludeRegex []string `toml:"exclude_regex"`
ExcludeUnchanged bool `toml:"exclude_unchanged"`
FollowSymlink bool `toml:"follow_symlink"`
Poll bool `toml:"poll"`
PollInterval int `toml:"poll_interval"`
Delay int `toml:"delay"`
StopOnError bool `toml:"stop_on_error"`
SendInterrupt bool `toml:"send_interrupt"`
KillDelay time.Duration `toml:"kill_delay"`
Rerun bool `toml:"rerun"`
RerunDelay int `toml:"rerun_delay"`
PreCmd []string `toml:"pre_cmd" comment:"Array of commands to run before each build"`
Cmd string `toml:"cmd" comment:"Shell command to run for building."`
PostCmd []string `toml:"post_cmd" comment:"Array of commands to run after ^C"`
Bin string `toml:"bin" comment:"Binary file yields from cmd."`
FullBin string `toml:"full_bin" comment:"Customize binary, can setup environment variables when run your app."`
ArgsBin []string `toml:"args_bin" comment:"Add additional arguments when running binary (bin/full_bin)."`
Log string `toml:"log" comment:"Log file places in your tmp_dir."`
IncludeExt []string `toml:"include_ext" comment:"Watch these filename extensions."`
ExcludeDir []string `toml:"exclude_dir" comment:"Ignore these filename extensions or directories."`
IncludeDir []string `toml:"include_dir" comment:"Watch these directories if you specified."`
ExcludeFile []string `toml:"exclude_file" comment:"Exclude these files."`
IncludeFile []string `toml:"include_file" comment:"Watch these files."`
ExcludeRegex []string `toml:"exclude_regex" comment:"Exclude specific regular expressions."`
ExcludeUnchanged bool `toml:"exclude_unchanged" comment:"Exclude unchanged files."`
FollowSymlink bool `toml:"follow_symlink" comment:"Follow symlink for directories"`
Poll bool `toml:"poll" comment:"Poll files for changes instead of using fsnotify."`
PollInterval int `toml:"poll_interval" comment:"Poll interval (defaults to the minimum interval of 500ms)."`
Delay int `toml:"delay" comment:"Delay in milliseconds."`
StopOnError bool `toml:"stop_on_error" comment:"Stop running old binary when build errors occur."`
SendInterrupt bool `toml:"send_interrupt" comment:"Send Interrupt signal before killing process (windows does not support this feature)"`
KillDelay time.Duration `toml:"kill_delay" comment:"Delay after sending Interrupt signal in nanoseconds."`
Rerun bool `toml:"rerun" comment:"Rerun binary or not"`
RerunDelay int `toml:"rerun_delay" comment:"Delay after each executions in milliseconds."`
regexCompiled []*regexp.Regexp
}

type cfgLog struct {
AddTime bool `toml:"time" comment:"Show log time"`
MainOnly bool `toml:"main_only" comment:"Only show main log (silences watcher, build, runner)"`
}

type cfgColor struct {
Main string `toml:"main" comment:"Customize main part's color. If no color found, use the raw app log."`
Watcher string `toml:"watcher" comment:"Customize watcher part's color."`
Build string `toml:"build" comment:"Customize build part's color."`
Runner string `toml:"runner" comment:"Customize runner part's color."`
App string `toml:"app" comment:"Customize app part's color."`
}

type cfgMisc struct {
CleanOnExit bool `toml:"clean_on_exit" comment:"Delete tmp directory on exit"`
}

type cfgScreen struct {
ClearOnRebuild bool `toml:"clear_on_rebuild" comment:"Clear screen on rebuild"`
KeepScroll bool `toml:"keep_scroll" comment:"Keep scroll position"`
}

func (c *cfgBuild) RegexCompiled() ([]*regexp.Regexp, error) {
if len(c.ExcludeRegex) > 0 && len(c.regexCompiled) == 0 {
c.regexCompiled = make([]*regexp.Regexp, 0, len(c.ExcludeRegex))
Expand All @@ -74,28 +96,6 @@
return c.regexCompiled, nil
}

type cfgLog struct {
AddTime bool `toml:"time"`
MainOnly bool `toml:"main_only"`
}

type cfgColor struct {
Main string `toml:"main"`
Watcher string `toml:"watcher"`
Build string `toml:"build"`
Runner string `toml:"runner"`
App string `toml:"app"`
}

type cfgMisc struct {
CleanOnExit bool `toml:"clean_on_exit"`
}

type cfgScreen struct {
ClearOnRebuild bool `toml:"clear_on_rebuild"`
KeepScroll bool `toml:"keep_scroll"`
}

type sliceTransformer struct{}

func (t sliceTransformer) Transformer(typ reflect.Type) func(dst, src reflect.Value) error {
Expand Down
2 changes: 1 addition & 1 deletion runner/flag.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const unsetDefault = "DEFAULT"
// ParseConfigFlag parse toml information for flag
func ParseConfigFlag(f *flag.FlagSet) map[string]TomlInfo {
c := Config{}
m := flatConfig(c)
m := FlatConfig(c)
for k, v := range m {
f.StringVar(v.Value, k, unsetDefault, "")
}
Expand Down
16 changes: 10 additions & 6 deletions runner/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"strings"
"sync"

"github.com/fsnotify/fsnotify"

Check failure on line 16 in runner/util.go

View workflow job for this annotation

GitHub Actions / smoke_test_macos / smoke_test

github.com/fsnotify/fsnotify@v1.6.0: Get "https://proxy.golang.org/github.com/fsnotify/fsnotify/@v/v1.6.0.zip": EOF
)

const (
Expand Down Expand Up @@ -300,6 +300,7 @@
fieldPath string
field reflect.StructField
Value *string
Comment string
}

func setValue2Struct(v reflect.Value, fieldName string, value string) {
Expand Down Expand Up @@ -350,22 +351,25 @@
}
}

// flatConfig ...
func flatConfig(stut interface{}) map[string]TomlInfo {
// FlatConfig ...
func FlatConfig(stut interface{}) map[string]TomlInfo {
m := make(map[string]TomlInfo)
t := reflect.TypeOf(stut)
t := reflect.ValueOf(stut)
setTage2Map("", t, m, "")
return m
}

func setTage2Map(root string, t reflect.Type, m map[string]TomlInfo, fieldPath string) {
func setTage2Map(root string, v reflect.Value, m map[string]TomlInfo, fieldPath string) {
t := v.Type()
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
value := v.Field(i)
tomlVal := field.Tag.Get("toml")
comment := field.Tag.Get("comment")
switch field.Type.Kind() {
case reflect.Struct:
path := fieldPath + field.Name + "."
setTage2Map(root+tomlVal+".", field.Type, m, path)
setTage2Map(root+tomlVal+".", value, m, path)
default:
if tomlVal == "" {
continue
Expand All @@ -375,7 +379,7 @@
var v *string
str := ""
v = &str
m[tomlPath] = TomlInfo{field: field, Value: v, fieldPath: path}
m[tomlPath] = TomlInfo{field: field, Value: v, fieldPath: path, Comment: comment}
}
}
}
2 changes: 1 addition & 1 deletion runner/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ func Test_killCmd_SendInterrupt_false(t *testing.T) {

func TestGetStructureFieldTagMap(t *testing.T) {
c := Config{}
tagMap := flatConfig(c)
tagMap := FlatConfig(c)
for _, i2 := range tagMap {
fmt.Printf("%v\n", i2.fieldPath)
}
Expand Down
Loading