Пример #1
0
// NAME
//    clean - Clean all generated files
//
// DESCRIPTION
//    Clean all generated files and paths.
//
// OPTIONS
//    --backup, -b
//        clean all backup files (*~, #*)
//    --verbose, -v
//        run in verbose mode
func TaskClean(t *tasking.T) {
	var paths []string

	paths = append(
		paths,
		ARMBinaryPath,
		"pkg",
		filepath.Join("bin", ProjectName),
		filepath.Join(AndroidPath, "bin"),
		filepath.Join(AndroidPath, "gen"),
		filepath.Join(AndroidPath, "libs"),
		filepath.Join(AndroidPath, "obj"),
	)

	// Actually remove files using rm
	for _, path := range paths {
		err := rm_rf(t, path)
		if err != nil {
			t.Error(err)
		}
	}

	if t.Flags.Bool("backup") {
		err := t.Exec(`sh -c`, `"find ./ -name '*~' -print0 | xargs -0 rm -f"`)
		if err != nil {
			t.Error(err)
		}
	}

	if t.Failed() {
		t.Fatalf("%-20s %s\n", status(t.Failed()), "Clean all generated files and paths.")
	}
	t.Logf("%-20s %s\n", status(t.Failed()), "Clean all generated files and paths.")
}
Пример #2
0
// NAME
//    deploy - Deploy the application
//
// DESCRIPTION
//    Build and deploy the application on the device via ant.
//
// OPTIONS
//    --verbose, -v
//        run in verbose mode
func TaskDeploy(t *tasking.T) {
	deployAndroid(t)
	if t.Failed() {
		t.Fatalf("%-20s %s\n", status(t.Failed()), "Build and deploy the application on the device via ant.")
	}
	t.Logf("%-20s %s\n", status(t.Failed()), "Build and deploy the application on the device via ant.")
}
Пример #3
0
// NAME
//    clean - Clean all generated files
//
// DESCRIPTION
//    Clean all generated files and paths.
//
func TaskClean(t *tasking.T) {
	var paths []string

	paths = append(
		paths,
		ARMBinaryPath,
		"pkg",
		filepath.Join("bin"),
		filepath.Join(AndroidPath, "bin"),
		filepath.Join(AndroidPath, "gen"),
		filepath.Join(AndroidPath, "libs"),
		filepath.Join(AndroidPath, "obj"),
	)

	// Actually remove files using rm
	for _, path := range paths {
		err := rm_rf(t, path)
		if err != nil {
			t.Error(err)
		}
	}
	if t.Failed() {
		t.Fatalf("%-20s %s\n", status(t.Failed()), "Clean all generated files and paths.")
	}
	t.Logf("%-20s %s\n", status(t.Failed()), "Clean all generated files and paths.")
}
Пример #4
0
// NAME
//   specgen - generates Go code from the UPnP specification files.
//
// DESCRIPTION
//   The specification is available for download from:
//
// OPTIONS
//   -s, --specs_dir=<spec directory>
//     Path to the specification storage directory. This is used to find (and download if not present) the specification ZIP files. Defaults to 'specs'
//   -o, --out_dir=<output directory>
//     Path to the output directory. This is is where the DCP source files will be placed. Should normally correspond to the directory for github.com/huin/goupnp/dcps. Defaults to '../dcps'
//   --nogofmt
//     Disable passing the output through gofmt. Do this if debugging code output problems and needing to see the generated code prior to being passed through gofmt.
func TaskSpecgen(t *tasking.T) {
	specsDir := fallbackStrValue("specs", t.Flags.String("specs_dir"), t.Flags.String("s"))
	if err := os.MkdirAll(specsDir, os.ModePerm); err != nil {
		t.Fatalf("Could not create specs-dir %q: %v\n", specsDir, err)
	}
	outDir := fallbackStrValue("../dcps", t.Flags.String("out_dir"), t.Flags.String("o"))
	useGofmt := !t.Flags.Bool("nogofmt")

NEXT_DCP:
	for _, d := range dcpMetadata {
		specFilename := filepath.Join(specsDir, d.Name+".zip")
		err := acquireFile(specFilename, d.XMLSpecURL)
		if err != nil {
			t.Logf("Could not acquire spec for %s, skipping: %v\n", d.Name, err)
			continue NEXT_DCP
		}
		dcp := newDCP(d)
		if err := dcp.processZipFile(specFilename); err != nil {
			log.Printf("Error processing spec for %s in file %q: %v", d.Name, specFilename, err)
			continue NEXT_DCP
		}
		for i, hack := range d.Hacks {
			if err := hack(dcp); err != nil {
				log.Printf("Error with Hack[%d] for %s: %v", i, d.Name, err)
				continue NEXT_DCP
			}
		}
		dcp.writePackage(outDir, useGofmt)
		if err := dcp.writePackage(outDir, useGofmt); err != nil {
			log.Printf("Error writing package %q: %v", dcp.Metadata.Name, err)
			continue NEXT_DCP
		}
	}
}
Пример #5
0
// NAME
//    cross-compile - cross-compiles gh for current platform.
//
// DESCRIPTION
//    Cross-compiles gh for current platform. Build artifacts will be in target/VERSION
func TaskCrossCompile(t *tasking.T) {
	t.Logf("Cross-compiling gh for %s...\n", runtime.GOOS)
	t.Logf("GOPATH=%s\n", os.Getenv("GOPATH"))
	err := t.Exec("goxc", "-wd=.", "-os="+runtime.GOOS, "-c="+runtime.GOOS)
	if err != nil {
		t.Fatalf("Can't cross-compile gh: %s\n", err)
	}
}
Пример #6
0
// NAME
//    say-hello - Say hello to current user
//
// DESCRIPTION
//    Print out hello to current user
//
// OPTIONS
//    --verbose, -v
//        run in verbose mode
func TaskSayHello(t *tasking.T) {
	user, _ := user.Current()
	if t.Flags.Bool("v") || t.Flags.Bool("verbose") {
		t.Logf("Hello %s, the time now is %s\n", user.Name, time.Now())
	} else {
		t.Logf("Hello %s\n", user.Name)
	}
}
Пример #7
0
// NAME
//   init - Initialize a new Mandala application
//
// DESCRIPTION
//    Initialize a new Mandala application based on application.json
//
func TaskInit(t *tasking.T) {
	var err error

	// read application.json
	app, err := readJSON(jsonPath)
	if err != nil {
		t.Error(err)
	}

	var paths []string

	// execute templates and copy the files
	err = filepath.Walk(
		"templates",
		func(path string, info os.FileInfo, err error) error {
			if !info.IsDir() {
				paths = append(paths, path)
			}
			return nil
		},
	)
	if err != nil {
		t.Error(err)
	}

	for _, path := range paths {
		var dstPath string
		splits := strings.Split(path, "/")
		if len(splits) > 1 {
			dstPath = filepath.Join(splits[1:]...)
		} else {
			dstPath = filepath.Base(path)
		}
		if err = copyFile(path, dstPath, app); err != nil {
			t.Error(err)
		}
	}

	// Rename paths accordly to app.LibName

	if err = os.Rename("_task.go", strings.ToLower(app.LibName)+"_task.go"); err != nil {
		t.Error(err)
	}

	if err = os.Rename("src/_app", filepath.Join("src", strings.ToLower(app.LibName))); err != nil {
		t.Error(err)
	}

	if err = os.Rename("test/src/_app", filepath.Join("test/src/", strings.ToLower(app.TestLibName))); err != nil {
		t.Error(err)
	}

	if t.Failed() {
		t.Fatalf("%-20s %s\n", status(t.Failed()), "Initialize a new Mandala application")
	}

	t.Logf("%-20s %s\n", status(t.Failed()), "Initialize a new Mandala application")
}
Пример #8
0
// NAME
//    build - Build the application
//
// DESCRIPTION
//    Build the application for the given platforms.
//
// OPTIONS
//    --flags=<FLAGS>
//        pass FLAGS to the compiler
//    --verbose, -v
//        run in verbose mode
func TaskBuild(t *tasking.T) {
	for _, platform := range t.Args {
		buildFun[platform](t)
	}
	if t.Failed() {
		t.Fatalf("%-20s %s\n", status(t.Failed()), "Build the application for the given platforms.")
	}
	t.Logf("%-20s %s\n", status(t.Failed()), "Build the application for the given platforms.")
}
Пример #9
0
// NAME
//    test - Run the tests
//
// DESCRIPTION
//    Build and run the tests on the given platform returning output using logcat.
//
// OPTIONS
//    --flags=<FLAGS>
//        pass the given flags to the executable
//    --verbose, -v
//        run in verbose mode
func TaskTest(t *tasking.T) {
	TaskBuild(t)
	if f, ok := runFun[t.Args[0]]; ok {
		f(t)
	}
	if t.Failed() {
		t.Fatalf("%-20s %s\n", status(t.Failed()), "Run the example on the given platforms.")
	}
	t.Logf("%-20s %s\n", status(t.Failed()), "Run the example on the given platforms.")
}
Пример #10
0
// NAME
//    test - Run black-box tests
//
// DESCRIPTION
//    Build and run the application on the given platforms.
//
// OPTIONS
//    --flags=<FLAGS>
//        pass the flags to the executable
//    --logcat=Mandala:* stdout:* stderr:* *:S
//        show logcat output (android only)
//    --verbose, -v
//        run in verbose mode
func TaskTest(t *tasking.T) {
	TaskBuild(t)
	for _, platform := range t.Args {
		runFun[platform](t)
	}
	if t.Failed() {
		t.Fatalf("%-20s %s\n", status(t.Failed()), "Run the application on the given platforms.")
	}
	t.Logf("%-20s %s\n", status(t.Failed()), "Run the application on the given platforms.")
}
Пример #11
0
// NAME
//    release - Build the application in 'release mode'
//
// DESCRIPTION
//    Build the application for Android in 'release mode'.
//
// OPTIONS
//    --flags=<FLAGS>
//        pass FLAGS to the compiler
//    --verbose, -v
//        run in verbose mode
func TaskRelease(t *tasking.T) {
	// Build app in 'release mode'
	buildAndroid(t, true)
	// Sign and 'zipalign' app
	signAndroid(t)
	// Check task
	if t.Failed() {
		t.Fatalf("%-20s %s\n", status(t.Failed()), "Release the application for Android.")
	}
	t.Logf("%-20s %s\n", status(t.Failed()), "Release the application for Android.")
}
Пример #12
0
// NAME
//    build - Build the tests
//
// DESCRIPTION
//    Build the tests for the given platforms (xorg/android).
//
// OPTIONS
//    --buildflags=
//        pass the given flags to the compiler
//    --verbose, -v
//        run in verbose mode
func TaskBuild(t *tasking.T) {
	if len(t.Args) == 0 {
		t.Error("At least a platform name must be specified!")
	}
	if f, ok := buildFun[t.Args[0]]; ok {
		f(t)
	}
	if t.Failed() {
		t.Fatalf("%-20s %s\n", status(t.Failed()), "Build the tests for the given platforms.")
	}
	t.Logf("%-20s %s\n", status(t.Failed()), "Build the tests for the given platforms.")
}
Пример #13
0
// NAME
//    install-deps - install dependencies with go get
//
// DESCRIPTION
//    Install dependencies with go get.
func TaskInstallDeps(t *tasking.T) {
	deps := []string{
		"github.com/laher/goxc",
	}

	for _, dep := range deps {
		t.Logf("Installing %s\n", dep)
		err := t.Exec("go get", dep)
		if err != nil {
			t.Fatalf("Can't download dependency %s", err)
		}
	}
}
Пример #14
0
// NAME
//    build - Build the application
//
// DESCRIPTION
//    Build the application for the given platforms.
//
// OPTIONS
//    --flags=<FLAGS>
//        pass FLAGS to the compiler
//    --verbose, -v
//        run in verbose mode
func TaskBuild(t *tasking.T) {
	if len(t.Args) < 1 {
		t.Error("You must specify a build platform!")
	} else {
		for _, platform := range t.Args {
			buildFun[platform](t)
		}
	}
	if t.Failed() {
		t.Fatalf("%-20s %s\n", status(t.Failed()), "Build the application for the given platforms.")
	}
	t.Logf("%-20s %s\n", status(t.Failed()), "Build the application for the given platforms.")
}
Пример #15
0
// NAME
//    say-hello - Say hello to current user
//
// DESCRIPTION
//    Print out hello to current user
//
// OPTIONS
//    -n, --name="NAME"
//        say hello to an user with the given NAME
//    -v, --verbose
//        run in verbose mode
func TaskSayHello(t *tasking.T) {
	username := t.Flags.String("name")
	if username == "" {
		user, _ := user.Current()
		username = user.Name
	}

	if t.Flags.Bool("verbose") {
		t.Logf("Hello %s, the time now is %s\n", username, time.Now())
	} else {
		t.Logf("Hello %s\n", username)
	}
}
Пример #16
0
// NAME
//    package - cross compile gh and package it
//
// DESCRIPTION
//    Cross compile gh and package it into PWD/target
func TaskPackage(t *tasking.T) {
	gopath, err := ioutil.TempDir("", "gh-build")
	os.Setenv("GOPATH", gopath)
	t.Logf("GOPATH=%s\n", gopath)

	path := fmt.Sprintf("%s%c%s", filepath.Join(gopath, "bin"), os.PathListSeparator, os.Getenv("PATH"))
	os.Setenv("PATH", path)
	t.Logf("PATH=%s\n", path)

	t.Logf("Packaging for %s...\n", runtime.GOOS)

	t.Log("Installing dependencies...")
	TaskInstallDeps(t)

	pwd, err := os.Getwd()
	if err != nil {
		t.Fatal(err)
	}

	ghPath := filepath.Join(gopath, "src", "github.com", "jingweno", "gh")
	t.Logf("Copying source from %s to %s\n", pwd, ghPath)
	err = copyDir(pwd, ghPath)
	if err != nil {
		t.Fatal(err)
	}
	err = os.Chdir(ghPath)
	if err != nil {
		t.Fatal(err)
	}

	t.Log("Cross-compiling...")
	godepPath := filepath.Join(ghPath, "Godeps", "_workspace")
	gopath = fmt.Sprintf("%s%c%s", gopath, os.PathListSeparator, godepPath)
	os.Setenv("GOPATH", gopath)
	TaskCrossCompile(t)

	source := filepath.Join(ghPath, "target")
	target := filepath.Join(pwd, "target")
	t.Logf("Copying build artifacts from %s to %s...\n", source, target)
	err = mkdirAll(target)
	if err != nil {
		t.Fatal(err)
	}

	err = copyBuildArtifacts(source, target)
	if err != nil {
		t.Fatal(err)
	}
}
Пример #17
0
// Cross-compiles gh for current operating system.
//
// Cross-compiles gh for current operating system. The build artifacts will be in target/VERSION
func TaskCrossCompile(t *tasking.T) {
	t.Log("Updating goxc...")
	err := t.Exec("go get -u github.com/laher/goxc")
	if err != nil {
		t.Errorf("Can't update goxc: %s\n", err)
		return
	}

	t.Logf("Cross-compiling gh for %s...\n", runtime.GOOS)
	err = t.Exec("goxc", "-wd=.", "-os="+runtime.GOOS, "-c="+runtime.GOOS)
	if err != nil {
		t.Errorf("Can't cross-compile gh: %s\n", err)
		return
	}
}
Пример #18
0
// NAME
//    gh-user - Get URL for a given GitHub user login
//
// DESCRIPTION
//    Given a GitHub user login, call the GitHub API to get this user and print out the user page URL.
//
//    For example
//
//    $ gotask git-hub-user jingweno
//
// OPTIONS
//    --verbose, -v
//        run in verbose mode
func TaskGitHubUser(t *tasking.T) {
	if len(t.Args) == 0 {
		t.Error("No GitHub user login is provided!")
		return
	}

	login := t.Args[0]
	data, err := fetchGitHubUser(login)
	if err != nil {
		t.Error(err)
		return
	}

	url, ok := data["html_url"]
	if !ok {
		t.Errorf("No URL found for user login %s\n", login)
		return
	}

	t.Logf("The URL for user %s is %s\n", login, url)
}
Пример #19
0
// Cross-compiles gh for all supported platforms.
//
// Cross-compiles gh for all supported platforms. The build artifacts
// will be in target/VERSION. This only works on darwin with Vagrant setup.
func TaskCrossCompileAll(t *tasking.T) {
	t.Log("Removing build target...")
	err := os.RemoveAll("target")
	if err != nil {
		t.Errorf("Can't remove build target: %s\n", err)
		return
	}

	// for current
	t.Logf("Compiling for %s...\n", runtime.GOOS)
	TaskCrossCompile(t)
	if t.Failed() {
		return
	}

	// for linux
	t.Log("Compiling for linux...")
	err = t.Exec("vagrant ssh -c 'cd ~/src/github.com/jingweno/gh && git pull origin master && gotask cross-compile'")
	if err != nil {
		t.Errorf("Can't compile on linux: %s\n", err)
		return
	}
}
Пример #20
0
// NAME
//   specgen - generates Go code from the UPnP specification files.
//
// DESCRIPTION
//   The specification is available for download from:
//
// OPTIONS
//   -s, --spec_filename=<upnpresources.zip>
//     Path to the specification file, available from http://upnp.org/resources/upnpresources.zip
//   -o, --out_dir=<output directory>
//     Path to the output directory. This is is where the DCP source files will be placed. Should normally correspond to the directory for github.com/huin/goupnp/dcps
//   --nogofmt
//     Disable passing the output through gofmt. Do this if debugging code output problems and needing to see the generated code prior to being passed through gofmt.
func TaskSpecgen(t *tasking.T) {
	specFilename := t.Flags.String("spec-filename")
	if specFilename == "" {
		specFilename = t.Flags.String("s")
	}
	if specFilename == "" {
		t.Fatal("--spec_filename is required")
	}
	outDir := t.Flags.String("out-dir")
	if outDir == "" {
		outDir = t.Flags.String("o")
	}
	if outDir == "" {
		log.Fatal("--out_dir is required")
	}
	useGofmt := !t.Flags.Bool("nogofmt")

	specArchive, err := openZipfile(specFilename)
	if err != nil {
		t.Fatalf("Error opening spec file: %v", err)
	}
	defer specArchive.Close()

	dcpCol := newDcpsCollection()
	for _, f := range globFiles("standardizeddcps/*/*.zip", specArchive.Reader) {
		dirName := strings.TrimPrefix(f.Name, "standardizeddcps/")
		slashIndex := strings.Index(dirName, "/")
		if slashIndex == -1 {
			// Should not happen.
			t.Logf("Could not find / in %q", dirName)
			return
		}
		dirName = dirName[:slashIndex]

		dcp := dcpCol.dcpForDir(dirName)
		if dcp == nil {
			t.Logf("No alias defined for directory %q: skipping %s\n", dirName, f.Name)
			continue
		} else {
			t.Logf("Alias found for directory %q: processing %s\n", dirName, f.Name)
		}

		dcp.processZipFile(f)
	}

	for _, dcp := range dcpCol.dcpByAlias {
		if err := dcp.writePackage(outDir, useGofmt); err != nil {
			log.Printf("Error writing package %q: %v", dcp.Metadata.Name, err)
		}
	}
}
Пример #21
0
// NAME
//	deploy - Run platform-specific deployment routine
//
// DESCRIPTION
// 	Embeds resources, compiles binary, copies related libs and plugins, etc...
//  Distribution-ready application package will be the result of this task.
//	Supported platforms are: darwin, linux, windows.
//
// OPTIONS
//	--verbose, -v
//		Enable some logging
//	--dmg
//		Create an installable dmg (darwin only)
func TaskDeploy(t *tasking.T) {
	deploy, ok := deployers[runtime.GOOS]
	if !ok {
		t.Fatal("deploy: platform unsupported:", runtime.GOOS)
	}

	verbose = t.Flags.Bool("verbose")

	// prepare output path
	path := fmt.Sprintf("%s/%s", outDir, runtime.GOOS)
	if err := os.RemoveAll(path); err != nil {
		t.Fatal(err)
	}
	if err := os.MkdirAll(path, 0755); err != nil {
		t.Fatal(err)
	}
	// gather info
	pkgInfo, err := getPkgInfo()
	if err != nil {
		t.Fatal(err)
	}
	qtInfo, err := getQtInfo()
	if err != nil {
		t.Fatal(err)
	}
	// read deploy profile
	buf, err := ioutil.ReadFile(deployProfileSrc)
	if err != nil {
		t.Fatal(err)
	}
	var profile deployProfile
	err = yaml.Unmarshal(buf, &profile)
	if err != nil {
		t.Fatalf("deploy: profile: %v\n", err)
	} else if verbose {
		t.Log("deploy: profile loaded")
	}
	cfg := config{
		PkgInfo: pkgInfo,
		QtInfo:  qtInfo,
		Path:    path,
		Profile: profile,
	}
	if t.Flags.Bool("verbose") {
		t.Log("deploy: package name:", pkgInfo.Name)
		t.Logf("deploy: qt base: %s (%s)\n", qtInfo.BasePath, qtInfo.Version)
	}
	// embed resources
	if verbose {
		t.Log("deploy: embedding resources")
	}
	if err := exec.Command("rice", "embed-go").Run(); err != nil {
		t.Fatalf("deploy: rice: %v", err)
	}
	// run deployment
	if err := deploy(&cfg, t); err != nil {
		if err := os.RemoveAll(path); err != nil {
			t.Fatal(err)
		}
		t.Fatal(err)
	}
	// clean leftovers
	if err := exec.Command("rice", "clean").Run(); err != nil {
		t.Fatalf("clean: rice: %v", err)
	}
}