示例#1
0
文件: app.go 项目: yihe2/gobuildweb
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
}
示例#2
0
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
	})
}
示例#3
0
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
}
示例#4
0
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
}
示例#5
0
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
}
示例#6
0
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()
		}
	}
}
示例#7
0
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
}