Added a $BPM_PKG_ARCH variable to source script

Added a "keep" field to package descriptor files which will prevent the specified files from being overwritten
Completely revamped the bpm-setup script in the bpm-utils package
This commit is contained in:
CapCreeperGR 2024-04-23 17:27:34 +03:00
parent d086b4a639
commit e75d2fb1da
10 changed files with 198 additions and 165 deletions

View File

@ -52,44 +52,37 @@ bpm help
Creating a package for BPM is simple
To create a package you need to
1) Create a working directory
1) Make sure you have installed the bpm-utils package from the test-packages directory in the repository
2) Run the following command (You can run the comamnd with no arguments to see available options)
```
mkdir my_bpm_package
bpm-setup -D my_bpm_package -t <binary/source>
```
2) Create a pkg.info file following this format (You can find examples in the test_packages directory)
3) This will create a directory named 'my_bpm_package' under the current directory with all the required files for the chosen package type
4) You are able to edit the pkg.info descriptor file inside the newly created directory to your liking. Here's an example of what a descriptor file could look like
```
name: my_package
description: My package's description
version: 1.0
architecture: x86_64
url: https://www.my-website.com/ (Optional)
license: MyLicense (Optional)
type: <binary/source>
depends: dependency1,dependency2
make_depends: make_depend1,make_depend2
depends: dependency1,dependency2 (Optional)
make_depends: make_depend1,make_depend2 (Optional)
```
depends and make depends are optional fields, you may skip them if you'd like
### Binary Packages
3) If you are making a binary package, simply create a 'files' directory
3) If you are making a binary package, copy all your binaries along with the directories they reside in (i.e files/usr/bin/my_binary)
6) Run the following to create a package archive
```
mkdir files
```
4) Copy all your binaries along with the directories they reside in (i.e files/usr/bin/my_binary)
5) Either copy the bpm-create script from the bpm-utils test package into your /usr/local/bin directory or install the bpm-utils.bpm package
6) Run the following
```
bpm-create <filename.bpm>
bpm-package <filename.bpm>
```
7) It's done! You now hopefully have a working BPM package!
### Source Packages
3) If you are making a source package, you need to create a 'source.sh' file
3) If you would like to bundle patches or other files with your source package place them in the 'source-files' directory. They will be extracted to the same location as the source.sh file during compilation
4) You need to edit your 'source.sh' file, the default source.sh template should explain the basic process of compiling your program
5) Your goal is to download your program's source code with either git, wget, curl, etc. and put the binaries under a folder called 'output' in the root of the temp directory. There is a simple example script with helpful comments in the htop-src test package
6) When you are done making your source.sh script run the following to create a package archive
```
touch source.sh
bpm-package <filename.bpm>
```
4) If you would like to bundle patches or other files with your source package create a 'source-files' directory and place your files in there. They will be extracted to the same location as the source.sh file during compilation
5) You are able to run bash code in source.sh. BPM will extract this file in a directory under /tmp and it will be run there
6) Your goal is to download your program's source code with either git, wget, curl, etc. and put the binaries under a folder called 'output' in the root of the temp directory. There is a simple example script with helpful comments in the htop-src test package
7) When you are done making your source.sh script run the following to create a package archive
```
bpm-create <filename.bpm>
```
8) That's it! Your source package should now be compiling correctly!
7) That's it! Your source package should now be compiling correctly!

View File

@ -25,6 +25,7 @@ type PackageInfo struct {
License string
Arch string
Type string
Keep []string
Depends []string
MakeDepends []string
Provides []string
@ -203,6 +204,7 @@ func ExecutePackageScripts(filename, rootDir string, operation Operation, postOp
cmd.Env = append(cmd.Env, fmt.Sprintf("BPM_PKG_DESC=%s", pkgInfo.Description))
cmd.Env = append(cmd.Env, fmt.Sprintf("BPM_PKG_VERSION=%s", pkgInfo.Version))
cmd.Env = append(cmd.Env, fmt.Sprintf("BPM_PKG_URL=%s", pkgInfo.Url))
cmd.Env = append(cmd.Env, fmt.Sprintf("BPM_PKG_ARCH=%s", pkgInfo.Arch))
depends := make([]string, len(pkgInfo.Depends))
copy(depends, pkgInfo.Depends)
for i := 0; i < len(depends); i++ {
@ -269,6 +271,7 @@ func ReadPackageInfo(contents string, defaultValues bool) (*PackageInfo, error)
License: "",
Arch: "",
Type: "",
Keep: nil,
Depends: nil,
MakeDepends: nil,
Provides: nil,
@ -308,6 +311,9 @@ func ReadPackageInfo(contents string, defaultValues bool) (*PackageInfo, error)
pkgInfo.Arch = split[1]
case "type":
pkgInfo.Type = split[1]
case "keep":
pkgInfo.Keep = strings.Split(strings.Replace(split[1], " ", "", -1), ",")
pkgInfo.Keep = stringSliceRemoveEmpty(pkgInfo.Keep)
case "depends":
pkgInfo.Depends = strings.Split(strings.Replace(split[1], " ", "", -1), ",")
pkgInfo.Depends = stringSliceRemoveEmpty(pkgInfo.Depends)
@ -335,7 +341,7 @@ func ReadPackageInfo(contents string, defaultValues bool) (*PackageInfo, error)
return &pkgInfo, nil
}
func CreateInfoFile(pkgInfo PackageInfo) string {
func CreateInfoFile(pkgInfo PackageInfo, keepSourceFields bool) string {
ret := ""
ret = ret + "name: " + pkgInfo.Name + "\n"
ret = ret + "description: " + pkgInfo.Description + "\n"
@ -348,9 +354,15 @@ func CreateInfoFile(pkgInfo PackageInfo) string {
}
ret = ret + "architecture: " + pkgInfo.Arch + "\n"
ret = ret + "type: " + pkgInfo.Type + "\n"
if len(pkgInfo.Keep) > 0 {
ret = ret + "keep (" + strconv.Itoa(len(pkgInfo.Keep)) + "): " + strings.Join(pkgInfo.Keep, ",") + "\n"
}
if len(pkgInfo.Depends) > 0 {
ret = ret + "depends (" + strconv.Itoa(len(pkgInfo.Depends)) + "): " + strings.Join(pkgInfo.Depends, ",") + "\n"
}
if len(pkgInfo.MakeDepends) > 0 && keepSourceFields {
ret = ret + "make_depends (" + strconv.Itoa(len(pkgInfo.MakeDepends)) + "): " + strings.Join(pkgInfo.MakeDepends, ",") + "\n"
}
if len(pkgInfo.Provides) > 0 {
ret = ret + "provides (" + strconv.Itoa(len(pkgInfo.Provides)) + "): " + strings.Join(pkgInfo.Provides, ",") + "\n"
}
@ -410,7 +422,8 @@ func InstallPackage(filename, installDir string, force, binaryPkgFromSrc, keepTe
return err
}
if strings.HasPrefix(header.Name, "files/") && header.Name != "files/" {
extractFilename := path.Join(installDir, strings.TrimPrefix(header.Name, "files/"))
trimmedName := strings.TrimPrefix(header.Name, "files/")
extractFilename := path.Join(installDir, trimmedName)
switch header.Typeflag {
case tar.TypeDir:
files = append(files, strings.TrimPrefix(header.Name, "files/"))
@ -422,6 +435,13 @@ func InstallPackage(filename, installDir string, force, binaryPkgFromSrc, keepTe
fmt.Println("Creating Directory: " + extractFilename)
}
case tar.TypeReg:
if _, err := os.Stat(extractFilename); err == nil {
if slices.Contains(pkgInfo.Keep, trimmedName) {
fmt.Println("Skipping File: " + extractFilename + "(File is configured to be kept during installs/updates)")
files = append(files, trimmedName)
continue
}
}
err := os.Remove(extractFilename)
if err != nil && !os.IsNotExist(err) {
return err
@ -571,6 +591,7 @@ func InstallPackage(filename, installDir string, force, binaryPkgFromSrc, keepTe
cmd.Env = append(cmd.Env, fmt.Sprintf("BPM_PKG_DESC=%s", pkgInfo.Description))
cmd.Env = append(cmd.Env, fmt.Sprintf("BPM_PKG_VERSION=%s", pkgInfo.Version))
cmd.Env = append(cmd.Env, fmt.Sprintf("BPM_PKG_URL=%s", pkgInfo.Url))
cmd.Env = append(cmd.Env, fmt.Sprintf("BPM_PKG_ARCH=%s", pkgInfo.Arch))
depends := make([]string, len(pkgInfo.Depends))
copy(depends, pkgInfo.Depends)
for i := 0; i < len(depends); i++ {
@ -614,6 +635,13 @@ func InstallPackage(filename, installDir string, force, binaryPkgFromSrc, keepTe
fmt.Println("Creating Directory: " + extractFilename)
}
} else if d.Type().IsRegular() {
if _, err := os.Stat(extractFilename); err == nil {
if slices.Contains(pkgInfo.Keep, relFilename) {
fmt.Println("Skipping File: " + extractFilename + "(File is configured to be kept during installs/updates)")
files = append(files, relFilename)
return nil
}
}
err := os.Remove(extractFilename)
if err != nil && !os.IsNotExist(err) {
return err
@ -674,7 +702,7 @@ func InstallPackage(filename, installDir string, force, binaryPkgFromSrc, keepTe
compiledInfo = *pkgInfo
compiledInfo.Type = "binary"
compiledInfo.Arch = GetArch()
err = os.WriteFile(path.Join(compiledDir, "pkg.info"), []byte(CreateInfoFile(compiledInfo)), 0644)
err = os.WriteFile(path.Join(compiledDir, "pkg.info"), []byte(CreateInfoFile(compiledInfo, false)), 0644)
if err != nil {
return err
}
@ -1170,6 +1198,7 @@ func RemovePackage(pkg, rootDir string) error {
cmd.Env = append(cmd.Env, fmt.Sprintf("BPM_PKG_DESC=%s", pkgInfo.Description))
cmd.Env = append(cmd.Env, fmt.Sprintf("BPM_PKG_VERSION=%s", pkgInfo.Version))
cmd.Env = append(cmd.Env, fmt.Sprintf("BPM_PKG_URL=%s", pkgInfo.Url))
cmd.Env = append(cmd.Env, fmt.Sprintf("BPM_PKG_ARCH=%s", pkgInfo.Arch))
depends := make([]string, len(pkgInfo.Depends))
copy(depends, pkgInfo.Depends)
for i := 0; i < len(depends); i++ {

21
main.go
View File

@ -17,7 +17,7 @@ import (
/* A simple-to-use package manager */
/* ---------------------------------- */
var bpmVer = "0.1.7"
var bpmVer = "0.2.0"
var subcommand = "help"
var subcommandArgs []string
@ -84,7 +84,7 @@ func resolveCommand() {
fmt.Printf("Package (%s) could not be found\n", pkg)
continue
}
fmt.Print("----------------\n" + bpm_utils.CreateInfoFile(*info))
fmt.Print("----------------\n" + bpm_utils.CreateInfoFile(*info, true))
if n == len(packages)-1 {
fmt.Println("----------------")
}
@ -112,7 +112,7 @@ func resolveCommand() {
fmt.Printf("Package (%s) could not be found\n", pkg)
continue
}
fmt.Print("----------------\n" + bpm_utils.CreateInfoFile(*info))
fmt.Print("----------------\n" + bpm_utils.CreateInfoFile(*info, true))
if n == len(packages)-1 {
fmt.Println("----------------")
}
@ -133,7 +133,7 @@ func resolveCommand() {
if err != nil {
log.Fatalf("Could not read package\nError: %s\n", err)
}
fmt.Print("----------------\n" + bpm_utils.CreateInfoFile(*pkgInfo))
fmt.Print("----------------\n" + bpm_utils.CreateInfoFile(*pkgInfo, true))
fmt.Println("----------------")
verb := "install"
if pkgInfo.Type == "source" {
@ -149,14 +149,14 @@ func resolveCommand() {
continue
}
if pkgInfo.Type == "source" {
if unresolved := bpm_utils.CheckMakeDependencies(pkgInfo, rootDir); len(unresolved) != 0 {
if unresolved := bpm_utils.CheckMakeDependencies(pkgInfo, "/"); len(unresolved) != 0 {
fmt.Printf("skipping... cannot %s package (%s) due to missing make dependencies: %s\n", verb, pkgInfo.Name, strings.Join(unresolved, ", "))
continue
}
}
}
if rootDir != "/" {
fmt.Println("Warning: Installing to " + rootDir)
fmt.Println("Warning: Operating in " + rootDir)
}
if !yesAll {
reader := bufio.NewReader(os.Stdin)
@ -231,10 +231,10 @@ func resolveCommand() {
fmt.Printf("Package (%s) could not be found\n", pkg)
continue
}
fmt.Print("----------------\n" + bpm_utils.CreateInfoFile(*pkgInfo))
fmt.Print("----------------\n" + bpm_utils.CreateInfoFile(*pkgInfo, true))
fmt.Println("----------------")
if rootDir != "/" {
fmt.Println("Warning: Installing to " + rootDir)
fmt.Println("Warning: Operating in " + rootDir)
}
if !yesAll {
reader := bufio.NewReader(os.Stdin)
@ -305,11 +305,10 @@ func resolveCommand() {
}
func printHelp() {
fmt.Println("\033[1m------Help------\033[0m")
fmt.Println("\033[1m\\ Command Format /\033[0m")
fmt.Println("\033[1m---- Command Format ----\033[0m")
fmt.Println("-> command format: bpm <subcommand> [-flags]...")
fmt.Println("-> flags will be read if passed right after the subcommand otherwise they will be read as subcommand arguments")
fmt.Println("\033[1m\\ Command List /\033[0m")
fmt.Println("\033[1m---- Command List ----\033[0m")
fmt.Println("-> bpm version | shows information on the installed version of bpm")
fmt.Println("-> bpm info [-R] | shows information on an installed package")
fmt.Println(" -R=<root_path> lets you define the root path which will be used")

View File

@ -1,77 +0,0 @@
#!/bin/bash
if [ $# -eq 0 ]
then
echo "No output package name given!"
exit 1
fi
output=$1
if [[ ! "$output" =~ ^[a-z.A-Z0-9_-]{1,}$ ]]; then
echo "Invalid output name! The name must only contain letters, numbers, hyphens or underscores!"
exit 1
fi
type="binary"
toCompress=("pkg.info")
echo "Creating package with the name $output..."
if [ -d files ]; then
echo "files/ directory found"
toCompress+=("files/")
else
if [ -f source.sh ]; then
type="source"
echo "source.sh file found"
toCompress+=("source.sh")
if [ -f pre_update.sh ]; then
echo "pre_update.sh file found"
toCompress+=("pre_update.sh")
fi
if [ -f post_update.sh ]; then
echo "post_update.sh file found"
toCompress+=("post_update.sh")
fi
if [ -f pre_install.sh ]; then
echo "pre_install.sh file found"
toCompress+=("pre_install.sh")
fi
if [ -f post_install.sh ]; then
echo "post_install.sh file found"
toCompress+=("post_install.sh")
fi
if [ -f post_remove.sh ]; then
echo "post_remove.sh file found"
toCompress+=("post_remove.sh")
fi
if [ -d source-files ]; then
echo "source-files/ directory found"
toCompress+=("source-files/")
fi
else
echo "files/ directory or source.sh file not found in $PWD"
exit 1
fi
fi
if [ -f pkg.info ]; then
echo "pkg.info file found"
else
echo "pkg.info file not found in $PWD"
exit 1
fi
echo "Creating $type package as $output"
tar -czf "$output" "${toCompress[@]}"
#if [[ "$type" == "binary" ]]; then
# tar -czf "$output" files/ pkg.info
#else
# if [ -d source-files ]; then
# tar -czf "$output" source.sh source-files/ pkg.info
# else
# tar -czf "$output" source.sh pkg.info
# fi
#fi

View File

@ -1,66 +1,154 @@
#!/bin/bash
if [ $# -lt 2 ]; then
echo "Arguments missing! Try 'bpm-setup <directory> <binary/source>'"
usage () {
echo "------BPM-Setup options------"
echo "bpm-setup -D <directory> | Path to package directory"
echo "bpm-setup -y | Skips confirmation prompt"
echo "bpm-setup -n <name> | Set the package name (Defaults to \"package-name\")"
echo "bpm-setup -d <description> | Set the package description (Defaults to \"Default package description\")"
echo "bpm-setup -v <version> | Set the package version (Defaults to \"1.0\")"
echo "bpm-setup -u <url> | Set the package URL (Optional)"
echo "bpm-setup -l <licenses> | Set the package licenses (Optional)"
echo "bpm-setup -t <binary/source> | Set the package type to binary or source (Defaults to binary)"
echo "bpm-setup -s <source template file> | Use a default template file (Defaults to /etc/bpm-utils/source.default)"
}
if [ $# -eq 0 ]; then
usage
exit
fi
NAME="package-name"
DESCRIPTION="Default package description"
VERSION="1.0"
#URL="https://my.project.url/ (Optional)"
#LICENSE="Your project's license (Optional)"
TYPE="binary"
SOURCE_FILE="/etc/bpm-utils/source.default"
while getopts "D:n:d:v:u:l:t:s:y" o; do
case "${o}" in
D)
DIRECTORY="${OPTARG}"
;;
y)
CONFIRM=yes
;;
n)
NAME="${OPTARG}"
;;
d)
DESCRIPTION="${OPTARG}"
;;
v)
VERSION="${OPTARG}"
;;
u)
URL="${OPTARG}"
;;
l)
LICENSE="${OPTARG}"
;;
t)
TYPE="${OPTARG}"
;;
s)
SOURCE_FILE="$(realpath ${OPTARG})"
;;
*)
usage
exit 1
;;
esac
done
if [ -z "${DIRECTORY}" ]; then
echo "Required directory argument missing. Try 'bpm-setup -D <directory> [other options...]"
exit 1
fi
output=$1
type=$2
if [[ ! "${DIRECTORY}" == "/"* ]]; then
DIRECTORY="${PWD}/${DIRECTORY}"
fi
if [[ ! "$output" =~ ^[a-zA-Z0-9_-]{1,}$ ]]; then
echo "Invalid output name! The name must only contain letters, numbers, hyphens or underscores!"
if [ -e "${DIRECTORY}" ]; then
echo "This path already exists"
exit 1
fi
if [[ "$type" != "binary" ]] && [[ "$type" != "source" ]]; then
if [[ "$TYPE" != "binary" ]] && [[ "$TYPE" != "source" ]]; then
echo "Invalid package type! Package type must be either 'binary' or 'source'"
exit 1
fi
mkdir -pv $output
cd $output
if [[ "$type" == "binary" ]]; then
cat > pkg.info << EOF
name: package_name
description: Package Description
version: 1.0
url: your package's website/repository url. Optonal
license: your package's license. Optional
architecture: $(uname -m)
type: binary
EOF
if [ -z "${CONFIRM}" ]; then
echo "Setting up package working directory at ${DIRECTORY} with the following information:"
echo "Package name: $NAME"
echo "Package description: $DESCRIPTION"
echo "Package version: $VERSION"
if [ -z "${URL}" ]; then
echo "Package URL: Not set"
else
echo "Package URL: $URL"
fi
if [ -z "${LICENSE}" ]; then
echo "Package license: Not set"
else
echo "Package license: $LICENSE"
fi
echo "Package type: $TYPE"
read -p "Create package directory? [y/N]: " CREATE
case $CREATE in
[Yy]* )
;;
*)
echo "Exiting bpm-setup..."
exit
;;
esac
fi
if ! mkdir -pv $DIRECTORY; then
echo "Could not create $DIRECTORY!"
exit 1
fi
cd $DIRECTORY
touch pkg.info
echo "name: ${NAME}" >> pkg.info
echo "description: ${DESCRIPTION}" >> pkg.info
echo "version: ${VERSION}" >> pkg.info
if [ ! -z "${URL}" ]; then echo "url: ${URL}" >> pkg.info; fi
if [ ! -z "${LICENSE}" ]; then echo "license: ${LICENSE}" >> pkg.info; fi
if [[ "$TYPE" == "binary" ]]; then
echo "architecture: $(uname -m)" >> pkg.info
echo "type: binary" >> pkg.info
mkdir -pv files
echo "Package directory created successfully!"
echo "Make sure to edit the pkg.info file with the appropriate information for your package"
echo "Add your binaries under the files/ directory. For example a binary called 'my_binary' should go under files/usr/bin/my_binary"
echo "Add your binaries under the 'files' directory. For example a binary called 'my_binary' should go under files/usr/bin/my_binary"
echo "You can turn your package into a .bpm file use the 'bpm-create <name>' command"
else
cat > pkg.info << EOF
name: package_name
description: Package Description
version: 1.0
url: your package's website/repository url. Optional
license: your package's license. Optional
architecture: any
type: source
EOF
cat > source.sh << 'EOF'
# This is the source.sh script. It is executed by BPM in a temporary directory when compiling a source package
# BPM expects there to be an 'output' directory under the root of the temporary directory after this script finishes executing, otherwise your program may not be correctly installed
# It is recommended you create the 'output' directory along with a 'source' directory in the root of the temporary directory like this
echo "Compiling my_program..."
# Creating 'source' and 'output' directory variables
source=$(pwd)/source
output=$(pwd)/output
# Creating the 'source' and 'output' directories
mkdir $source
mkdir $output
# Downloading files
git clone https://myrepo.com/repo.git source
EOF
echo "architecture: any" >> pkg.info
echo "type: source" >> pkg.info
mkdir -pv source-files
if [ -f "${SOURCE_FILE}" ]; then
touch source.temp
cat "${SOURCE_FILE}" > source.temp
export NAME DESCRIPTION VERSION URL LICENSE TYPE
envsubst '$NAME:$DESCRIPTION:$VERSION:$URL:$LICENSE:$TYPE' < source.temp > source.sh
rm source.temp
else
echo "Source file at ${SOURCE_FILE} does not exist! Creating empty source.sh instead..."
touch source.sh
fi
echo "Package directory created successfully!"
echo "Make sure to edit the pkg.info file with the appropriate information for your package"
echo "Add your compilation code in the source.sh file. Follow the instructions on the template file on how to do properly compile your program"
echo "You can turn your package into a .bpm file use the 'bpm-create <name>' command"
echo "Add your compilation code in the source.sh file. Follow the instructions on the template file on how to properly create your compilation script"
echo "You can add additional files that will be used during compilation to the 'source-files' directory"
echo "You can turn your package into a .bpm file use the 'bpm-package <filename>' command"
fi

View File

@ -1,7 +1,8 @@
name: bpm-utils
description: Utilities to create BPM packages
version: 1.4.0
version: 2.0.0
url: https://gitlab.com/bubble-package-manager/bpm/
license: GPL3
architecture: x86_64
type: binary
architecture: any
keep: etc/bpm-utils/source.default
type: binary

Binary file not shown.

View File

@ -1,6 +1,6 @@
name: bpm
description: The Bubble Package Manager
version: 0.1.7
version: 0.2.0
url: https://gitlab.com/bubble-package-manager/bpm/
license: GPL3
architecture: x86_64