|
|
|
@ -15,28 +15,31 @@ import (
|
|
|
|
|
var rootCompilationUID = "65534"
|
|
|
|
|
var rootCompilationGID = "65534"
|
|
|
|
|
|
|
|
|
|
func CompileSourcePackage(archiveFilename, outputFilename string, skipChecks bool) (err error) {
|
|
|
|
|
func CompileSourcePackage(archiveFilename, outputFilename string, skipChecks bool) (outputBpmPackages map[string]string, err error) {
|
|
|
|
|
// Initialize map
|
|
|
|
|
outputBpmPackages = make(map[string]string)
|
|
|
|
|
|
|
|
|
|
// Read BPM archive
|
|
|
|
|
bpmpkg, err := ReadPackage(archiveFilename)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Ensure package type is 'source'
|
|
|
|
|
if bpmpkg.PkgInfo.Type != "source" {
|
|
|
|
|
return errors.New("cannot compile a non-source package")
|
|
|
|
|
return nil, errors.New("cannot compile a non-source package")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Read compilation options file in current directory
|
|
|
|
|
compilationOptions, err := readCompilationOptionsFile()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get HOME directory
|
|
|
|
|
homeDir, err := os.UserHomeDir()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get UID and GID to use for compilation
|
|
|
|
@ -44,11 +47,11 @@ func CompileSourcePackage(archiveFilename, outputFilename string, skipChecks boo
|
|
|
|
|
if os.Getuid() == 0 {
|
|
|
|
|
_uid, err := strconv.ParseInt(rootCompilationUID, 10, 32)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("could not convert UID '%s' to int", rootCompilationUID)
|
|
|
|
|
return nil, fmt.Errorf("could not convert UID '%s' to int", rootCompilationUID)
|
|
|
|
|
}
|
|
|
|
|
_gid, err := strconv.ParseInt(rootCompilationGID, 10, 32)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("could not convert GID '%s' to int", rootCompilationGID)
|
|
|
|
|
return nil, fmt.Errorf("could not convert GID '%s' to int", rootCompilationGID)
|
|
|
|
|
}
|
|
|
|
|
uid = int(_uid)
|
|
|
|
|
gid = int(_gid)
|
|
|
|
@ -63,26 +66,26 @@ func CompileSourcePackage(archiveFilename, outputFilename string, skipChecks boo
|
|
|
|
|
if _, err := os.Stat(tempDirectory); err == nil {
|
|
|
|
|
err := os.RemoveAll(tempDirectory)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Create temporary directory
|
|
|
|
|
err = os.MkdirAll(tempDirectory, 0755)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Change temporary directory owner
|
|
|
|
|
err = os.Chown(tempDirectory, uid, gid)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Extract source.sh file
|
|
|
|
|
err = extractTarballFile(archiveFilename, "source.sh", tempDirectory, uid, gid)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get package scripts and extract them
|
|
|
|
@ -90,26 +93,26 @@ func CompileSourcePackage(archiveFilename, outputFilename string, skipChecks boo
|
|
|
|
|
for _, script := range packageScripts {
|
|
|
|
|
err = extractTarballFile(archiveFilename, script, tempDirectory, uid, gid)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Extract source files
|
|
|
|
|
err = extractTarballDirectory(archiveFilename, "source-files", tempDirectory, uid, gid)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Create source directory
|
|
|
|
|
err = os.Mkdir(path.Join(tempDirectory, "source"), 0755)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Change source directory owner
|
|
|
|
|
err = os.Chown(path.Join(tempDirectory, "source"), uid, gid)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Setup environment for commands
|
|
|
|
@ -145,7 +148,7 @@ func CompileSourcePackage(archiveFilename, outputFilename string, skipChecks boo
|
|
|
|
|
cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(uid), Gid: uint32(gid)}
|
|
|
|
|
err = cmd.Run()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Execute check function in source.sh script if not skipping checks
|
|
|
|
@ -164,129 +167,192 @@ func CompileSourcePackage(archiveFilename, outputFilename string, skipChecks boo
|
|
|
|
|
cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(uid), Gid: uint32(gid)}
|
|
|
|
|
err = cmd.Run()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Remove output directory if it already exists
|
|
|
|
|
if _, err := os.Stat(path.Join(tempDirectory, "output")); err == nil {
|
|
|
|
|
err := os.RemoveAll(path.Join(tempDirectory, "output"))
|
|
|
|
|
// Variable that will be used later
|
|
|
|
|
isSplitPkg := true
|
|
|
|
|
|
|
|
|
|
// Get all packages to compile
|
|
|
|
|
packagesToCompile := bpmpkg.PkgInfo.SplitPackages
|
|
|
|
|
if len(packagesToCompile) == 0 {
|
|
|
|
|
packagesToCompile = append(packagesToCompile, bpmpkg.PkgInfo)
|
|
|
|
|
isSplitPkg = false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Compile each package
|
|
|
|
|
for _, pkg := range packagesToCompile {
|
|
|
|
|
// Get package function name
|
|
|
|
|
packageFunctionName := "package"
|
|
|
|
|
if isSplitPkg {
|
|
|
|
|
packageFunctionName = "package_" + pkg.Name
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Remove output directory if it already exists
|
|
|
|
|
if _, err := os.Stat(path.Join(tempDirectory, "output")); err == nil {
|
|
|
|
|
err := os.RemoveAll(path.Join(tempDirectory, "output"))
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Create new output directory
|
|
|
|
|
err = os.Mkdir(path.Join(tempDirectory, "output"), 0755)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Change output directory owner
|
|
|
|
|
err = os.Chown(path.Join(tempDirectory, "output"), uid, gid)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Execute package function in source.sh script and generate package file list
|
|
|
|
|
cmd = exec.Command("bash", "-c",
|
|
|
|
|
"set -a\n"+ // Source and export functions and variables in source.sh script
|
|
|
|
|
". \"${BPM_WORKDIR}\"/source.sh\n"+
|
|
|
|
|
"set +a\n"+
|
|
|
|
|
"echo \"Running "+packageFunctionName+"() function\"\n"+
|
|
|
|
|
"( cd \"$BPM_SOURCE\" && fakeroot -s \"$BPM_WORKDIR\"/fakeroot_file bash -e -c '"+packageFunctionName+"' ) || exit 1\n"+ // Run package() function
|
|
|
|
|
"fakeroot -i \"$BPM_WORKDIR\"/fakeroot_file find \"$BPM_OUTPUT\" -mindepth 1 -printf \"%P %#m %U %G %s\\n\" > \"$BPM_WORKDIR\"/pkg.files") // Create package file list
|
|
|
|
|
cmd.Dir = tempDirectory
|
|
|
|
|
cmd.Stdout = os.Stdout
|
|
|
|
|
cmd.Stderr = os.Stderr
|
|
|
|
|
cmd.Env = env
|
|
|
|
|
cmd.SysProcAttr = &syscall.SysProcAttr{}
|
|
|
|
|
cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(uid), Gid: uint32(gid)}
|
|
|
|
|
err = cmd.Run()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Create gzip-compressed archive for the package files
|
|
|
|
|
cmd = exec.Command("bash", "-c", "find output -printf \"%P\\n\" | fakeroot -i \"$BPM_WORKDIR\"/fakeroot_file tar -czf files.tar.gz --no-recursion -C output -T -")
|
|
|
|
|
cmd.Dir = tempDirectory
|
|
|
|
|
cmd.Stdout = os.Stdout
|
|
|
|
|
cmd.Stderr = os.Stderr
|
|
|
|
|
cmd.Env = env
|
|
|
|
|
cmd.SysProcAttr = &syscall.SysProcAttr{}
|
|
|
|
|
cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(uid), Gid: uint32(gid)}
|
|
|
|
|
err = cmd.Run()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("files.tar.gz archive could not be created: %s", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Clone source package info
|
|
|
|
|
var pkgInfo PackageInfo
|
|
|
|
|
if !isSplitPkg {
|
|
|
|
|
pkgInfo = *bpmpkg.PkgInfo
|
|
|
|
|
} else {
|
|
|
|
|
pkgInfo = *pkg
|
|
|
|
|
|
|
|
|
|
// Ensure required fields are set
|
|
|
|
|
if strings.TrimSpace(pkgInfo.Name) == "" {
|
|
|
|
|
return nil, fmt.Errorf("split package name is empty")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Copy data from main source package
|
|
|
|
|
if pkgInfo.Description == "" {
|
|
|
|
|
pkgInfo.Description = bpmpkg.PkgInfo.Description
|
|
|
|
|
}
|
|
|
|
|
pkgInfo.Version = bpmpkg.PkgInfo.Version
|
|
|
|
|
pkgInfo.Revision = bpmpkg.PkgInfo.Revision
|
|
|
|
|
pkgInfo.Url = bpmpkg.PkgInfo.Url
|
|
|
|
|
if pkgInfo.License == "" {
|
|
|
|
|
pkgInfo.License = bpmpkg.PkgInfo.License
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Set package type to binary
|
|
|
|
|
pkgInfo.Type = "binary"
|
|
|
|
|
|
|
|
|
|
// Set package architecture
|
|
|
|
|
if val, ok := compilationOptions["ARCH"]; ok {
|
|
|
|
|
pkgInfo.Arch = val
|
|
|
|
|
} else {
|
|
|
|
|
pkgInfo.Arch = GetArch()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Remove source package specific fields
|
|
|
|
|
pkgInfo.MakeDepends = nil
|
|
|
|
|
pkgInfo.SplitPackages = nil
|
|
|
|
|
|
|
|
|
|
// Marshal package info
|
|
|
|
|
pkgInfoBytes, err := yaml.Marshal(pkgInfo)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
pkgInfoBytes = append(pkgInfoBytes, '\n')
|
|
|
|
|
|
|
|
|
|
// Create pkg.info file
|
|
|
|
|
err = os.WriteFile(path.Join(tempDirectory, "pkg.info"), pkgInfoBytes, 0644)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Change pkg.info file owner
|
|
|
|
|
err = os.Chown(path.Join(tempDirectory, "pkg.info"), uid, gid)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get files to include in BPM archive
|
|
|
|
|
bpmArchiveFiles := make([]string, 0)
|
|
|
|
|
bpmArchiveFiles = append(bpmArchiveFiles, "pkg.info", "pkg.files", "files.tar.gz") // Base files
|
|
|
|
|
bpmArchiveFiles = append(bpmArchiveFiles, packageScripts...) // Package scripts
|
|
|
|
|
|
|
|
|
|
// Create final BPM archive
|
|
|
|
|
cmd = exec.Command("bash", "-c", "tar -cf final-archive.bpm --owner=0 --group=0 -C \"$BPM_WORKDIR\" "+strings.Join(bpmArchiveFiles, " "))
|
|
|
|
|
cmd.Dir = tempDirectory
|
|
|
|
|
cmd.Stdout = os.Stdout
|
|
|
|
|
cmd.Stderr = os.Stderr
|
|
|
|
|
currentDir, err := os.Getwd()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
cmd.Env = append(env, "CURRENT_DIR="+currentDir)
|
|
|
|
|
cmd.SysProcAttr = &syscall.SysProcAttr{}
|
|
|
|
|
cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(uid), Gid: uint32(gid)}
|
|
|
|
|
err = cmd.Run()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("BPM archive could not be created: %s", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Remove pkg.info file
|
|
|
|
|
err = os.Remove(path.Join(tempDirectory, "pkg.info"))
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Set output filename if split package
|
|
|
|
|
if len(bpmpkg.PkgInfo.SplitPackages) != 1 {
|
|
|
|
|
// Get current working directory
|
|
|
|
|
workdir, err := os.Getwd()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("could not get working directory: %s", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
outputFilename = path.Join(workdir, fmt.Sprintf("%s-%s-%d.bpm", pkgInfo.Name, pkgInfo.Version, pkgInfo.Revision))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Move final BPM archive
|
|
|
|
|
err = os.Rename(path.Join(tempDirectory, "final-archive.bpm"), outputFilename)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Set final BPM archive owner
|
|
|
|
|
err = os.Chown(outputFilename, os.Getuid(), os.Getgid())
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
outputBpmPackages[pkgInfo.Name] = outputFilename
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Create new output directory
|
|
|
|
|
err = os.Mkdir(path.Join(tempDirectory, "output"), 0755)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Change output directory owner
|
|
|
|
|
err = os.Chown(path.Join(tempDirectory, "output"), uid, gid)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Execute package function in source.sh script and generate package file list
|
|
|
|
|
cmd = exec.Command("bash", "-c",
|
|
|
|
|
"set -a\n"+ // Source and export functions and variables in source.sh script
|
|
|
|
|
". \"${BPM_WORKDIR}\"/source.sh\n"+
|
|
|
|
|
"set +a\n"+
|
|
|
|
|
"echo \"Running package() function\"\n"+
|
|
|
|
|
"( cd \"$BPM_SOURCE\" && fakeroot -s \"$BPM_WORKDIR\"/fakeroot_file bash -e -c 'package' ) || exit 1\n"+ // Run package() function
|
|
|
|
|
"fakeroot -i \"$BPM_WORKDIR\"/fakeroot_file find \"$BPM_OUTPUT\" -mindepth 1 -printf \"%P %#m %U %G %s\\n\" > \"$BPM_WORKDIR\"/pkg.files") // Create package file list
|
|
|
|
|
cmd.Dir = tempDirectory
|
|
|
|
|
cmd.Stdout = os.Stdout
|
|
|
|
|
cmd.Stderr = os.Stderr
|
|
|
|
|
cmd.Env = env
|
|
|
|
|
cmd.SysProcAttr = &syscall.SysProcAttr{}
|
|
|
|
|
cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(uid), Gid: uint32(gid)}
|
|
|
|
|
err = cmd.Run()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Create gzip-compressed archive for the package files
|
|
|
|
|
cmd = exec.Command("bash", "-c", "find output -printf \"%P\\n\" | fakeroot -i \"$BPM_WORKDIR\"/fakeroot_file tar -czf files.tar.gz --no-recursion -C output -T -")
|
|
|
|
|
cmd.Dir = tempDirectory
|
|
|
|
|
cmd.Stdout = os.Stdout
|
|
|
|
|
cmd.Stderr = os.Stderr
|
|
|
|
|
cmd.Env = env
|
|
|
|
|
cmd.SysProcAttr = &syscall.SysProcAttr{}
|
|
|
|
|
cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(uid), Gid: uint32(gid)}
|
|
|
|
|
err = cmd.Run()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("files.tar.gz archive could not be created: %s", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Copy pkgInfo struct
|
|
|
|
|
pkgInfo := bpmpkg.PkgInfo
|
|
|
|
|
|
|
|
|
|
// Set package type to binary
|
|
|
|
|
pkgInfo.Type = "binary"
|
|
|
|
|
|
|
|
|
|
// Set package architecture
|
|
|
|
|
if val, ok := compilationOptions["ARCH"]; ok {
|
|
|
|
|
pkgInfo.Arch = val
|
|
|
|
|
} else {
|
|
|
|
|
pkgInfo.Arch = GetArch()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Marshal package info
|
|
|
|
|
pkgInfoBytes, err := yaml.Marshal(pkgInfo)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
pkgInfoBytes = append(pkgInfoBytes, '\n')
|
|
|
|
|
|
|
|
|
|
// Create pkg.info file
|
|
|
|
|
err = os.WriteFile(path.Join(tempDirectory, "pkg.info"), pkgInfoBytes, 0644)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Change pkg.info file owner
|
|
|
|
|
err = os.Chown(path.Join(tempDirectory, "pkg.info"), uid, gid)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get files to include in BPM archive
|
|
|
|
|
bpmArchiveFiles := make([]string, 0)
|
|
|
|
|
bpmArchiveFiles = append(bpmArchiveFiles, "pkg.info", "pkg.files", "files.tar.gz") // Base files
|
|
|
|
|
bpmArchiveFiles = append(bpmArchiveFiles, packageScripts...) // Package scripts
|
|
|
|
|
|
|
|
|
|
// Create final BPM archive
|
|
|
|
|
cmd = exec.Command("bash", "-c", "tar -cf final-archive.bpm --owner=0 --group=0 -C \"$BPM_WORKDIR\" "+strings.Join(bpmArchiveFiles, " "))
|
|
|
|
|
cmd.Dir = tempDirectory
|
|
|
|
|
cmd.Stdout = os.Stdout
|
|
|
|
|
cmd.Stderr = os.Stderr
|
|
|
|
|
currentDir, err := os.Getwd()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
cmd.Env = append(env, "CURRENT_DIR="+currentDir)
|
|
|
|
|
cmd.SysProcAttr = &syscall.SysProcAttr{}
|
|
|
|
|
cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(uid), Gid: uint32(gid)}
|
|
|
|
|
err = cmd.Run()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("BPM archive could not be created: %s", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Move final BPM archive
|
|
|
|
|
err = os.Rename(path.Join(tempDirectory, "final-archive.bpm"), outputFilename)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Set final BPM archive owner
|
|
|
|
|
err = os.Chown(outputFilename, os.Getuid(), os.Getgid())
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
return outputBpmPackages, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func readCompilationOptionsFile() (options map[string]string, err error) {
|
|
|
|
|