// Main is an entry point of the subcommand (tool). func main(hs []tool.Handler, i int, args tool.Data) { // The first argument in the list is a path. // If it's missing use an empty string instead. p := args.GetDefault(0, "") // Prepare source and destination directory paths. src, err := path.ImportToAbsolute("github.com/colegion/goal/internal/skeleton") log.AssertNil(err) destImp, err := path.CleanImport(p) log.AssertNil(err) dest, err := path.ImportToAbsolute(destImp) log.AssertNil(err) // Make sure the requested import path (dest) does not exist yet. if _, err := os.Stat(dest); !os.IsNotExist(err) { log.Error.Panicf(`Cannot use "%s", such import path already exists.`, destImp) } // Scan the skeleton directory and get a list of directories / files // to be copied / processed. res, err := walk(src) log.AssertNil(err) // Create the directories in destination path. for i := 0; i < len(res.dirs); i++ { err = os.MkdirAll(filepath.Join(dest, res.dirs[i]), 0755) log.AssertNil(err) } // Copy static files to the destination directories. for i := 0; i < len(res.files); i++ { copyFile(res.files[i].absolute, filepath.Join(dest, res.files[i].relative)) } // Process source files and copy to the destination directories. for i := 0; i < len(res.srcs); i++ { copyModifiedFile( res.srcs[i].absolute, filepath.Join(dest, res.srcs[i].relative), [][][]byte{ { []byte("github.com/colegion/goal/internal/skeleton"), []byte(destImp), }, }, ) } log.Info.Printf(info, destImp) }
// main is an entry point of the "run" subcommand (tool). func main(hs []tool.Handler, i int, args tool.Data) { // The first argument in the list is a path. // If it's missing use an empty string instead. p := args.GetDefault(0, "") // Determine import path and absolute path of the project to run. imp, err := path.CleanImport(p) log.AssertNil(err) dir, err := path.ImportToAbsolute(imp) log.AssertNil(err) // Prepare a path of configuration file. cf := filepath.Join(dir, ConfigFile) // Start a user tasks runner and instances controller. go instanceController() // Start a configuration file watcher. go configDaemon(imp, cf) // Show user friendly errors and terminate subprograms // in case of panics. defer func() { channel <- message{ action: "exit", } <-stopped log.Trace.Panicln("Application has been terminated.") }() // Execute all commands from the requested directory. curr, _ := os.Getwd() os.Chdir(dir) // pushd defer func() { // Going back to the initial directory. os.Chdir(curr) // popd }() // Load the configuration. reloadConfig() // Cleaning up after we are done. signal.Notify(notify, os.Interrupt, syscall.SIGTERM) <-notify }