Compare commits

..

8 Commits

19 changed files with 396 additions and 572 deletions

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
# IDE Directories
.idea
# Build directory
build

36
Makefile Normal file
View File

@ -0,0 +1,36 @@
SHELL = /bin/bash
ifeq ($(PREFIX),)
PREFIX := /usr/local
endif
ifeq ($(BINDIR),)
BINDIR := $(PREFIX)/bin
endif
ifeq ($(SYSCONFDIR),)
SYSCONFDIR := $(PREFIX)/etc
endif
ifeq ($(GO),)
GO := $(shell type -a -P go | head -n 1)
endif
build:
mkdir -p build
cd src/bpm-convert; $(GO) build -ldflags "-w" -o ../../build/bpm-convert git.enumerated.dev/bubble-package-manager/bpm-utils/src/bpm-convert
cd src/bpm-package; $(GO) build -ldflags "-w" -o ../../build/bpm-package git.enumerated.dev/bubble-package-manager/bpm-utils/src/bpm-package
cd src/bpm-repo; $(GO) build -ldflags "-w" -o ../../build/bpm-repo git.enumerated.dev/bubble-package-manager/bpm-utils/src/bpm-repo
cd src/bpm-setup; $(GO) build -ldflags "-w" -o ../../build/bpm-setup git.enumerated.dev/bubble-package-manager/bpm-utils/src/bpm-setup
install: build config/
# Create directories
install -dm755 $(DESTDIR)$(BINDIR)
install -dm755 $(DESTDIR)$(SYSCONFDIR)
# Install binaries
install -Dm755 build/bpm-* -t $(DESTDIR)$(BINDIR)/
# Install config files
install -dm755 $(DESTDIR)$(SYSCONFDIR)/bpm-utils/
cp -r config/* -t $(DESTDIR)$(SYSCONFDIR)/bpm-utils/
clean:
rm -r build/
.PHONY: build

View File

@ -1,217 +0,0 @@
#!/bin/bash
if [ -f .compilation-options ]; then
source ./.compilation-options
fi
echo "$ARCH"
while getopts "ksfa:" o; do
case "${o}" in
a) ARCH="$OPTARG";;
k) KEEP=true;;
s) SKIPCHECK=true;;
f) FORCE=true;;
*) exit 1;;
esac
done
PACKAGE="${@:$OPTIND:1}"
DIR="$PWD"
if [ -z "$ARCH" ]; then
ARCH=$(uname -m)
fi
if ! [ -f "$PACKAGE" ]; then
echo "$PACKAGE is not a path to a file"
exit 1
fi
if ! file "$PACKAGE" | grep -q 'POSIX tar archive'; then
echo "$PACKAGE is not a BPM package"
exit 1
fi
if ! tar -tf "$PACKAGE" | grep -q 'source.sh'; then
echo "$PACKAGE is not a BPM source package"
exit 1
fi
echo "$Converting $PACKAGE..."
declare -A PKGINFO
# Declare and run Read Package Information function
function ReadPkgInfo() {
local BACK="$PWD"
cd "$DIR"
if [ $# -eq 0 ]; then
FILE=pkg.info
PKGINFO_FILE=$(tar -xf "$PACKAGE" pkg.info -O)
else
FILE=pkg.info."$1"
fi
if ! tar -tf "$PACKAGE" "$FILE"; then
echo "Could not find $FILE in $PACKAGE"
exit 1
fi
PKGINFO_FILE=$(tar -xf "$PACKAGE" "$FILE" -O)
while read line; do
PKGINFO[$(echo -n "$line" | cut -d":" -f1 | xargs)]=$(echo -n "$line" | cut -d":" -f2 | xargs)
done < <(tar -xf "$PACKAGE" "$FILE" -O)
cd "$BACK"
}
ReadPkgInfo
if [ -z "$FORCE" ] && command -v bpm &> /dev/null && [ -n "$PKGINFO[depends]" ]; then
MISSING=()
for depend in $(echo "${PKGINFO[depends]}" | tr -d '[]' | tr ',' '\n' ); do
if ! bpm info "$depend" &> /dev/null; then
MISSING+=("$depend")
fi
done
if [ "${#MISSING[@]}" -ne 0 ]; then
echo "The following dependencies could not be resolved: ${MISSING[@]}"
EXIT=true
fi
elif ! command -v bpm &> /dev/null; then
echo "BPM not in PATH. Skipping dependency resolution"
elif [ -n "$FORCE" ]; then
echo "Force compilation enabled. Skipping dependency resolution"
fi
if [ -z "$FORCE" ] && command -v bpm &> /dev/null && [ -n "$PKGINFO[make_depends]" ]; then
MISSING=()
for depend in $(echo "${PKGINFO[make_depends]}" | tr -d '[]' | tr ',' '\n' ); do
if ! bpm info "$depend" &> /dev/null; then
MISSING+=("$depend")
fi
done
if [ "${#MISSING[@]}" -ne 0 ]; then
echo "The following make dependencies could not be resolved: ${MISSING[@]}"
EXIT=true
fi
elif ! command -v bpm &> /dev/null; then
echo "BPM not in PATH. Skipping make dependency resolution"
elif [ -n "$FORCE" ]; then
echo "Force compilation enabled. Skipping make dependency resolution"
fi
if [ -n "$EXIT" ]; then
exit 1
fi
# Creating temporary compilation directory structure
TEMPDIR="/var/tmp/bpm_source_${PKGINFO[name]}"
if [ -d "$TEMPDIR" ] && [ -z "$KEEP" ]; then
rm -rf "$TEMPDIR"
fi
mkdir -p "$TEMPDIR"
mkdir -p "$TEMPDIR"/source
[ -d "$TEMPDIR"/output ] && rm -rf "$TEMPDIR"/output
mkdir -p "$TEMPDIR"/output
tar -xf "$PACKAGE" -C "$TEMPDIR" source.sh
if tar -xf "$PACKAGE" -C "$TEMPDIR" source-files &> /dev/null; then
mv "$TEMPDIR"/source-files/* "$TEMPDIR"/
rm -d "$TEMPDIR"/source-files
fi
PACKAGE_SCRIPTS=()
while read line; do
PACKAGE_SCRIPTS+=("$line")
done < <(tar -tf "$PACKAGE" | grep -v -E 'source.sh|pkg.info|source-files')
tar -xf "$PACKAGE" -C "$TEMPDIR" ${PACKAGE_SCRIPTS[@]} &> /dev/null
cd "$TEMPDIR"
# Declare and run Set Variables function
function SetVariables() {
export BPM_PKG_NAME="${PKGINFO[name]}"
export BPM_PKG_DESC="${PKGINFO[description]}"
export BPM_PKG_VERSION="${PKGINFO[version]}"
export BPM_PKG_REVISION="${PKGINFO[revision]}"
[ -z "$BPM_PKG_REVISION" ] && export BPM_PKG_REVISION=1
export BPM_PKG_URL="${PKGINFO[url]}"
export BPM_PKG_ARCH="${PKGINFO[architecture]}"
IFS=',' read -r -a BPM_PKG_DEPENDS <<< "${PKGINFO[depends]}"
IFS=',' read -r -a BPM_PKG_MAKE_DEPENDS <<< "${PKGINFO[make_depends]}"
export BPM_PKG_DEPENDS
export BPM_PKG_MAKE_DEPENDS
export BPM_WORKDIR="$TEMPDIR"
export BPM_SOURCE="$TEMPDIR"/source
export BPM_OUTPUT="$TEMPDIR"/output
}
SetVariables
# Declare Run Package Function function
function RunPkgFunction() {
if [ $# -eq 0 ]; then
echo "No function name given"
exit 1
fi
func="$1"
if [[ $(type -t "$func") == function ]]; then
echo "Running ${func}() function..."
bash -e -c "$func"
if [ $? -ne 0 ]; then
echo "Failed to run ${func}() function in source.sh"
exit 1
fi
fi
}
# Read source.sh file and source functions
set -a
source source.sh
set +a
cd "$BPM_WORKDIR"
RunPkgFunction prepare
cd "$BPM_SOURCE"
RunPkgFunction build
cd "$BPM_SOURCE"
if [ -z "$SKIPCHECK" ]; then
RunPkgFunction check
fi
# Packaging all packages
for func in $(typeset -F | awk '{print $3}' | grep '^package'); do
cd "$BPM_SOURCE"
if [[ "$func" == "package" ]]; then
pkgname="$BPM_PKG_NAME"
ReadPkgInfo
else
pkgname="${func##package-}"
ReadPkgInfo "$pkgname"
fi
SetVariables
echo "Running ${func}() function..."
touch "$TEMPDIR"/fakeroot_file_"$pkgname"
fakeroot -s "$TEMPDIR"/fakeroot_file_"$pkgname" bash -e -c "$func"
if [ $? -ne 0 ]; then
echo "Failed to run ${func}() function in source.sh"
exit 1
fi
cd "$BPM_WORKDIR"
touch pkg.info
if [[ "$pkgname" == "$BPM_PKG_NAME" ]]; then
echo "${PKGINFO_FILE}" > pkg.info
else
echo "${PKGINFO_FILE}" > pkg.info
fi
echo "${PKGINFO_FILE}" > pkg.info
sed -i "s/architecture:.*/architecture: ${ARCH}/g" pkg.info
sed -i 's/type:.*/type: binary/g' pkg.info
fakeroot -i "$TEMPDIR"/fakeroot_file_"$pkgname" find "$TEMPDIR"/output -mindepth 1 -printf "%P %#m %U %G %s\n" > "$TEMPDIR"/pkg.files
find output -printf "%P\n" | fakeroot -i "$TEMPDIR"/fakeroot_file_"$pkgname" tar -czf files.tar.gz --no-recursion -C output -T -
tar -cf "$DIR"/"$pkgname"-"$BPM_PKG_VERSION"-"$BPM_PKG_REVISION"-"$ARCH".bpm --owner=0 --group=0 -C "$TEMPDIR" pkg.info pkg.files ${PACKAGE_SCRIPTS[@]} files.tar.gz
echo "Packaged ${pkgname} successfully!"
rm "$TEMPDIR"/fakeroot_file_"$pkgname"
rm -r output/
mkdir output
rm pkg.info
done
if [ -z "$KEEP" ]; then
rm -rf "$TEMPDIR"
fi

View File

@ -1,99 +0,0 @@
#!/bin/bash
if [ -f .compilation-options ]; then
source ./.compilation-options
fi
while getopts "cskfa:" flag; do
case "$flag" in
c) CONVERT=true;;
k) KEEP=true;;
s) SKIPCHECK=true;;
f) FORCE=true;;
a) ARCH="${OPTARG}";;
*) exit 1;;
esac
done
if [ -f pkg.info ]; then
echo "pkg.info file found"
else
echo "pkg.info file not found in $PWD"
exit 1
fi
output="${@:$OPTIND:1}"
if [ -z "$output" ]; then
pkgname=$(grep "^name: " pkg.info)
output=$(echo "$pkgname" | cut -d' ' -f2)"-src.bpm"
fi
if [ -z "$output" ] || [[ ! "$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=()
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 pre_remove.sh ]; then
echo "pre_remove.sh file found"
toCompress+=("pre_remove.sh")
fi
if [ -f post_remove.sh ]; then
echo "post_remove.sh file found"
toCompress+=("post_remove.sh")
fi
if [ -d source-files ]; then
if [ ! -z "$(ls -A source-files)" ]; then
echo "source-files/ directory found"
toCompress+=("source-files/")
fi
fi
else
echo "files/ directory or source.sh file not found in $PWD"
exit 1
fi
fi
for pkginfo in ./pkg.inf*; do
pkginfo=$(basename "$pkginfo")
echo "${pkginfo} file found"
toCompress+=("$pkginfo")
done
echo "Creating $type package as $output"
tar -c --owner=0 --group=0 --no-same-owner -f "$output" "${toCompress[@]}"
if [ ! -z "$CONVERT" ] && "$CONVERT" && [[ "$type" == "source" ]]; then
args=()
[ -n "$KEEP" ] && args+=("-k")
[ -n "$SKIPCHECK" ] && args+=("-s")
[ -n "$FORCE" ] && args+=("-f")
bpm-convert "${args[@]}" -a "$ARCH" "$output"
fi

176
bpm-setup
View File

@ -1,176 +0,0 @@
#!/bin/bash
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)"
echo "bpm-setup -g <true/false> | Create git repository (Defaults to true)"
}
if [ $# -eq 0 ]; then
usage
exit
fi
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"
GIT=true
while getopts "D:n:d:v:u:l:t:s:g: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})"
;;
g)
if [[ "${OPTARG}" == true ]]; then
GIT=TRUE
elif [[ "${OPTARG}" == false ]]; then
GIT=false
else
echo "${OPTARG} is not a true or false value!"
exit 1
fi
;;
*)
usage
exit 1
;;
esac
done
if [ -z "${DIRECTORY}" ]; then
echo "Required directory argument missing. Try 'bpm-setup -D <directory> [other options...]"
exit 1
fi
if [ -z "${NAME}" ]; then
NAME="${DIRECTORY}"
fi
if [[ ! "${DIRECTORY}" == "/"* ]]; then
DIRECTORY="${PWD}/${DIRECTORY}"
fi
if [ -e "${DIRECTORY}" ]; then
echo "This path already exists"
exit 1
fi
if [[ "$TYPE" != "binary" ]] && [[ "$TYPE" != "source" ]]; then
echo "Invalid package type! Package type must be either 'binary' or 'source'"
exit 1
fi
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"
if [[ "$TYPE" == "source" ]]; then
echo "Create Git repository: $GIT"
fi
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 "You can turn your package into a .bpm file use the 'bpm-create <name>' command"
else
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
if $GIT ; then
git init
echo -e "*.bpm\n.gitignore" > .gitignore
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 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

42
config/templates/cmake Normal file
View File

@ -0,0 +1,42 @@
# This is the source.sh script. It is executed by BPM in a temporary directory when compiling a source package
# BPM Expects the source code to be extracted into the automatically created 'source' directory which can be accessed using $BPM_SOURCE
# BPM Expects the output files to be present in the automatically created 'output' directory which can be accessed using $BPM_OUTPUT
DOWNLOAD="https://wwww.my-url.com/file.tar.gz"
FILENAME="${DOWNLOAD##*/}"
# The prepare function is executed in the root of the temp directory
# This function is used for downloading files and putting them into the correct location
prepare() {
wget "$DOWNLOAD"
tar -xvf "$FILENAME" --strip-components=1 -C "$BPM_SOURCE"
}
# The build function is executed in the source directory
# This function is used to compile the source code
build() {
mkdir build
cd build
cmake -DCMAKE_INSTALL_PREFIX=/usr ..
make
}
# The check function is executed in the source directory
# This function is used to run tests to verify the package has been compiled correctly
check() {
cd build
make test
}
# The package function is executed in the source directory
# This function is used to move the compiled files into the output directory
package() {
cd build
make DESTDIR="$BPM_OUTPUT" install
# Install package license
install -Dm644 "$BPM_SOURCE"/LICENSE "$BPM_OUTPUT"/usr/share/licenses/$NAME/LICENSE
}

View File

@ -29,4 +29,7 @@ check() {
# This function is used to move the compiled files into the output directory # This function is used to move the compiled files into the output directory
package() { package() {
make DESTDIR="$BPM_OUTPUT" install make DESTDIR="$BPM_OUTPUT" install
# Install package license
install -Dm644 "$BPM_SOURCE"/LICENSE "$BPM_OUTPUT"/usr/share/licenses/$NAME/LICENSE
} }

34
config/templates/gnu-make Normal file
View File

@ -0,0 +1,34 @@
# This is the source.sh script. It is executed by BPM in a temporary directory when compiling a source package
# BPM Expects the source code to be extracted into the automatically created 'source' directory which can be accessed using $BPM_SOURCE
# BPM Expects the output files to be present in the automatically created 'output' directory which can be accessed using $BPM_OUTPUT
DOWNLOAD="https://wwww.my-url.com/file.tar.gz"
FILENAME="${DOWNLOAD##*/}"
# The prepare function is executed in the root of the temp directory
# This function is used for downloading files and putting them into the correct location
prepare() {
wget "$DOWNLOAD"
tar -xvf "$FILENAME" --strip-components=1 -C "$BPM_SOURCE"
}
# The build function is executed in the source directory
# This function is used to compile the source code
build() {
make PREFIX=/usr
}
# The check function is executed in the source directory
# This function is used to run tests to verify the package has been compiled correctly
check() {
make check
}
# The package function is executed in the source directory
# This function is used to move the compiled files into the output directory
package() {
make DESTDIR="$BPM_OUTPUT" PREFIX=/usr install
# Install package license
install -Dm644 "$BPM_SOURCE"/LICENSE "$BPM_OUTPUT"/usr/share/licenses/$NAME/LICENSE
}

42
config/templates/meson Normal file
View File

@ -0,0 +1,42 @@
# This is the source.sh script. It is executed by BPM in a temporary directory when compiling a source package
# BPM Expects the source code to be extracted into the automatically created 'source' directory which can be accessed using $BPM_SOURCE
# BPM Expects the output files to be present in the automatically created 'output' directory which can be accessed using $BPM_OUTPUT
DOWNLOAD="https://wwww.my-url.com/file.tar.gz"
FILENAME="${DOWNLOAD##*/}"
# The prepare function is executed in the root of the temp directory
# This function is used for downloading files and putting them into the correct location
prepare() {
wget "$DOWNLOAD"
tar -xvf "$FILENAME" --strip-components=1 -C "$BPM_SOURCE"
}
# The build function is executed in the source directory
# This function is used to compile the source code
build() {
mkdir build
cd build
meson setup --prefix=/usr ..
meson compile
}
# The check function is executed in the source directory
# This function is used to run tests to verify the package has been compiled correctly
check() {
cd build
meson test
}
# The package function is executed in the source directory
# This function is used to move the compiled files into the output directory
package() {
cd build
meson install --destdir="$BPM_OUTPUT"
# Install package license
install -Dm644 "$BPM_SOURCE"/LICENSE "$BPM_OUTPUT"/usr/share/licenses/$NAME/LICENSE
}

View File

@ -0,0 +1,34 @@
# This is the source.sh script. It is executed by BPM in a temporary directory when compiling a source package
# BPM Expects the source code to be extracted into the automatically created 'source' directory which can be accessed using $BPM_SOURCE
# BPM Expects the output files to be present in the automatically created 'output' directory which can be accessed using $BPM_OUTPUT
DOWNLOAD="https://wwww.my-url.com/file.tar.gz"
FILENAME="${DOWNLOAD##*/}"
# The prepare function is executed in the root of the temp directory
# This function is used for downloading files and putting them into the correct location
prepare() {
wget "$DOWNLOAD"
tar -xvf "$FILENAME" --strip-components=1 -C "$BPM_SOURCE"
}
# The build function is executed in the source directory
# This function is used to compile the source code
build() {
python3 -m build --wheel --no-isolation .
}
# The check function is executed in the source directory
# This function is used to run tests to verify the package has been compiled correctly
check() {
# Python module testing command varies from module to module
}
# The package function is executed in the source directory
# This function is used to move the compiled files into the output directory
package() {
python3 -m installer --destdir="$BPM_OUTPUT" dist/*.whl
# Install package license
install -Dm644 "$BPM_SOURCE"/LICENSE "$BPM_OUTPUT"/usr/share/licenses/$NAME/LICENSE
}

View File

@ -1,80 +0,0 @@
#!/bin/bash
containsElement () {
local e match="$1"
shift
for e; do [[ "$e" == "$match" ]] && return 0; done
return 1
}
SCRIPT_PATH=$(realpath "$0")
SCRIPT_DIR=$(dirname "$SCRIPT_PATH")
DEEP=false
PKGS=()
while getopts "d" flag; do
case "$flag" in
d) DEEP=true
shopt -s globstar;;
*) >&2 echo "Unknown flag ${flag}"
exit 2;;
esac
done
if [ -z "${@:$OPTIND:1}" ]; then
echo "You have not specified a repository"
exit 1
fi
if ! [ -d "${@:$OPTIND:1}" ]; then
>&2 echo "The given path is not a directory"
exit 1
fi
if realpath "${@:$OPTIND:1}" &> /dev/null; then
REPO=$(realpath "${@:$OPTIND:1}")
fi
shopt -s nullglob
create_entry() {
if [ $# -eq 0 ]; then
return 0
fi
if ! [ -f "$1" ]; then
return 0
fi
info="info:"$'\n'
info+=$(tar -xf "$pkg" pkg.info -O | sed 's/^/ /g')
package=$(echo "$info" | grep 'name: ' | xargs | awk '{print $2}')
if ! echo "$info" | grep -q '^ type: binary'; then
>&2 echo "The following package is not a binary package: ${package}"
exit 1
fi
if containsElement "$package" "${PKGS[@]}"; then
>&2 echo "The following package was found in more than 1 package archives: ${package}"
exit 1
fi
PKGS+=("$package")
file="$(realpath -s --relative-to="$REPO" "$pkg")"
info+=$'\n'"download: ${file}"
info+=$'\n'"download_size: "$(cat "$pkg" | wc -c)
info+=$'\n'"installed_size: "$(tar -xf "$pkg" files.tar.gz -O | zcat | wc -c)
info+=$'\n---'
echo "$info"
}
if ! $DEEP; then
for arch in "$REPO"/*/; do
for pkg in "$arch"/*.bpm; do
create_entry "$pkg"
done
done
else
for arch in "$REPO"/*/; do
for pkg in "$arch"/**/*.bpm; do
create_entry "$pkg"
done
done
fi

3
src/bpm-convert/go.mod Normal file
View File

@ -0,0 +1,3 @@
module git.enumerated.dev/bubble-package-manager/bpm-utils/src/bpm-convert
go 1.23

7
src/bpm-convert/main.go Normal file
View File

@ -0,0 +1,7 @@
package main
import "fmt"
func main() {
fmt.Println("bpm-convert")
}

3
src/bpm-package/go.mod Normal file
View File

@ -0,0 +1,3 @@
module git.enumerated.dev/bubble-package-manager/bpm-utils/src/bpm-package
go 1.23

7
src/bpm-package/main.go Normal file
View File

@ -0,0 +1,7 @@
package main
import "fmt"
func main() {
fmt.Println("bpm-package")
}

3
src/bpm-repo/go.mod Normal file
View File

@ -0,0 +1,3 @@
module git.enumerated.dev/bubble-package-manager/bpm-utils/src/bpm-repo
go 1.23

7
src/bpm-repo/main.go Normal file
View File

@ -0,0 +1,7 @@
package main
import "fmt"
func main() {
fmt.Println("bpm-repo")
}

3
src/bpm-setup/go.mod Normal file
View File

@ -0,0 +1,3 @@
module git.enumerated.dev/bubble-package-manager/bpm-utils/src/bpm-setup
go 1.23

167
src/bpm-setup/main.go Normal file
View File

@ -0,0 +1,167 @@
package main
import (
"bufio"
"flag"
"fmt"
"log"
"os"
"os/exec"
"path"
"path/filepath"
"strings"
)
var directory = flag.String("D", "", "Path to package directory")
var name = flag.String("n", "", "Set the package name (Defaults to \"package-name\")")
var description = flag.String("d", "Default Package Description", "Set the description (Defaults to \"package-description\")")
var version = flag.String("v", "1.0", "Set the package version (Defaults to \"1.0\")")
var url = flag.String("u", "", "Set the package URL (Optional)")
var license = flag.String("l", "", "Set the package licenses (Optional)")
var template = flag.String("t", "gnu-configure", "Set the package template (Defaults to \"gnu-configure\")")
var git = flag.Bool("g", true, "Create git repository (Defaults to true)")
func main() {
// Setup flags
setupFlags()
// Show command help if no directory name is given
if *directory == "" {
help()
os.Exit(1)
}
// run checks
runChecks()
// Show summary
showSummary()
// Confirmation prompt
fmt.Printf("Create package directory? [y\\N]: ")
reader := bufio.NewReader(os.Stdin)
text, _ := reader.ReadString('\n')
if strings.TrimSpace(strings.ToLower(text)) != "y" && strings.TrimSpace(strings.ToLower(text)) != "yes" {
fmt.Println("Cancelling package directory creation...")
os.Exit(1)
}
// Create package directory
createDirectory()
}
func setupFlags() {
flag.Usage = help
flag.Parse()
if *name == "" {
*name = *directory
}
}
func help() {
fmt.Println("Usage: bpm-setup <options>")
fmt.Println("Description: bpm-setup sets up directories for BPM source package creation")
fmt.Println("Options:")
fmt.Println(" -D=<directory> | Path to package directory")
fmt.Println(" -n=<name> | Set the package name (Defaults to \"package-name\")")
fmt.Println(" -d=<description> | Set the package description (Defaults to \"Default package description\")")
fmt.Println(" -v=<version> | Set the package version (Defaults to \"1.0\")")
fmt.Println(" -u=<url> | Set the package URL (Optional)")
fmt.Println(" -l=<licenses> | Set the package licenses (Optional)")
fmt.Println(" -t=<template file> | Use a template file (Defaults to gnu-configure)")
fmt.Println(" -g=<true/false> | Create git repository (Defaults to true)")
}
func runChecks() {
if strings.TrimSpace(*directory) == "" {
log.Fatalf("No directory was specified!")
}
if strings.TrimSpace(*name) == "" {
log.Fatalf("No package name was specified!")
}
if stat, err := os.Stat(path.Join("/etc/bpm-utils/templates/", *template)); err != nil || stat.IsDir() {
log.Fatalf("%s is not a valid template file!", *template)
}
}
func showSummary() {
absPath, err := filepath.Abs(strings.TrimSpace(*directory))
if err != nil {
log.Fatalf("Failed to determine absolute path: %s", err)
}
fmt.Printf("Setting up package directory at %s with the following information:\n", absPath)
fmt.Printf("Package name: %s\n", strings.TrimSpace(*name))
fmt.Printf("Package description: %s\n", *description)
fmt.Printf("Package version: %s\n", *version)
if url != nil && *url != "" {
fmt.Printf("Package URL: %s\n", *url)
} else {
fmt.Printf("Package URL: Not Set\n")
}
if license != nil && *license != "" {
fmt.Printf("Package license: %s\n", *license)
} else {
fmt.Printf("Package license: Not Set\n")
}
fmt.Printf("Template file: %s\n", *template)
fmt.Printf("Create git repository: %t\n", *git)
}
func createDirectory() {
// Trim spaces
*directory = strings.TrimSpace(*directory)
*name = strings.TrimSpace(*name)
// Create directory
err := os.Mkdir(*directory, 0755)
if err != nil {
log.Fatalf("Error: could not create directory: %s", err)
}
// Create pkg.info contents string
pkgInfo := "name: " + *name + "\n"
pkgInfo += "description: " + *description + "\n"
pkgInfo += "version: " + *version + "\n"
if url != nil && *url != "" {
pkgInfo += "url: " + *url + "\n"
}
if license != nil && *license != "" {
pkgInfo += "license: " + *license + "\n"
}
pkgInfo += "architecture: any\n"
pkgInfo += "type: source\n"
// Write string to file
err = os.WriteFile(path.Join(*directory, "pkg.info"), []byte(pkgInfo), 0644)
if err != nil {
log.Fatalf("Could not write to pkg.info: %s", err)
}
// Create source-files directory
err = os.Mkdir(path.Join(*directory, "source-files"), 0755)
if err != nil {
log.Fatalf("Error: could not create directory: %s", err)
}
// Copy source template file
input, err := os.ReadFile(path.Join("/etc/bpm-utils/templates", *template))
if err != nil {
log.Fatalf("Error: could not read template file: %s", err)
return
}
err = os.WriteFile(path.Join(*directory, "source.sh"), input, 0644)
if err != nil {
log.Fatalf("Error: could not write to source file: %s", err)
return
}
// Create git repository
if git != nil && *git {
err = exec.Command("git", "init", *directory).Run()
if err != nil {
log.Fatalf("Error: could not initialize git repository: %s", err)
}
}
}