Esempio n. 1
0
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, "")
	}
}
Esempio n. 2
0
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
}
Esempio n. 3
0
func (il _ImageLibrary) Build(isProduction bool) error {
	folderName := fmt.Sprintf("assets/images/%s", il.entry)
	if exist, err := il.checkFile(folderName, false); !exist {
		return err
	}
	targetFolder := fmt.Sprintf("public/images/%s", il.entry)
	if err := ResetDir(targetFolder, true); err != nil {
		return err
	}

	// copy the single image files
	if imageItems, err := il.getImages(folderName); err != nil {
		return err
	} else {
		for _, imgItem := range imageItems {
			target := fmt.Sprintf("public/images/%s/%s", il.entry, imgItem.name)
			if err := il.copyFile(target, imgItem.fullpath); err != nil {
				return err
			}
			target = il.addFingerPrint(targetFolder, imgItem.name)
			loggers.Succ("[ImageLibrary][%s] Saved images: %s", il.entry, target)
		}
	}

	// check if we have sprite folders under assets
	return il.buildSprites(il.entry, isProduction)
}
Esempio n. 4
0
func (d _GoPkgMappingDumper) Dump(mapping *AssetsMapping) error {
	pkgName, targetPath := d.GetPkgPath()

	mapping.PkgName = pkgName
	sort.Sort(mapping)

	if file, err := os.Create(targetPath); err != nil {
		return fmt.Errorf("Cannot create the assets mapping go file, %+v", err)
	} else {
		defer file.Close()
		if err := tmAssetsMapping.Execute(file, mapping); err != nil {
			return fmt.Errorf("Cannot generate assets mapping file, %+v", err)
		}
	}

	var out bytes.Buffer
	cmd := exec.Command("gofmt", "-w", targetPath)
	cmd.Stderr = &out
	if err := cmd.Run(); err != nil {
		loggers.Error("[AssetMapping] failed to gofmt source code, %v", out.String())
		return err
	}
	loggers.Succ("[AssetMappings] Saved asssets mapping go file: %q", targetPath)
	return nil
}
Esempio n. 5
0
func (s _Sprite) save(spriteImg image.Image, items []_ImageItem, fullWidth, fullHeight int) error {
	targetFolder := fmt.Sprintf("public/images/%s", s.entry)
	target := path.Join(targetFolder, s.name+".png")
	if file, err := os.Create(target); err != nil {
		return fmt.Errorf("Cannot create sprite file %s, %v", target, err)
	} else {
		defer file.Close()
		if err := png.Encode(file, spriteImg); err != nil {
			return nil
		}
		target = s.addFingerPrint(targetFolder, s.name+".png")
		loggers.Succ("[Sprite][%s] Saved sprite image: %s", s.entry, target)

		// generate the stylus file
		stylus := "assets/stylesheets/sprites"
		if err := os.MkdirAll(stylus, os.ModePerm|os.ModeDir); err != nil {
			return fmt.Errorf("Cannot mkdir %s, %v", stylus, err)
		}
		stylus = fmt.Sprintf("assets/stylesheets/sprites/%s_%s.styl", s.entry, s.name)
		if stylusFile, err := os.Create(stylus); err != nil {
			return fmt.Errorf("Cannot create the stylus file for sprite %s, %v", stylus, err)
		} else {
			defer stylusFile.Close()

			spriteEntry := SpriteEntry{
				Entry:   s.entry,
				Name:    s.name,
				Url:     fmt.Sprintf("%s/images/%s/%s", s.config.UrlPrefix, s.entry, filepath.Base(target)),
				Sprites: make([]SpriteImage, len(items)),
				Width:   fullWidth / s.pixelRatio,
				Height:  fullHeight / s.pixelRatio,
			}
			lastHeight := 0
			for i, image := range items {
				name := image.name
				name = name[:len(name)-len(filepath.Ext(name))]
				width, height := image.Bounds().Dx(), image.Bounds().Dy()
				if width%s.pixelRatio != 0 || height%s.pixelRatio != 0 {
					loggers.Warn("You have images cannot be adjusted by the pixel ratio, %s, bounds=%v, pixelRatio=%d",
						image.fullpath, image.Bounds(), s.pixelRatio)
				}
				spriteEntry.Sprites[i] = SpriteImage{
					Name:   fmt.Sprintf("%s-%s", s.name, name),
					X:      0,
					Y:      -1 * lastHeight,
					Width:  width / s.pixelRatio,
					Height: height / s.pixelRatio,
				}
				lastHeight += (height + s.pixelRatio) / s.pixelRatio
			}
			if err := tmSprites.Execute(stylusFile, spriteEntry); err != nil {
				return fmt.Errorf("Cannot generate stylus for sprites %s, %v", spriteEntry, err)
			}
		}
	}
	return nil
}
Esempio n. 6
0
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
}
Esempio n. 7
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
}
Esempio n. 8
0
func (app *AppShell) start() error {
	app.command = exec.Command("./"+app.binName, app.args...)
	app.command.Stdout = os.Stdout
	app.command.Stderr = os.Stderr
	app.command.Env = mergeEnv(nil)

	if err := app.command.Start(); err != nil {
		return err
	}
	loggers.Succ("App is starting, %v", app.command.Args)
	fmt.Println()
	go app.command.Wait()
	time.Sleep(500 * time.Millisecond)
	return nil
}
Esempio n. 9
0
func (app *AppShell) distExtraCommand() error {
	extraCmd := rootConfig.Distribution.ExtraCmd
	if extraCmd == nil || len(extraCmd) == 0 {
		return nil
	}
	cmd := exec.Command(extraCmd[0], extraCmd[1:]...)
	cmd.Stderr = os.Stderr
	cmd.Stdout = os.Stdout
	if err := cmd.Run(); err != nil {
		loggers.Error("Error when running distribution extra command, %v, %s", extraCmd, err)
		return err
	}
	loggers.Succ("Run extra command succ: %v", cmd.Args)
	return nil
}
Esempio n. 10
0
func (app *AppShell) binaryTest(module string) error {
	return nil // close the test first, will reconsider this
	if module == "" {
		module = "./..."
	}
	testCmd := exec.Command("go", "test", "-v", module)
	testCmd.Stderr = os.Stderr
	testCmd.Stdout = os.Stdout
	testCmd.Env = mergeEnv(nil)
	if err := testCmd.Run(); err != nil {
		loggers.Error("Error when testing go modules[%s], %v", module, err)
		return err
	}
	loggers.Succ("Module[%s] Test passed: %v", module, testCmd.Args)
	return nil
}
Esempio n. 11
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
}
Esempio n. 12
0
func (d _JsonMappingDumper) Dump(mapping *AssetsMapping) error {
	srcMap := make(map[string]string)
	for _, m := range mapping.Mappings {
		srcMap[m.Src] = m.Target
	}

	if data, err := json.MarshalIndent(srcMap, "", "  "); err != nil {
		return fmt.Errorf("Cannot encoding the assets into json, %s", err)
	} else {
		if err := ioutil.WriteFile(d.jsonFile, data, 0644); err != nil {
			loggers.Error("[AsssetMapping] failed to write json mapping file, %s", err)
			return err
		}
	}
	loggers.Succ("[AssetMappings] Saved asssets mapping json file: %q", d.jsonFile)
	return nil
}
Esempio n. 13
0
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
}
Esempio n. 14
0
func (app *AppShell) binaryTest(module string) error {
	return nil // close the test first, will reconsider this
	if module == "" {
		module = "./..."
	}
	builder := rootConfig.Package.Builder
	cmdName := "go"
	flags := make([]string, 0)
	if builder != "" {
		cmdName = builder
		flags = append(flags, "go")
	}
	flags = append(flags, "test", "-v", module)
	testCmd := exec.Command(cmdName, flags...)
	testCmd.Stderr = os.Stderr
	testCmd.Stdout = os.Stdout
	testCmd.Env = mergeEnv(nil)
	if err := testCmd.Run(); err != nil {
		loggers.Error("Error when testing go modules[%s], %v", module, err)
		return err
	}
	loggers.Succ("Module[%s] Test passed: %v", module, testCmd.Args)
	return nil
}
Esempio n. 15
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
}
Esempio n. 16
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
}