示例#1
0
func Example_genBinaryPackage() {

	ctrl := deb.NewControlDefault("testpkg", "me", "<*****@*****.**>", "Dummy package for doing nothing", "testpkg is a dummy package", true)
	for _, pkg := range ctrl.BinaryParas() {
		pkg.Set(deb.VersionFName, "0.0.2")
	}
	build := debgen.NewBuildParams()
	build.Init()
	build.IsRmtemp = false
	artifacts, err := deb.NewWriters(ctrl)
	if err != nil {
		log.Fatalf("Error building binary: %v", err)
	}
	artifacts[deb.ArchAmd64].MappedFiles = map[string]string{"/usr/bin/a": "_out/a.amd64"}
	artifacts[deb.ArchI386].MappedFiles = map[string]string{"/usr/bin/a": "_out/a.i386"}
	artifacts[deb.ArchArmhf].MappedFiles = map[string]string{"/usr/bin/a": "_out/a.armhf"}

	prep() //prepare files for packaging using some other means.

	for arch, artifact := range artifacts {
		log.Printf("generating artifact '%s'/%v", arch, artifact)
		dgen := debgen.NewDebGenerator(artifact, build)
		err = dgen.GenerateAllDefault()
		if err != nil {
			log.Fatalf("Error building for '%s': %v", arch, err)
		}
	}

	// Output:
	//
}
示例#2
0
func Example_genDevPackage() {
	ctrl := deb.NewControlDefault("testpkg", "me", "me@a", "Dummy package for doing nothing", "testpkg is package ", true)

	spara := ctrl.GetParasByField(deb.SourceFName, "testpkg")
	bpara := ctrl.GetParasByField(deb.PackageFName, "testpkg-dev")
	nctrl := &deb.Control{spara[0], bpara[0]}

	build := debgen.NewBuildParams()
	build.IsRmtemp = false
	build.Init()
	var err error
	mappedFiles, err := debgen.GlobForGoSources(".", []string{build.TmpDir, build.DestDir})
	if err != nil {
		log.Fatalf("Error building -dev: %v", err)
	}

	artifacts, err := deb.NewWriters(nctrl)
	if err != nil {
		log.Fatalf("Error building -dev: %v", err)
	}
	for _, artifact := range artifacts {
		dgen := debgen.NewDebGenerator(artifact, build)
		dgen.DataFiles = mappedFiles
		err = dgen.GenerateAllDefault()
		if err != nil {
			log.Fatalf("Error building -dev: %v", err)
		}
	}

	// Output:
	//
}
示例#3
0
func Example_genSourcePackage() {
	ctrl := deb.NewControlDefault("testpkg", "me", "me@a", "Dummy package for doing nothing", "testpkg is package ", true)

	build := debgen.NewBuildParams()
	build.IsRmtemp = false
	debgen.ApplyGoDefaults(ctrl)
	spkg := deb.NewSourcePackage(ctrl)
	err := build.Init()
	if err != nil {
		log.Fatalf("Error initializing dirs: %v", err)
	}
	spgen := debgen.NewSourcePackageGenerator(spkg, build)
	spgen.ApplyDefaultsPureGo()
	sourcesDestinationDir := ctrl.Get(deb.SourceFName) + "_" + ctrl.Get(deb.VersionFName)
	sourceDir := ".."
	sourcesRelativeTo := debgen.GetGoPathElement(sourceDir)
	spgen.OrigFiles, err = debgen.GlobForSources(sourcesRelativeTo, sourceDir, debgen.GlobGoSources, sourcesDestinationDir, []string{build.TmpDir, build.DestDir})
	if err != nil {
		log.Fatalf("Error resolving sources: %v", err)
	}
	err = spgen.GenerateAllDefault()

	if err != nil {
		log.Fatalf("Error building source: %v", err)
	}

	// Output:
	//
}
示例#4
0
//Adds an entry to the changelog
func changelogAddEntryTask(args []string) error {
	build := debgen.NewBuildParams()
	fs := InitBuildFlags(cmdName+" "+TaskChangelogAdd, build)
	var version string
	fs.StringVar(&version, "version", "", "Package Version")
	var architecture string
	fs.StringVar(&architecture, "arch", "all", "Architectures [any,386,armhf,amd64,all]")
	var distribution string
	fs.StringVar(&distribution, "distribution", "unstable", "Distribution (unstable is recommended until Debian accept the package into testing/stable)")
	var entry string
	fs.StringVar(&entry, "entry", "", "Changelog entry data")

	err := fs.Parse(os.Args[2:])
	if err != nil {
		return fmt.Errorf("Error parsing %v", err)
	}
	if version == "" {
		return fmt.Errorf("Error: --version is a required flag")
	}
	if entry == "" {
		return fmt.Errorf("Error: --entry is a required flag")
	}
	ctrl, err := changelogPrepareCtrl(version, distribution, architecture, build)
	if err != nil {
		return err
	}
	return changelogAddEntry(ctrl, build, entry)
}
示例#5
0
func sourceGen(input []string) error {
	build := debgen.NewBuildParams()
	fs := InitBuildFlags(cmdName+" "+TaskGenSource, build)
	var sourceDir string
	fs.StringVar(&sourceDir, "sources", ".", "source dir")
	var isDiscoverGoPath bool
	fs.BoolVar(&isDiscoverGoPath, "discover-gopath", true, "Use Go-style path (try to discover base relative to GOPATH element)")
	var sourcesGlob string
	fs.StringVar(&sourcesGlob, "sources-glob", debgen.GlobGoSources, "Glob for inclusion of sources")
	var destinationDir string
	fs.StringVar(&destinationDir, "destination-dir", debgen.DevGoPathDefault, "Directory name to store sources in archive")
	var sourcesRelativeTo string
	fs.StringVar(&sourcesRelativeTo, "sources-relative-to", ".", "Sources relative to (this is ignored when -discover-gopath is selected)")
	fs.StringVar(&build.Version, "version", "", "Package version")

	// parse and validate flags
	err := fs.Parse(os.Args[2:])
	if err != nil {
		return fmt.Errorf("%v", err)
	}
	if build.Version == "" {
		return fmt.Errorf("Error: --version is a required flag")
	}
	if isDiscoverGoPath {
		sourcesRelativeTo = debgen.GetGoPathElement(sourceDir)
	}
	mappedSources, err := debgen.GlobForSources(sourcesRelativeTo, sourceDir, sourcesGlob, destinationDir, []string{build.TmpDir, build.DebianDir})
	if err != nil {
		return fmt.Errorf("%v", err)
	}
	fi, err := os.Open(filepath.Join(build.DebianDir, "control"))
	if err != nil {
		return fmt.Errorf("%v", err)
	}

	cfr := deb.NewControlFileReader(fi)
	ctrl, err := cfr.Parse()
	if err != nil {
		return fmt.Errorf("%v", err)
	}

	spgen, err := debgen.PrepareSourceDebGenerator(ctrl, build)
	for k, v := range mappedSources {
		spgen.OrigFiles[k] = v
	}
	if err != nil {
		return fmt.Errorf("%v", err)
	}
	err = spgen.GenerateAllDefault()
	if err != nil {
		return fmt.Errorf("%v", err)
	}

	return err
}
示例#6
0
func debGen(input []string) error {
	build := debgen.NewBuildParams()
	fs := InitBuildFlags(cmdName+" "+TaskGenDeb, build)
	/*
		fs.StringVar(&build.SourcesGlob, "sources-glob", "**.go", "Glob pattern for sources.")
		fs.StringVar(&build.SourceDir, "sources-dir", ".", "source dir")
		fs.StringVar(&build.SourcesRelativeTo, "sources-relative-to", "", "Sources relative to (it will assume relevant gopath element, unless you specify this)")
		fs.StringVar(&build.Bin386Glob, "bin-386", "*386/*", "Glob pattern for binaries for the 386 platform.")
		fs.StringVar(&build.BinArmhfGlob, "bin-armhf", "*armhf/*", "Glob pattern for binaries for the armhf platform.")
		fs.StringVar(&build.BinAmd64Glob, "bin-amd64", "*amd64/*", "Glob pattern for binaries for the amd64 platform.")
		fs.StringVar(&build.BinAnyGlob, "bin-any", "*any/*", "Glob pattern for binaries for *any* platform.")
	*/
	//fs.StringVar(&build.sourcesDest, "sources-dest", debgen.DevGoPathDefault+"/src", "directory containing sources.")
	arches := ""
	fs.StringVar(&arches, "arch-filter", "", "Filter by Architecture. Comma-separated [386,armhf,amd64,all]")

	//	fs.StringVar(&build.ResourcesGlob, "resources", "", "directory containing resources for this platform")
	fs.StringVar(&build.Version, "version", "", "Package version")
	err := fs.Parse(os.Args[2:])
	if err != nil {
		return fmt.Errorf("Error parsing flags: %v", err)
	}
	build.Arches, err = deb.ResolveArches(arches)
	if err != nil {
		return fmt.Errorf("Error resolving architecture: %v", err)
	}
	//Read control data
	fi, err := os.Open(filepath.Join(build.DebianDir, "control"))
	if err != nil {
		return fmt.Errorf("Error reading control data: %v", err)
	}
	cfr := deb.NewControlFileReader(fi)
	ctrl, err := cfr.Parse()
	if err != nil {
		return fmt.Errorf("Error reading control file: %v", err)
	}
	dgens, err := debgen.PrepareBasicDebGen(ctrl, build)
	if err != nil {
		return fmt.Errorf("Error preparing 'deb generators': %v", err)
	}
	for _, dgen := range dgens {
		err = dgen.GenerateAllDefault()
		if err != nil {
			return fmt.Errorf("Error building deb: %v", err)
		}
	}
	return nil
}
示例#7
0
/*
func checksums(path, name string) (*Checksum, *Checksum, *Checksum, error) {
	//checksums
	f, err := os.Open(path)
	if err != nil {
		return nil, nil, nil, err
	}

	hashMd5 := md5.New()
	size, err := io.Copy(hashMd5, f)
	if err != nil {
		return nil, nil, nil, err
	}
	checksumMd5 := Checksum{hex.EncodeToString(hashMd5.Sum(nil)), size, name}

	f.Seek(int64(0), 0)
	hash256 := sha256.New()
	size, err = io.Copy(hash256, f)
	if err != nil {
		return nil, nil, nil, err
	}
	checksumSha256 := Checksum{hex.EncodeToString(hash256.Sum(nil)), size, name}

	f.Seek(int64(0), 0)
	hash1 := sha1.New()
	size, err = io.Copy(hash1, f)
	if err != nil {
		return nil, nil, nil, err
	}
	checksumSha1 := Checksum{hex.EncodeToString(hash1.Sum(nil)), size, name}

	err = f.Close()
	if err != nil {
		return nil, nil, nil, err
	}

	return &checksumMd5, &checksumSha1, &checksumSha256, nil

}
*/
func debSourceBuild(tp TaskParams) (err error) {
	metadata := tp.Settings.GetTaskSettingMap(TASK_DEB_SOURCE, "metadata")
	//armArchName := getArmArchName(tp.Settings)
	metadataDebX := tp.Settings.GetTaskSettingMap(TASK_DEB_SOURCE, "metadata-deb")
	otherMappedFilesFromSetting := tp.Settings.GetTaskSettingMap(TASK_DEB_GEN, "other-mapped-files")
	otherMappedFiles, err := calcOtherMappedFiles(otherMappedFilesFromSetting)
	if err != nil {
		return err
	}
	metadataDeb := map[string]string{}
	for k, v := range metadataDebX {
		val, ok := v.(string)
		if ok {
			metadataDeb[k] = val
		}
	}
	rmtemp := tp.Settings.GetTaskSettingBool(TASK_DEB_SOURCE, "rmtemp")
	debDir := filepath.Join(tp.OutDestRoot, tp.Settings.GetFullVersionName()) //v0.8.1 dont use platform dir
	tmpDir := filepath.Join(debDir, ".goxc-temp")

	shortDescription := "?"
	if desc, keyExists := metadata["description"]; keyExists {
		var err error
		shortDescription, err = typeutils.ToString(desc, "description")
		if err != nil {
			return err
		}
	}
	longDescription := " "
	if ldesc, keyExists := metadata["long-description"]; keyExists {
		var err error
		longDescription, err = typeutils.ToString(ldesc, "long-description")
		if err != nil {
			return err
		}
	}
	maintainerName := "?"
	if maint, keyExists := metadata["maintainer"]; keyExists {
		var err error
		maintainerName, err = typeutils.ToString(maint, "maintainer")
		if err != nil {
			return err
		}
	}
	maintainerEmail := "*****@*****.**"
	if maintEmail, keyExists := metadata["maintainer-email"]; keyExists {
		var err error
		maintainerEmail, err = typeutils.ToString(maintEmail, "maintainer-email")
		if err != nil {
			return err
		}
	}

	build := debgen.NewBuildParams()
	build.DestDir = debDir
	build.TmpDir = tmpDir
	build.Init()
	build.IsRmtemp = rmtemp
	var ctrl *deb.Control
	//Read control data. If control file doesnt exist, use parameters ...
	fi, err := os.Open(filepath.Join(build.DebianDir, "control"))
	if os.IsNotExist(err) {
		log.Printf("WARNING - no debian 'control' file found. Use `debber` to generate proper debian metadata")
		ctrl = deb.NewControlDefault(tp.AppName, maintainerName, maintainerEmail, shortDescription, longDescription, false)
	} else if err != nil {
		return fmt.Errorf("%v", err)
	} else {
		cfr := deb.NewControlFileReader(fi)
		ctrl, err = cfr.Parse()
		if err != nil {
			return fmt.Errorf("%v", err)
		}
	}
	goSourcesDir := tp.Settings.GetTaskSettingString(TASK_DEB_SOURCE, "go-sources-dir")
	mappedSources, err := debgen.GlobForGoSources(goSourcesDir, []string{build.DestDir, build.TmpDir})
	if err != nil {
		return fmt.Errorf("%v", err)
	}
	for k, v := range mappedSources {
		otherMappedFiles[k] = v
	}
	build.Version = tp.Settings.GetFullVersionName()
	spgen, err := debgen.PrepareSourceDebGenerator(ctrl, build)
	if spgen.OrigFiles == nil {
		spgen.OrigFiles = map[string]string{}
	}
	for k, v := range otherMappedFiles {
		spgen.OrigFiles[k] = v
	}
	if err != nil {
		return fmt.Errorf("%v", err)
	}
	err = spgen.GenerateAllDefault()
	if err != nil {
		return fmt.Errorf("%v", err)
	}
	if tp.Settings.IsVerbose() {
		log.Printf("Wrote dsc file to %s", filepath.Join(build.DestDir, spgen.SourcePackage.DscFileName))
		log.Printf("Wrote orig file to %s", filepath.Join(build.DestDir, spgen.SourcePackage.OrigFileName))
		log.Printf("Wrote debian file to %s", filepath.Join(build.DestDir, spgen.SourcePackage.DebianFileName))
	}
	return nil
}
示例#8
0
func debBuild(dest platforms.Platform, tp TaskParams) error {
	metadata := tp.Settings.GetTaskSettingMap(TASK_DEB_GEN, "metadata")
	armArchName := getArmArchName(tp.Settings)
	//maintain support for old configs ...
	metadataDebX := tp.Settings.GetTaskSettingMap(TASK_DEB_GEN, "metadata-deb")
	otherMappedFilesFromSetting := tp.Settings.GetTaskSettingMap(TASK_DEB_GEN, "other-mapped-files")
	otherMappedFiles, err := calcOtherMappedFiles(otherMappedFilesFromSetting)
	if err != nil {
		return err
	}

	if tp.Settings.IsVerbose() {
		log.Printf("other mapped files: %+v", otherMappedFiles)
	}
	metadataDeb := map[string]string{}
	for k, v := range metadataDebX {
		val, ok := v.(string)
		if ok {
			metadataDeb[k] = val
		}
	}
	rmtemp := tp.Settings.GetTaskSettingBool(TASK_DEB_GEN, "rmtemp")
	debDir := filepath.Join(tp.OutDestRoot, tp.Settings.GetFullVersionName()) //v0.8.1 dont use platform dir
	tmpDir := filepath.Join(debDir, ".goxc-temp")

	shortDescription := "?"
	if desc, keyExists := metadata["description"]; keyExists {
		var err error
		shortDescription, err = typeutils.ToString(desc, "description")
		if err != nil {
			return err
		}
	}
	longDescription := " "
	if ldesc, keyExists := metadata["long-description"]; keyExists {
		var err error
		longDescription, err = typeutils.ToString(ldesc, "long-description")
		if err != nil {
			return err
		}
	}
	maintainerName := "?"
	if maint, keyExists := metadata["maintainer"]; keyExists {
		var err error
		maintainerName, err = typeutils.ToString(maint, "maintainer")
		if err != nil {
			return err
		}
	}
	maintainerEmail := "*****@*****.**"
	if maintEmail, keyExists := metadata["maintainer-email"]; keyExists {
		var err error
		maintainerEmail, err = typeutils.ToString(maintEmail, "maintainer-email")
		if err != nil {
			return err
		}
	}
	//'dev' Package should be a separate task
	addDevPackage := false
	/*
		pkg := deb.NewPackage(tp.AppName, tp.Settings.GetFullVersionName(), maintainer, description)
		pkg.AdditionalControlData = metadataDeb*/

	build := debgen.NewBuildParams()
	build.DestDir = debDir
	build.TmpDir = tmpDir
	build.Init()
	build.IsRmtemp = rmtemp
	var ctrl *deb.Control
	//Read control data. If control file doesnt exist, use parameters ...
	fi, err := os.Open(filepath.Join(build.DebianDir, "control"))
	if os.IsNotExist(err) {
		log.Printf("WARNING - no debian 'control' file found. Use `debber` to generate proper debian metadata")
		ctrl = deb.NewControlDefault(tp.AppName, maintainerName, maintainerEmail, shortDescription, longDescription, addDevPackage)
	} else if err != nil {
		return fmt.Errorf("%v", err)
	} else {
		cfr := deb.NewControlFileReader(fi)
		ctrl, err = cfr.Parse()
		if err != nil {
			return fmt.Errorf("%v", err)
		}
	}
	debArch := getDebArch(dest.Arch, armArchName)
	build.Arches = []deb.Architecture{debArch}
	build.Version = tp.Settings.GetFullVersionName()
	dgens, err := debgen.PrepareBasicDebGen(ctrl, build)
	if err != nil {
		return fmt.Errorf("Error preparing deb generator: %v", err)
	}
	//there should only be one for this platform.
	// Anyway this part maps all binaries.
	for _, dgen := range dgens {
		// -dev paragraphs handled by 'deb-dev' task.
		if !strings.HasSuffix(dgen.DebWriter.Control.Get(deb.PackageFName), "-dev") {
			for _, mainDir := range tp.MainDirs {
				var exeName string
				if len(tp.MainDirs) == 1 {
					exeName = tp.Settings.AppName
				} else {
					exeName = filepath.Base(mainDir)
				}
				binPath, err := core.GetAbsoluteBin(dest.Os, dest.Arch, tp.Settings.AppName, exeName, tp.WorkingDirectory, tp.Settings.GetFullVersionName(), tp.Settings.OutPath, tp.Settings.ArtifactsDest)
				if err != nil {
					return err
				}
				if dgen.DataFiles == nil {
					dgen.DataFiles = map[string]string{}
				}
				dgen.DataFiles["./usr/bin/"+exeName] = binPath
			}
			for k, v := range otherMappedFiles {
				dgen.DataFiles[k] = v
			}
			err = dgen.GenerateAllDefault()
			if err != nil {
				return fmt.Errorf("Error generating deb: %v", err)
			}
			if !tp.Settings.IsQuiet() {
				log.Printf("Wrote deb to %s", filepath.Join(build.DestDir, dgen.DebWriter.Filename))
			}
		}
	}
	return err

}
示例#9
0
文件: deb-dev.go 项目: boldfield/goxc
func debDevBuild(tp TaskParams) error {
	metadata := tp.Settings.GetTaskSettingMap(TASK_DEB_GEN, "metadata")
	//maintain support for old configs ...
	metadataDebX := tp.Settings.GetTaskSettingMap(TASK_DEB_GEN, "metadata-deb")
	otherMappedFilesFromSetting := tp.Settings.GetTaskSettingMap(TASK_DEB_GEN, "other-mapped-files")
	otherMappedFiles, err := calcOtherMappedFiles(otherMappedFilesFromSetting)
	if err != nil {
		return err
	}
	metadataDeb := map[string]string{}
	for k, v := range metadataDebX {
		val, ok := v.(string)
		if ok {
			metadataDeb[k] = val
		}
	}
	rmtemp := tp.Settings.GetTaskSettingBool(TASK_DEB_GEN, "rmtemp")
	debDir := filepath.Join(tp.OutDestRoot, tp.Settings.GetFullVersionName()) //v0.8.1 dont use platform dir
	tmpDir := filepath.Join(debDir, ".goxc-temp")

	shortDescription := "?"
	if desc, keyExists := metadata["description"]; keyExists {
		var err error
		shortDescription, err = typeutils.ToString(desc, "description")
		if err != nil {
			return err
		}
	}
	longDescription := " "
	if ldesc, keyExists := metadata["long-description"]; keyExists {
		var err error
		longDescription, err = typeutils.ToString(ldesc, "long-description")
		if err != nil {
			return err
		}
	}
	maintainerName := "?"
	if maint, keyExists := metadata["maintainer"]; keyExists {
		var err error
		maintainerName, err = typeutils.ToString(maint, "maintainer")
		if err != nil {
			return err
		}
	}
	maintainerEmail := "*****@*****.**"
	if maintEmail, keyExists := metadata["maintainer-email"]; keyExists {
		var err error
		maintainerEmail, err = typeutils.ToString(maintEmail, "maintainer-email")
		if err != nil {
			return err
		}
	}
	//'dev' Package should be a separate task
	addDevPackage := false
	/*
		pkg := deb.NewPackage(tp.AppName, tp.Settings.GetFullVersionName(), maintainer, description)
		pkg.AdditionalControlData = metadataDeb*/

	build := debgen.NewBuildParams()
	build.DestDir = debDir
	build.TmpDir = tmpDir
	build.Init()
	build.IsRmtemp = rmtemp
	var ctrl *deb.Control
	//Read control data. If control file doesnt exist, use parameters ...
	fi, err := os.Open(filepath.Join(build.DebianDir, "control"))
	if os.IsNotExist(err) {
		log.Printf("WARNING - no debian 'control' file found. Use `debber` to generate proper debian metadata")
		ctrl = deb.NewControlDefault(tp.AppName, maintainerName, maintainerEmail, shortDescription, longDescription, addDevPackage)
	} else if err != nil {
		return fmt.Errorf("%v", err)
	} else {
		cfr := deb.NewControlFileReader(fi)
		ctrl, err = cfr.Parse()
		if err != nil {
			return fmt.Errorf("%v", err)
		}
	}
	goSourcesDir := tp.Settings.GetTaskSettingString(TASK_DEB_GEN, "go-sources-dir")
	mappedSources, err := debgen.GlobForGoSources(goSourcesDir, []string{build.DestDir, build.TmpDir})
	if err != nil {
		return fmt.Errorf("%v", err)
	}
	for k, v := range mappedSources {
		otherMappedFiles[k] = v
	}
	debArch := deb.ArchAll
	build.Arches = []deb.Architecture{debArch}
	build.Version = tp.Settings.GetFullVersionName()
	dgens, err := debgen.PrepareBasicDebGen(ctrl, build)
	if err != nil {
		return fmt.Errorf("Error preparing deb generator: %v", err)
	}
	//there should only be one for this platform.
	// Anyway this part maps all binaries.
	for _, dgen := range dgens {
		if strings.HasSuffix(dgen.DebWriter.Control.Get(deb.PackageFName), "-dev") {
			for k, v := range otherMappedFiles {
				dgen.DataFiles[k] = v
			}
			err = dgen.GenerateAllDefault()
			if err != nil {
				return fmt.Errorf("Error generating deb: %v", err)
			}
			if !tp.Settings.IsQuiet() {
				log.Printf("Wrote -dev deb to %s", filepath.Join(build.DestDir, dgen.DebWriter.Filename))
			}
		}
	}
	return err

}
示例#10
0
func initDebber(input []string) error {
	//set to nothing
	ctrl := deb.NewControlEmpty()
	build := debgen.NewBuildParams()
	build.DestDir = "debian"
	fs := InitBuildFlags(cmdName+" init", build)
	var entry string
	var overwrite bool
	var flavour string
	var pkgName, maintainerName, maintainerEmail, shortDescription, longDescription, architecture string
	var license string
	fs.StringVar(&pkgName, "name", "", "Package name [required]")
	fs.StringVar(&maintainerName, "maintainer", "", "Maintainer name [required]")
	fs.StringVar(&maintainerEmail, "maintainer-email", "", "Maintainer's email address [required]")
	fs.StringVar(&shortDescription, "desc", "", "Package description [required]")
	fs.StringVar(&longDescription, "long-desc", "", "Package Long description")
	fs.StringVar(&entry, "entry", "Initial project import", "Changelog entry data")
	fs.BoolVar(&overwrite, "overwrite", false, "Overwrite existing files")
	fs.StringVar(&architecture, "architecture", "any", "Package Architecture (any)")
	fs.StringVar(&license, "license", "BSD-3-clause", "License")
	fs.StringVar(&flavour, "flav", "go:exe", "'flavour' implies a set of defaults - currently, one of 'go:exe', 'go:pkg', 'dev' or ''")
	//TODO flavour
	err := fs.Parse(os.Args[2:])
	if err != nil {
		return fmt.Errorf("%v", err)
	}
	if pkgName == "" || maintainerName == "" || maintainerEmail == "" || shortDescription == "" || longDescription == "" {
		return fmt.Errorf("Required fields: --name, --maintainer, --maintainer-email, --desc, --long-desc")
	}
	//handle spaces in longDescription. TODO: utility function
	longDescriptions := strings.Split(longDescription, "\n")
	longDescription = ""
	for _, ldl := range longDescriptions {
		if longDescription != "" {
			longDescription += "\n"
		}
		longDescription += " " + strings.TrimSpace(ldl)
	}
	(*ctrl)[0].Set(deb.SourceFName, pkgName)
	(*ctrl)[0].Set(deb.MaintainerFName, fmt.Sprintf("%s <%s>", maintainerName, maintainerEmail))
	(*ctrl)[0].Set(deb.DescriptionFName, fmt.Sprintf("%s\n%s", shortDescription, longDescription))
	(*ctrl)[0].Set(deb.ArchitectureFName, architecture)
	if len(*ctrl) < 2 {
		*ctrl = append(*ctrl, deb.NewPackage())
	}
	(*ctrl)[1].Set(deb.PackageFName, pkgName)
	(*ctrl)[1].Set(deb.DescriptionFName, fmt.Sprintf("%s\n%s", shortDescription, longDescription))
	(*ctrl)[1].Set(deb.ArchitectureFName, architecture)
	//-dev package. Optional somehow?
	if len(*ctrl) < 3 {
		*ctrl = append(*ctrl, deb.NewPackage())
	}
	(*ctrl)[2].Set(deb.PackageFName, pkgName+"-dev")
	(*ctrl)[2].Set(deb.ArchitectureFName, "all")
	(*ctrl)[2].Set(deb.DescriptionFName, fmt.Sprintf("%s - development package\n%s", shortDescription, longDescription))
	deb.SetDefaults(ctrl)
	if strings.HasPrefix(flavour, "go:") {
		debgen.ApplyGoDefaults(ctrl)
	} else {
		debgen.ApplyBasicDefaults(ctrl)
	}
	if err == nil {
		//validation ...
		err = deb.ValidateControl(ctrl)
		if err != nil {
			println("")
			fmt.Fprintf(os.Stderr, "Usage:\n")
			fs.PrintDefaults()
			println("")
		}
	}
	if err != nil {
		return fmt.Errorf("%v", err)
	}
	err = build.Init()
	if err != nil {
		return fmt.Errorf("Error initialising build: %v", err)
	}

	spkg := deb.NewSourcePackage(ctrl)
	spgen := debgen.NewSourcePackageGenerator(spkg, build)
	if flavour == "go:exe" {
		spgen.ApplyDefaultsPureGo()
	}

	//create control file
	filename := filepath.Join(build.DebianDir, "control")
	_, err = os.Stat(filename)
	if os.IsNotExist(err) || overwrite {
		err = spgen.GenSourceControlFile()
		if err != nil {
			return fmt.Errorf("Error generating control file: %v", err)
		}
	} else if err != nil {
		return fmt.Errorf("Error generating control file: %v", err)
	} else {
		log.Printf("%s already exists", filename)
	}

	//changelog file
	filename = filepath.Join(build.DebianDir, "changelog")
	_, err = os.Stat(filename)
	if os.IsNotExist(err) || overwrite {
		changelogAddEntry(ctrl, build, entry)
	} else if err != nil {
		return fmt.Errorf("Error reading existing changelog: %v", err)
	} else {
		log.Printf("%s already exists", filename)
	}

	//copyright file
	filename = filepath.Join(build.DebianDir, "copyright")
	_, err = os.Stat(filename)
	if os.IsNotExist(err) || overwrite {
		err = copyrightInit(ctrl, build, license)
		if err != nil {
			return err
		}
	} else if err != nil {
		return fmt.Errorf("Error reading existing copyright file: %v", err)
	} else {
		log.Printf("%s already exists", filename)
	}

	//rules file ...
	filename = filepath.Join(build.DebianDir, "rules")
	_, err = os.Stat(filename)
	if os.IsNotExist(err) || overwrite {
		templateVars := debgen.NewTemplateData(ctrl)
		tpl, err := template.New("template").Parse(spgen.TemplateStrings["rules"])
		if err != nil {
			return fmt.Errorf("Error parsing template: %v", err)
		}
		//create ..
		f, err := os.Create(filename)
		if err != nil {
			return fmt.Errorf("Error creating file: %v", err)
		}
		defer f.Close()
		err = tpl.Execute(f, templateVars)
		if err != nil {
			return fmt.Errorf("Error executing template: %v", err)
		}
		err = f.Close()
		if err != nil {
			return fmt.Errorf("Error closing written file: %v", err)
		}
	} else if err != nil {
		return fmt.Errorf("Error reading existing rules file: %v", err)
	} else {
		log.Printf("%s already exists", filename)
	}
	return nil
}