Пример #1
0
// 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)
}
Пример #2
0
// 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
}