func (pw *ProjectWatcher) updateConfig() { loggers.Info("Reloading the project.toml file ...") var newConfig ProjectConfig if _, err := toml.DecodeFile("project.toml", &newConfig); err != nil { loggers.Error("We found the project.toml has changed, but it contains some error, will omit it.") loggers.Error("TOML Error: %v", err) fmt.Println() loggers.Info("Waiting for the file changes ...") } else { loggers.Succ("Loaded the new project.toml, will update all the dependencies ...") rootConfig.Lock() rootConfig.Package = newConfig.Package rootConfig.Assets = newConfig.Assets rootConfig.Distribution = newConfig.Distribution rootConfig.Unlock() if err := updateGolangDeps(); err != nil { loggers.Error("Failed to load project Go dependencies, %v", err) return } if err := updateAssetsDeps(); err != nil { loggers.Error("Failed to load project assets dependencies, %v", err) return } pw.addTask(kTaskBuildImages, "") pw.addTask(kTaskBuildStyles, "") pw.addTask(kTaskBuildJavaScripts, "") pw.addTask(kTaskGenAssetsMapping, "") pw.addTask(kTaskBuildBinary, "") pw.addTask(kTaskBinaryRestart, "") } }
func updateGolangDeps() error { rootConfig.RLock() defer rootConfig.RUnlock() if rootConfig.Package == nil || len(rootConfig.Package.Dependencies) == 0 { return nil } fmt.Println() loggers.Info("Start to loading Go dependencies...") if hasGetColangDeps() { loggers.Info("Has Loaded Go package dependencies") return nil } params := []string{"get", ""} for _, dep := range rootConfig.Package.Dependencies { params[len(params)-1] = dep loggers.Info("Loading Go package dependency: %v", dep) getCmd := exec.Command("go", params...) getCmd.Stdout = os.Stdout getCmd.Stderr = os.Stderr getCmd.Env = mergeEnv(nil) if err := getCmd.Run(); err != nil { loggers.Error("Error when run go get: go %v, %v", params, err) return err } } loggers.Succ("Loaded Go package dependencies: \n\t%v", strings.Join(rootConfig.Package.Dependencies, "\n\t")) return nil }
func (app *AppShell) startRunner() { for task := range app.taskChan { switch task.taskType { case kTaskBuildImages: app.curError = app.buildImages(task.module) case kTaskBuildStyles: app.curError = app.buildStyles(task.module) case kTaskBuildJavaScripts: app.curError = app.buildJavaScripts(task.module) case kTaskGenAssetsMapping: app.curError = app.genAssetsMapping() case kTaskBinaryTest: app.curError = app.binaryTest(task.module) case kTaskBuildBinary: app.curError = app.buildBinary() case kTaskBinaryRestart: if app.curError == nil { if err := app.kill(); err != nil { loggers.Error("App cannot be killed, maybe you should restart the gobuildweb: %v", err) } else { if err := app.start(); err != nil { loggers.Error("App cannot be started, maybe you should restart the gobuildweb: %v", err) } } } else { loggers.Warn("You have errors with current assets and binary, please fix that ...") } fmt.Println() loggers.Info("Waiting for the file changes ...") } } }
func updateAssetsDeps() error { rootConfig.RLock() defer rootConfig.RUnlock() if rootConfig.Assets == nil || len(rootConfig.Assets.Dependencies) == 0 { return nil } fmt.Println() loggers.Info("Start to loading assets dependencies...") checkParams := []string{"list", "--depth", "0", ""} params := []string{"install", ""} deps := make([]string, len(rootConfig.Assets.Dependencies), len(rootConfig.Assets.Dependencies)+1) copy(deps, rootConfig.Assets.Dependencies) // add all dev deps for xxxify deps = append(deps, "browserify", "coffeeify", "envify", "uglifyify", "babelify", "babel-preset-es2015", "babel-preset-react", "nib", "stylus") for _, dep := range deps { checkParams[len(checkParams)-1] = dep listCmd := exec.Command("npm", checkParams...) listCmd.Env = mergeEnv(nil) if err := listCmd.Run(); err == nil { // the module has been installed loggers.Info("Checked npm module: %v", dep) continue } params[len(params)-1] = dep loggers.Info("Loading npm module: %v", dep) installCmd := exec.Command("npm", params...) installCmd.Stdout = os.Stdout installCmd.Stderr = os.Stderr installCmd.Env = mergeEnv(nil) if err := installCmd.Run(); err != nil { loggers.Error("Error when run npm install: npm %v, %v", params, err) return err } } loggers.Succ("Loaded assets dependencies: \n\t%v", strings.Join(deps, "\n\t")) return nil }
//是否已经下载了go运行所需要的包,是否可以编译成功 func hasGetColangDeps() bool { cmd := exec.Command("go", "build") loggers.Info("Started to go build...") err := cmd.Start() if err != nil { loggers.Error("Failed to go build... %+v", err) return false } done := make(chan error, 1) go func() { done <- cmd.Wait() }() err = <-done if err != nil { loggers.Error("Failed to go build...%+v", err) } else { loggers.Info("Successed to go build...") cmd := exec.Command("rm", "zhiwang_web") cmd.Run() return true } return false }
//传入参数specified-entries,用逗号分隔 func getAvailableEntries(specifiedEntries string, entries []assets.Entry) []assets.Entry { var availableEntries []assets.Entry specifiedEntries = strings.TrimSpace(specifiedEntries) if len(specifiedEntries) == 0 { return entries } specifiedEntryList := strings.Split(specifiedEntries, ",") specifiedEntryMap := map[string]bool{} for _, specifiedEntry := range specifiedEntryList { specifiedEntryMap[specifiedEntry] = true } for _, entry := range entries { if _, ok := specifiedEntryMap[entry.Name]; ok { availableEntries = append(availableEntries, entry) loggers.Info("the available entry is %+v", entry) } } return availableEntries }
func (app *AppShell) Dist() error { app.isProduction = true fmt.Println() loggers.Info("Creating distribution package for %v-%v", rootConfig.Package.Name, rootConfig.Package.Version) var err error if err = app.buildImages(""); err != nil { loggers.Error("Error when building images, %v", err) } else if err = app.genAssetsMapping(); err != nil { loggers.Error("Error when generating assets mapping source code, %v", err) } else if err = app.buildStyles(""); err != nil { loggers.Error("Error when building stylesheets, %v", err) } else if err = app.clearJavaScriptsAssets(); err != nil { loggers.Error("Error when clear javascripts, %v", err) } else if err = app.buildJavaScripts(APP_SHELL_JS_TASK_INIT_ENTRY_KEY); err != nil { loggers.Error("Error when building javascripts, %v", err) } else if err = app.genAssetsMapping(); err != nil { loggers.Error("Error when generating assets mapping source code, %v", err) } else if err = app.binaryTest(""); err != nil { loggers.Error("You have failed test cases, %v", err) } else if err = app.distExtraCommand(); err != nil { loggers.Error("Error when running the distribution extra command, %v", err) } else if err == nil { goOs, goArch := runtime.GOOS, runtime.GOARCH targets := append(rootConfig.Distribution.CrossTargets, [2]string{goOs, goArch}) visited := make(map[string]struct{}) for _, target := range targets { buildTarget := fmt.Sprintf("%s_%s", target[0], target[1]) if _, ok := visited[buildTarget]; ok { continue } visited[buildTarget] = struct{}{} if err = app.buildBinary(target[:]...); err != nil { loggers.Error("Error when building binary for %v, %v", target, err) } } } if err == nil { err = app.buildPackage() } return err }
func (pw *ProjectWatcher) runAndWatch(dir string, appArgs []string) error { if watcher, err := fsnotify.NewWatcher(); err != nil { return err } else { pw.app = NewAppShell(appArgs) if err := pw.app.Run(); err != nil { return err } pw.watcher = watcher defer pw.watcher.Close() if err := pw.addDirs(dir); err != nil { return err } go pw.watchProject() loggers.Info("Waiting for file changes ...") <-pw.stopChan return nil } }