func (app *AppShell) buildPackage() error { name, version := rootConfig.Package.Name, rootConfig.Package.Version pkgName := fmt.Sprintf("%s-%s", name, version) srcFolders := append([]string{"public"}, rootConfig.Distribution.PackExtras...) 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{}{} srcFolders = append(srcFolders, app.binaryName(name, version, target[0], target[1])) } if zipFile, err := os.Create(pkgName + ".zip"); err != nil { return fmt.Errorf("Cannot create the zip file[%q], %v", pkgName, err) } else { defer zipFile.Close() zw := zip.NewWriter(zipFile) defer zw.Close() for _, srcFolder := range srcFolders { err := filepath.Walk(srcFolder, func(fn string, info os.FileInfo, err error) error { if err == nil && !info.IsDir() { zipSrcName := path.Join(pkgName, fn) fileHeader, err := zip.FileInfoHeader(info) if err != nil { return err } fileHeader.Name = zipSrcName zipSrcFile, err := zw.CreateHeader(fileHeader) if err != nil { return err } srcFile, err := os.Open(fn) if err != nil { return err } io.Copy(zipSrcFile, srcFile) srcFile.Close() loggers.Debug("Archiving %s", zipSrcName) } return nil }) if err != nil { return fmt.Errorf("Cannot walk the files when creating the zip file, %v", err) } } } loggers.Succ("Finish packing the deploy package in %s.zip", pkgName) return nil }
func (pw *ProjectWatcher) addDirs(root string) error { return filepath.Walk(root, func(fname string, info os.FileInfo, err error) error { if err == nil && info.IsDir() && !pw.isIgnoredDir(fname) { if err := pw.watcher.Add(fname); err != nil { return err } loggers.Debug("Watching %s", fname) } return nil }) }
func (css _StyleSheet) Build(isProduction bool) error { filename := fmt.Sprintf("assets/stylesheets/%s.styl", css.entry) isStylus := true if exist, _ := css.checkFile(filename, true); !exist { filename = fmt.Sprintf("assets/stylesheets/%s.css", css.entry) if exist, err := css.checkFile(filename, true); !exist { return err } else { isStylus = false } } target := fmt.Sprintf("public/stylesheets/%s.css", css.entry) // * Maybe it's a template using images, styles assets links // TODO // * Maybe we need to call stylus preprocess if isStylus { params := []string{"--use", "nib", filename, "--out", "public/stylesheets"} if isProduction { params = append(params, "--compress") } else { params = append(params, "--sourcemap-inline") } params = append(params, "--include-css") // add asset plugin to change original file path to the finger printed one if css.config.AssetsMappingJson != "" { params = append(params, "--use", getStylusPluginPath()) } cmd := exec.Command("./node_modules/stylus/bin/stylus", params...) loggers.Debug("[CSS][%s] Building asset: %s, %v", css.entry, filename, cmd.Args) cmd.Stderr = os.Stderr cmd.Stdout = os.Stdout cmd.Env = css.getEnv(isProduction) if err := cmd.Run(); err != nil { loggers.Error("[CSS][%s] Error when building asset %v, %v", css.entry, cmd.Args, err) return err } } else { if err := css.copyFile(target, filename); err != nil { return err } } // * generate the hash, clear old bundle, move to target target = css.addFingerPrint("public/stylesheets", css.entry+".css") loggers.Succ("[CSS][%s] Saved assset: %s", css.entry, target) return nil }
func (app *AppShell) buildBinary(params ...string) error { goOs, goArch := runtime.GOOS, runtime.GOARCH if len(params) == 2 && (goOs != params[0] || goArch != params[1]) { goOs, goArch = params[0], params[1] } rootConfig.RLock() builder := rootConfig.Package.Builder binName := app.binaryName(rootConfig.Package.Name, rootConfig.Package.Version, goOs, goArch) var buildOpts []string if app.isProduction { buildOpts = make([]string, len(rootConfig.Distribution.BuildOpts)) copy(buildOpts, rootConfig.Distribution.BuildOpts) } else { buildOpts = make([]string, len(rootConfig.Package.BuildOpts)) copy(buildOpts, rootConfig.Package.BuildOpts) } rootConfig.RUnlock() cmdName := "go" flags := make([]string, 0, 3+len(buildOpts)) if builder != "" { flags = append(flags, "go") cmdName = builder } flags = append(flags, "build") flags = append(flags, buildOpts...) flags = append(flags, []string{"-o", binName}...) buildCmd := exec.Command(cmdName, flags...) buildCmd.Stderr = os.Stderr buildCmd.Stdout = os.Stdout buildCmd.Env = mergeEnv(map[string]string{ "GOOS": goOs, "GOARCH": goArch, }) loggers.Debug("Running build: %v", buildCmd.Args) start := time.Now() if err := buildCmd.Run(); err != nil { loggers.Error("Building failed") return err } app.binName = binName duration := float64(time.Since(start).Nanoseconds()) / 1e6 loggers.Succ("Got binary built %s, takes=%.3fms", binName, duration) return nil }
func (js _JavaScript) Build(isProduction bool) error { if os.Getenv("NODE_ENV") == "production" { isProduction = true } assetEntry, ok := js.config.getAssetEntry(js.entry) if !ok { return nil } target := fmt.Sprintf("public/javascripts/%s.js", js.entry) filename := fmt.Sprintf("assets/javascripts/%s.js", js.entry) isCoffee := false if exist, _ := js.checkFile(filename, true); !exist { filename = fmt.Sprintf("assets/javascripts/%s.coffee", js.entry) if exist, err := js.checkFile(filename, true); !exist { return err } isCoffee = true } // * Maybe it's a template using images, styles assets links // TODO // * run browserify params := []string{filename} for _, require := range assetEntry.Requires { params = append(params, "--require", require) } for _, external := range assetEntry.Externals { if anEntry, ok := js.config.getAssetEntry(external); ok { for _, require := range anEntry.Requires { params = append(params, "--external", require) } } } for _, opt := range assetEntry.BundleOpts { params = append(params, opt) } if isCoffee { params = append(params, "--transform", "coffeeify") } else { params = append(params, "--transform", "[", "babelify", "--presets", "[", "es2015", "react", "]", "]") } params = append(params, "--transform", "envify") if isProduction { params = append(params, "-g", "uglifyify") } else { params = append(params, "--debug") } params = append(params, "--outfile", target) cmd := exec.Command("./node_modules/browserify/bin/cmd.js", params...) loggers.Debug("[JavaScript][%s] Building asset: %s, %v", js.entry, filename, cmd.Args) cmd.Stderr = os.Stderr cmd.Stdout = os.Stdout cmd.Env = js.getEnv(isProduction) if err := cmd.Run(); err != nil { loggers.Error("[JavaScript][%s] Error when building asset %v, %v", js.entry, cmd.Args, err) return err } // * generate the hash, clear old bundle, move to target target = js.addFingerPrint("public/javascripts", js.entry+".js") loggers.Succ("[JavaScript][%s] Saved assset: %s", js.entry, target) return nil }
func (pw *ProjectWatcher) watchProject() { tick := time.Tick(800 * time.Millisecond) for { select { case event := <-pw.watcher.Events: if event.Name == "" || pw.isIgnoredDir(event.Name) || strings.HasSuffix(event.Name, ".swp") || strings.HasSuffix(event.Name, ".DS_Store") { break } loggers.Debug("fsevents: %v", event) if event.Op&fsnotify.Create == fsnotify.Create || event.Op&fsnotify.Write == fsnotify.Write { if fi, err := os.Stat(event.Name); err == nil { if fi.IsDir() { if err := pw.watcher.Add(event.Name); err != nil { loggers.Error("Failed to add new directory into watching list[%v], %v", event.Name, err) } else { loggers.Debug("Watching %s", event.Name) } } else { if event.Name == "project.toml" { pw.updateConfig() } pw.maybeGoCodeChanged(event.Name) pw.maybeAssetsChanged(event.Name) } } } else if event.Op&fsnotify.Remove == fsnotify.Remove || event.Op&fsnotify.Rename == fsnotify.Rename { // maybe remove some dir if fi, err := os.Stat(event.Name); err == nil { if fi.IsDir() { if err := pw.watcher.Remove(event.Name); err != nil { loggers.Error("Failed to remove directory from watching list [%v], %v", event.Name, err) } // if the dir is under assets, we need to rebuild all the assets or sprites // else we take it as a go code directory // TODO } else { if event.Name == "project.toml" { panic("Please don't hurt the project.toml") } // maybe remove some source code // TODO } } } case err := <-pw.watcher.Errors: loggers.Error("Error: %v", err) case <-tick: pw.taskLock.Lock() if len(pw.tasks) > 0 { pw.app.executeTask(pw.tasks...) pw.tasks = make([]AppShellTask, 0) } pw.taskLock.Unlock() } } }
func (js _JavaScript) Build(isProduction bool) error { if os.Getenv("NODE_ENV") == "production" { isProduction = true } assetEntry, ok := js.config.getAssetEntry(js.entry) if !ok { return nil } suffixJs, suffixCoffee, originDir, targetDir := ".js", ".coffee", "assets/javascripts", "public/javascripts" filename, outfile := path.Join(originDir, js.entry+suffixJs), path.Join(targetDir, js.entry+suffixJs) isCoffee := false if exist, _ := js.checkFile(filename, true); !exist { filename = path.Join(originDir, js.entry+suffixCoffee) if exist, err := js.checkFile(filename, true); !exist { return err } isCoffee = true } // * generate the hash, just loaded if not change outTarget := js.traverEntryFingerPrint(originDir, targetDir, js.entry, filename, suffixJs) mapping := js._Asset.getJsonAssetsMapping() if targetName, ok := mapping[outfile[len("public/"):]]; ok { if targetName == outTarget[len("public/"):] { loggers.Succ("[JavaScript][%s] Loaded assset: %s", js.entry, outTarget) return nil } } // * Maybe it's a template using images, styles assets links // TODO // * run browserify params := []string{filename} for _, require := range assetEntry.Requires { params = append(params, "--require", require) } for _, external := range assetEntry.Externals { if anEntry, ok := js.config.getAssetEntry(external); ok { for _, require := range anEntry.Requires { params = append(params, "--external", require) } } } for _, opt := range assetEntry.BundleOpts { params = append(params, opt) } if isCoffee { params = append(params, "--transform", "coffeeify") } else { params = append(params, "--transform", "[", "babelify", "--presets", "[", "es2015", "react", "]", "]") } params = append(params, "--transform", "envify") if isProduction { params = append(params, "-g", "uglifyify") } else { params = append(params, "--debug") } params = append(params, "--outfile", outfile) cmd := exec.Command("./node_modules/browserify/bin/cmd.js", params...) loggers.Debug("[JavaScript][%s] Building asset: %s, %v", js.entry, filename, cmd.Args) cmd.Stderr = os.Stderr cmd.Stdout = os.Stdout cmd.Env = js.getEnv(isProduction) if err := cmd.Run(); err != nil { loggers.Error("[JavaScript][%s] Error when building asset %v, %v", js.entry, cmd.Args, err) return err } //clear old bundle, move to target js._Asset.removeOldFile(targetDir, js.entry+suffixJs) if err := os.Rename(outfile, outTarget); err != nil { loggers.Error("rename file error, %v", err) } // target = js.addFingerPrint("public/javascripts", js.entry+".js") loggers.Succ("[JavaScript][%s] Saved assset: %s", js.entry, outTarget) return nil }