mirror of
https://codeberg.org/Toasterson/ips.git
synced 2026-04-10 05:10:42 +00:00
Adding ports and specfile crates. Switch to thiserror for libraries
This commit is contained in:
parent
63b6a48341
commit
4ebecbd153
25 changed files with 990 additions and 180 deletions
3
.cargo/config.toml
Normal file
3
.cargo/config.toml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[build]
|
||||
#rustflags = ["-C", "link-arg=-fuse-ld=lld"]
|
||||
target-dir = "/ws/target"
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -90,3 +90,4 @@ Cargo.lock
|
|||
# Prototype directory
|
||||
sample_data/**/build/prototype/i386
|
||||
|
||||
.vagrant
|
||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[submodule "oi-userland"]
|
||||
path = oi-userland
|
||||
url = git@github.com:Toasterson/oi-userland.git
|
||||
5
.vscode/dryrun.log
vendored
5
.vscode/dryrun.log
vendored
|
|
@ -1,9 +1,8 @@
|
|||
make --dry-run --always-make --keep-going --print-directory
|
||||
make: Entering directory '/home/toast/workspace/illumos/aurora/ips'
|
||||
make: Entering directory '/ws/toast/illumos/rust/ips'
|
||||
rm -rf target artifacts
|
||||
|
||||
cargo build --release
|
||||
mkdir -p artifacts
|
||||
cp target/release/pkg6dev artifacts/
|
||||
make: Leaving directory '/home/toast/workspace/illumos/aurora/ips'
|
||||
make: Leaving directory '/ws/toast/illumos/rust/ips'
|
||||
|
||||
|
|
|
|||
104
.vscode/targets.log
vendored
104
.vscode/targets.log
vendored
|
|
@ -5,30 +5,19 @@ make all --print-data-base --no-builtin-variables --no-builtin-rules --question
|
|||
# License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
|
||||
# This is free software: you are free to change and redistribute it.
|
||||
# There is NO WARRANTY, to the extent permitted by law.
|
||||
|
||||
|
||||
# Make data base, printed on Thu Sep 1 15:11:07 2022
|
||||
# Make data base, printed on Fri Sep 2 20:28:38 2022
|
||||
|
||||
# Variables
|
||||
|
||||
# environment
|
||||
GO111MODULE = on
|
||||
# environment
|
||||
LC_ALL = C
|
||||
# environment
|
||||
LC_NAME = de_CH.UTF-8
|
||||
# environment
|
||||
LC_NUMERIC = de_CH.UTF-8
|
||||
# environment
|
||||
VSCODE_CWD = /home/toast
|
||||
# environment
|
||||
LC_ADDRESS = de_CH.UTF-8
|
||||
VSCODE_CWD = /ws/toast
|
||||
# default
|
||||
MAKE_COMMAND := make
|
||||
# environment
|
||||
VSCODE_HANDLES_SIGPIPE = true
|
||||
# environment
|
||||
GOPATH = /home/toast/workspace/go
|
||||
# automatic
|
||||
@D = $(patsubst %/,%,$(dir $@))
|
||||
# environment
|
||||
|
|
@ -36,13 +25,11 @@ VSCODE_HANDLES_UNCAUGHT_ERRORS = true
|
|||
# default
|
||||
.VARIABLES :=
|
||||
# environment
|
||||
PWD = /home/toast/workspace/illumos/aurora/ips
|
||||
PWD = /ws/toast/illumos/rust/ips
|
||||
# automatic
|
||||
%D = $(patsubst %/,%,$(dir $%))
|
||||
# environment
|
||||
LSCOLORS = Gxfxcxdxbxegedabagacad
|
||||
# environment
|
||||
OLDPWD = /home/toast
|
||||
MAIL = /var/spool/mail/toast
|
||||
# automatic
|
||||
^D = $(patsubst %/,%,$(dir $^))
|
||||
# automatic
|
||||
|
|
@ -52,19 +39,19 @@ LANG = C
|
|||
# default
|
||||
.LOADED :=
|
||||
# default
|
||||
.INCLUDE_DIRS = /usr/local/include /usr/include /usr/include
|
||||
.INCLUDE_DIRS = /usr/include /usr/local/include /usr/include
|
||||
# makefile
|
||||
MAKEFLAGS = pqrR
|
||||
# makefile
|
||||
CURDIR := /home/toast/workspace/illumos/aurora/ips
|
||||
CURDIR := /ws/toast/illumos/rust/ips
|
||||
# environment
|
||||
APPLICATION_INSIGHTS_NO_DIAGNOSTIC_CHANNEL = true
|
||||
APPLICATION_INSIGHTS_NO_DIAGNOSTIC_CHANNEL = 1
|
||||
# automatic
|
||||
*D = $(patsubst %/,%,$(dir $*))
|
||||
# environment
|
||||
MFLAGS = -pqrR
|
||||
# environment
|
||||
SSH_AUTH_SOCK = /run/user/1000/vscode-ssh-auth-sock-316701701
|
||||
SSH_AUTH_SOCK = /run/user/1000/vscode-ssh-auth-sock-643226622
|
||||
# default
|
||||
.SHELLFLAGS := -c
|
||||
# automatic
|
||||
|
|
@ -74,8 +61,6 @@ MAKEFILE_LIST := Makefile
|
|||
# automatic
|
||||
@F = $(notdir $@)
|
||||
# environment
|
||||
ZSH = /home/toast/.oh-my-zsh
|
||||
# environment
|
||||
XDG_SESSION_TYPE = tty
|
||||
# automatic
|
||||
?D = $(patsubst %/,%,$(dir $?))
|
||||
|
|
@ -87,92 +72,62 @@ DBUS_SESSION_BUS_ADDRESS = unix:path=/run/user/1000/bus
|
|||
<D = $(patsubst %/,%,$(dir $<))
|
||||
# environment
|
||||
VSCODE_NLS_CONFIG = {"locale":"en","availableLanguages":{}}
|
||||
# environment
|
||||
ANDROID_SDK_ROOT = /home/toast/Android/Sdk
|
||||
# default
|
||||
MAKE_HOST := x86_64-pc-linux-gnu
|
||||
# environment
|
||||
ANDROID_HOME = /home/toast/Android/Sdk
|
||||
# makefile
|
||||
SHELL = /bin/sh
|
||||
# default
|
||||
MAKECMDGOALS := all
|
||||
# environment
|
||||
QT_QPA_PLATFORM = xcb
|
||||
# environment
|
||||
SHLVL = 1
|
||||
SHLVL = 2
|
||||
# environment
|
||||
MAKELEVEL := 0
|
||||
# default
|
||||
MAKE = $(MAKE_COMMAND)
|
||||
# environment
|
||||
PATH = /home/toast/.vscode-server/bin/e4503b30fc78200f846c62cf8091b76ff5547662/bin/remote-cli:/home/toast/.krew/bin:/home/toast/bin:/home/toast/workspace/go/bin:/home/toast/.cargo/bin:/home/toast/.vim/bin:/home/toast/bin:/home/toast/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/toast/Android/Sdk/emulator:/home/toast/Android/Sdk/tools:/home/toast/Android/Sdk/tools/bin:/home/toast/Android/Sdk/platform-tools:/home/toast/.arkade/bin/:/home/toast/.emacs.d/bin
|
||||
PATH = /ws/toast/.vscode-server/bin/e4503b30fc78200f846c62cf8091b76ff5547662/bin/remote-cli:/ws/toast/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl
|
||||
# default
|
||||
MAKEFILES :=
|
||||
# environment
|
||||
MOTD_SHOWN = pam
|
||||
# environment
|
||||
LC_MONETARY = de_CH.UTF-8
|
||||
# automatic
|
||||
^F = $(notdir $^)
|
||||
# environment
|
||||
LC_TIME = de_CH.UTF-8
|
||||
# environment
|
||||
GOBIN = /home/toast/workspace/go/bin
|
||||
# environment
|
||||
SSH_CLIENT = 100.85.127.110 58934 22
|
||||
# environment
|
||||
LC_TELEPHONE = de_CH.UTF-8
|
||||
SSH_CLIENT = 45.191.210.18 63385 22
|
||||
# automatic
|
||||
?F = $(notdir $?)
|
||||
# environment
|
||||
LS_COLORS =
|
||||
# automatic
|
||||
+F = $(notdir $+)
|
||||
# environment
|
||||
LESS = -R
|
||||
# 'override' directive
|
||||
GNUMAKEFLAGS :=
|
||||
# environment
|
||||
BROWSER = /home/toast/.vscode-server/bin/e4503b30fc78200f846c62cf8091b76ff5547662/bin/helpers/browser.sh
|
||||
# environment
|
||||
SSH_KEY_PATH = ~/.ssh/id_rsa
|
||||
BROWSER = /ws/toast/.vscode-server/bin/e4503b30fc78200f846c62cf8091b76ff5547662/bin/helpers/browser.sh
|
||||
# environment
|
||||
LOGNAME = toast
|
||||
# makefile
|
||||
.DEFAULT_GOAL := all
|
||||
# environment
|
||||
EDITOR = vim
|
||||
# environment
|
||||
USER = toast
|
||||
# default
|
||||
MAKE_VERSION := 4.3
|
||||
# environment
|
||||
LC_MEASUREMENT = de_CH.UTF-8
|
||||
VSCODE_AGENT_FOLDER = /ws/toast/.vscode-server
|
||||
# environment
|
||||
SSH_AGENT_PID = 4552
|
||||
# environment
|
||||
PAGER = less
|
||||
# environment
|
||||
VSCODE_AGENT_FOLDER = /home/toast/.vscode-server
|
||||
# environment
|
||||
_ = /home/toast/.vscode-server/bin/e4503b30fc78200f846c62cf8091b76ff5547662/node
|
||||
# environment
|
||||
LC_PAPER = de_CH.UTF-8
|
||||
_ = /usr/bin/make
|
||||
# environment
|
||||
XDG_RUNTIME_DIR = /run/user/1000
|
||||
# environment
|
||||
VSCODE_IPC_HOOK_CLI = /run/user/1000/vscode-ipc-ee029a89-cf7d-4f9c-850d-175e32feba2a.sock
|
||||
VSCODE_IPC_HOOK_CLI = /run/user/1000/vscode-ipc-b3f27a57-ac5c-4725-88da-aea52f809474.sock
|
||||
# environment
|
||||
XDG_SESSION_CLASS = user
|
||||
# environment
|
||||
VSCODE_AMD_ENTRYPOINT = vs/workbench/api/node/extensionHostProcess
|
||||
# environment
|
||||
HOME = /home/toast
|
||||
HOME = /ws/toast
|
||||
# environment
|
||||
ELECTRON_RUN_AS_NODE = 1
|
||||
# environment
|
||||
XDG_SESSION_ID = 536
|
||||
XDG_SESSION_ID = 168
|
||||
# default
|
||||
.RECIPEPREFIX :=
|
||||
# automatic
|
||||
|
|
@ -180,13 +135,11 @@ XDG_SESSION_ID = 536
|
|||
# default
|
||||
SUFFIXES :=
|
||||
# default
|
||||
.FEATURES := target-specific order-only second-expansion else-if shortest-stem undefine oneshell nocomment grouped-target extra-prereqs archives jobserver output-sync check-symlink load
|
||||
.FEATURES := target-specific order-only second-expansion else-if shortest-stem undefine oneshell nocomment grouped-target extra-prereqs archives jobserver output-sync check-symlink guile load
|
||||
# environment
|
||||
LC_IDENTIFICATION = de_CH.UTF-8
|
||||
# environment
|
||||
SSH_CONNECTION = 100.85.127.110 58934 100.74.144.68 22
|
||||
SSH_CONNECTION = 45.191.210.18 63385 116.202.174.254 22
|
||||
# variable set hash-table stats:
|
||||
# Load=87/1024=8%, Rehash=0, Collisions=5/121=4%
|
||||
# Load=64/1024=6%, Rehash=0, Collisions=2/98=2%
|
||||
|
||||
# Pattern-specific Variable Values
|
||||
|
||||
|
|
@ -197,9 +150,9 @@ publish.% :
|
|||
# 1 pattern-specific variable values
|
||||
# Directories
|
||||
|
||||
# . (device 64769, inode 132376): 23 files, no impossibilities.
|
||||
# . (device 2306, inode 12717540): 25 files, no impossibilities.
|
||||
|
||||
# 23 files, no impossibilities in 1 directories.
|
||||
# 25 files, no impossibilities in 1 directories.
|
||||
|
||||
# Implicit Rules
|
||||
|
||||
|
|
@ -219,7 +172,7 @@ publish.userland:
|
|||
# Not a target:
|
||||
Makefile:
|
||||
# Implicit rule search has been done.
|
||||
# Last modified 2021-05-01 16:21:48.234604484
|
||||
# Last modified 2022-03-27 21:11:05.395373249
|
||||
# File has been updated.
|
||||
# Successfully updated.
|
||||
|
||||
|
|
@ -281,7 +234,6 @@ publish.libips:
|
|||
|
||||
test:
|
||||
# Phony target (prerequisite of .PHONY).
|
||||
|
||||
# Implicit rule search has not been done.
|
||||
# File does not exist.
|
||||
# File has not been updated.
|
||||
|
|
@ -323,12 +275,12 @@ release:
|
|||
|
||||
# No general ('VPATH' variable) search path.
|
||||
|
||||
# strcache buffers: 1 (0) / strings = 37 / storage = 350 B / avg = 9 B
|
||||
# current buf: size = 8162 B / used = 350 B / count = 37 / avg = 9 B
|
||||
# strcache buffers: 1 (0) / strings = 39 / storage = 371 B / avg = 9 B
|
||||
# current buf: size = 8162 B / used = 371 B / count = 39 / avg = 9 B
|
||||
|
||||
# strcache performance: lookups = 57 / hit rate = 35%
|
||||
# strcache performance: lookups = 59 / hit rate = 33%
|
||||
# hash-table stats:
|
||||
# Load=37/8192=0%, Rehash=0, Collisions=0/57=0%
|
||||
# Finished Make data base on Thu Sep 1 15:11:07 2022
|
||||
# Load=39/8192=0%, Rehash=0, Collisions=0/59=0%
|
||||
# Finished Make data base on Fri Sep 2 20:28:38 2022
|
||||
|
||||
|
||||
|
|
|
|||
231
Cargo.lock
generated
231
Cargo.lock
generated
|
|
@ -52,35 +52,23 @@ version = "1.2.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
|
||||
dependencies = [
|
||||
"block-padding 0.1.5",
|
||||
"byte-tools",
|
||||
"byteorder",
|
||||
"generic-array 0.12.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
|
||||
dependencies = [
|
||||
"block-padding 0.2.1",
|
||||
"generic-array 0.14.4",
|
||||
"block-padding",
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-padding"
|
||||
version = "0.1.5"
|
||||
name = "block-buffer"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
|
||||
checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324"
|
||||
dependencies = [
|
||||
"byte-tools",
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -95,18 +83,6 @@ version = "3.6.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe"
|
||||
|
||||
[[package]]
|
||||
name = "byte-tools"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.0.1"
|
||||
|
|
@ -127,9 +103,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
|||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "3.2.16"
|
||||
version = "3.2.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3dbbb6653e7c55cc8595ad3e1f7be8f32aba4eb7ff7f0fd1163d4f3d137c0a9"
|
||||
checksum = "23b71c3ce99b7611011217b366d923f1d0a7e07a92bb2dbf1e84508c673ca3bd"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"bitflags",
|
||||
|
|
@ -144,9 +120,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "3.2.15"
|
||||
version = "3.2.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ba52acd3b0a5c33aeada5cdaa3267cdc7c594a98731d4268cdc1532f4264cb4"
|
||||
checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro-error",
|
||||
|
|
@ -180,6 +156,15 @@ version = "0.8.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b"
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc948ebb96241bb40ab73effeb80d9f93afaad49359d159a5e61be51619fe813"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cpuid-bool"
|
||||
version = "0.1.2"
|
||||
|
|
@ -196,12 +181,13 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.8.1"
|
||||
name = "crypto-common"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
|
||||
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
||||
dependencies = [
|
||||
"generic-array 0.12.4",
|
||||
"generic-array",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -210,9 +196,45 @@ version = "0.9.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
|
||||
dependencies = [
|
||||
"generic-array 0.14.4",
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506"
|
||||
dependencies = [
|
||||
"block-buffer 0.10.2",
|
||||
"crypto-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs"
|
||||
version = "4.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059"
|
||||
dependencies = [
|
||||
"dirs-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-sys"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"redox_users",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
|
||||
|
||||
[[package]]
|
||||
name = "encoding_rs"
|
||||
version = "0.8.28"
|
||||
|
|
@ -222,12 +244,6 @@ dependencies = [
|
|||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fake-simd"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.20"
|
||||
|
|
@ -334,15 +350,6 @@ dependencies = [
|
|||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.12.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.4"
|
||||
|
|
@ -552,9 +559,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.90"
|
||||
version = "0.2.132"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba4aede83fc3617411dc6993bc8c70919750c1c257c6ca6a502aed6e0e2394ae"
|
||||
checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5"
|
||||
|
||||
[[package]]
|
||||
name = "libips"
|
||||
|
|
@ -695,12 +702,6 @@ version = "1.13.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1"
|
||||
|
||||
[[package]]
|
||||
name = "opaque-debug"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
|
||||
|
||||
[[package]]
|
||||
name = "opaque-debug"
|
||||
version = "0.3.0"
|
||||
|
|
@ -764,18 +765,19 @@ checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
|
|||
|
||||
[[package]]
|
||||
name = "pest"
|
||||
version = "2.1.3"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
|
||||
checksum = "4b0560d531d1febc25a3c9398a62a71256c0178f2e3443baedd9ad4bb8c9deb4"
|
||||
dependencies = [
|
||||
"thiserror",
|
||||
"ucd-trie",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest_derive"
|
||||
version = "2.1.0"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0"
|
||||
checksum = "905708f7f674518498c1f8d644481440f476d39ca6ecae83319bba7c6c12da91"
|
||||
dependencies = [
|
||||
"pest",
|
||||
"pest_generator",
|
||||
|
|
@ -783,9 +785,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "pest_generator"
|
||||
version = "2.1.3"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55"
|
||||
checksum = "5803d8284a629cc999094ecd630f55e91b561a1d1ba75e233b00ae13b91a69ad"
|
||||
dependencies = [
|
||||
"pest",
|
||||
"pest_meta",
|
||||
|
|
@ -796,11 +798,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "pest_meta"
|
||||
version = "2.1.3"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d"
|
||||
checksum = "1538eb784f07615c6d9a8ab061089c6c54a344c5b4301db51990ca1c241e8c04"
|
||||
dependencies = [
|
||||
"maplit 1.0.2",
|
||||
"once_cell",
|
||||
"pest",
|
||||
"sha-1",
|
||||
]
|
||||
|
|
@ -841,6 +843,21 @@ dependencies = [
|
|||
name = "pkg6repo"
|
||||
version = "0.0.1-placeholder"
|
||||
|
||||
[[package]]
|
||||
name = "ports"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
"libips",
|
||||
"reqwest",
|
||||
"shellexpand",
|
||||
"specfile",
|
||||
"thiserror",
|
||||
"url",
|
||||
"which",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.10"
|
||||
|
|
@ -943,13 +960,24 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.6"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8270314b5ccceb518e7e578952f0b72b88222d02e8f77f5ecf7abbb673539041"
|
||||
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_users"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"redox_syscall",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.5.5"
|
||||
|
|
@ -1143,14 +1171,13 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "sha-1"
|
||||
version = "0.8.2"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df"
|
||||
checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f"
|
||||
dependencies = [
|
||||
"block-buffer 0.7.3",
|
||||
"digest 0.8.1",
|
||||
"fake-simd",
|
||||
"opaque-debug 0.2.3",
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"digest 0.10.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1163,7 +1190,7 @@ dependencies = [
|
|||
"cfg-if",
|
||||
"cpuid-bool",
|
||||
"digest 0.9.0",
|
||||
"opaque-debug 0.3.0",
|
||||
"opaque-debug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1175,7 +1202,16 @@ dependencies = [
|
|||
"block-buffer 0.9.0",
|
||||
"digest 0.9.0",
|
||||
"keccak",
|
||||
"opaque-debug 0.3.0",
|
||||
"opaque-debug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shellexpand"
|
||||
version = "2.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ccc8076840c4da029af4f87e4e8daeb0fca6b87bbb02e10cb60b791450e11e4"
|
||||
dependencies = [
|
||||
"dirs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1194,6 +1230,16 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "specfile"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"pest",
|
||||
"pest_derive",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.5.2"
|
||||
|
|
@ -1248,18 +1294,18 @@ checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb"
|
|||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.30"
|
||||
version = "1.0.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417"
|
||||
checksum = "3d0a539a918745651435ac7db7a18761589a94cd7e94cd56999f828bf73c8a57"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.30"
|
||||
version = "1.0.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b"
|
||||
checksum = "c251e90f708e16c49a16f4917dc2131e75222b72edfa9cb7f7c58ae56aae0c09"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
@ -1377,9 +1423,9 @@ checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
|
|||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.13.0"
|
||||
version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06"
|
||||
checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
|
||||
|
||||
[[package]]
|
||||
name = "ucd-trie"
|
||||
|
|
@ -1580,6 +1626,17 @@ dependencies = [
|
|||
"webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "which"
|
||||
version = "4.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b"
|
||||
dependencies = [
|
||||
"either",
|
||||
"libc",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ members = [
|
|||
"pkg6dev",
|
||||
"pkg6repo",
|
||||
"userland",
|
||||
"specfile",
|
||||
"ports",
|
||||
]
|
||||
|
||||
|
||||
|
|
|
|||
19
Vagrantfile
vendored
Normal file
19
Vagrantfile
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# -*- mode: ruby -*-
|
||||
# vi: set ft=ruby :
|
||||
Vagrant.configure("2") do |config|
|
||||
config.vm.box = "openindiana/hipster"
|
||||
|
||||
config.vm.provision "shell", inline: <<-SHELL
|
||||
set -ex
|
||||
pkg install -v system/library/gcc-4-runtime build-essential system/library/g++-4-runtime jq
|
||||
mkdir /ws
|
||||
chown vagrant:vagrant /ws
|
||||
zfs create -o mountpoint=/zones rpool/zones
|
||||
SHELL
|
||||
|
||||
config.vm.provision "shell", privileged: false, inline: <<-SHELL
|
||||
set -ex
|
||||
chmod 664 $HOME/.bashrc
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | bash -s -- --profile complete -y
|
||||
SHELL
|
||||
end
|
||||
|
|
@ -7,14 +7,35 @@
|
|||
|
||||
use std::collections::{HashMap};
|
||||
use std::fs::{read_to_string};
|
||||
use crate::payload::Payload;
|
||||
use crate::payload::{Payload, PayloadError};
|
||||
use std::clone::Clone;
|
||||
use crate::digest::Digest;
|
||||
use std::str::FromStr;
|
||||
use std::path::{Path};
|
||||
use anyhow::{anyhow, Result};
|
||||
use pest::Parser;
|
||||
use pest_derive::Parser;
|
||||
use thiserror::Error;
|
||||
use std::result::Result as StdResult;
|
||||
|
||||
type Result<T> = StdResult<T, ActionError>;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ActionError {
|
||||
#[error("payload error: {0}")]
|
||||
PayloadError(#[from] PayloadError),
|
||||
|
||||
#[error("file action error: {0}")]
|
||||
FileError(#[from] FileError),
|
||||
|
||||
#[error("value {0} is not a boolean")]
|
||||
NotBooleanValue(String),
|
||||
|
||||
#[error("io error: {0}")]
|
||||
IOError(#[from] std::io::Error),
|
||||
|
||||
#[error("parser error: {0}")]
|
||||
ParserError(#[from] pest::error::Error<Rule>)
|
||||
}
|
||||
|
||||
pub trait FacetedAction {
|
||||
// Add a facet to the action if the facet is already present the function returns false.
|
||||
|
|
@ -615,6 +636,6 @@ fn string_to_bool(orig: &str) -> Result<bool> {
|
|||
"false" => Ok(false),
|
||||
"t" => Ok(true),
|
||||
"f" => Ok(false),
|
||||
_ => Err(anyhow!("not a boolean like value"))
|
||||
_ => Err(ActionError::NotBooleanValue(orig.clone().to_owned()))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,12 +4,14 @@
|
|||
// obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
use thiserror::Error;
|
||||
use anyhow::Result;
|
||||
use std::result::Result as StdResult;
|
||||
use std::str::FromStr;
|
||||
use sha2::{Digest as Sha2Digest};
|
||||
#[allow(unused_imports)]
|
||||
use sha3::{Digest as Sha3Digest};
|
||||
|
||||
type Result<T> = StdResult<T, DigestError>;
|
||||
|
||||
#[allow(dead_code)]
|
||||
static DEFAULT_ALGORITHM: DigestAlgorithm = DigestAlgorithm::SHA512;
|
||||
|
||||
|
|
@ -52,7 +54,7 @@ pub struct Digest {
|
|||
impl FromStr for Digest {
|
||||
type Err = DigestError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
fn from_str(s: &str) -> StdResult<Self, Self::Err> {
|
||||
let str = String::from(s);
|
||||
if !s.contains(":") {
|
||||
return Ok(Digest{
|
||||
|
|
|
|||
|
|
@ -7,10 +7,6 @@ pub mod actions;
|
|||
pub mod digest;
|
||||
pub mod payload;
|
||||
|
||||
extern crate pest;
|
||||
#[macro_use] extern crate pest_derive;
|
||||
extern crate maplit;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
|
|
|
|||
|
|
@ -3,10 +3,22 @@
|
|||
// MPL was not distributed with this file, You can
|
||||
// obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
use crate::digest::{Digest, DigestAlgorithm, DigestSource};
|
||||
use anyhow::Error;
|
||||
use crate::digest::{Digest, DigestAlgorithm, DigestSource, DigestError};
|
||||
use object::Object;
|
||||
use std::path::Path;
|
||||
use thiserror::Error;
|
||||
use std::result::Result as StdResult;
|
||||
use std::io::Error as IOError;
|
||||
|
||||
type Result<T> = StdResult<T, PayloadError>;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum PayloadError {
|
||||
#[error("io error: {0}")]
|
||||
IOError(#[from] IOError),
|
||||
#[error("digest error: {0}")]
|
||||
DigestError(#[from] DigestError),
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub enum PayloadCompressionAlgorithm {
|
||||
|
|
@ -56,7 +68,7 @@ impl Payload {
|
|||
self.architecture == PayloadArchitecture::NOARCH && self.bitness == PayloadBits::Independent
|
||||
}
|
||||
|
||||
pub fn compute_payload(path: &Path) -> Result<Self, Error> {
|
||||
pub fn compute_payload(path: &Path) -> Result<Self> {
|
||||
let f = std::fs::read(path)?;
|
||||
|
||||
let (bitness, architecture) = match object::File::parse(f.as_slice()) {
|
||||
|
|
|
|||
1
oi-userland
Submodule
1
oi-userland
Submodule
|
|
@ -0,0 +1 @@
|
|||
Subproject commit ca81f7dcc5ea1029defff41dbd9548940e8ba29a
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
use clap::{Parser, Subcommand};
|
||||
use libips::actions::{File, Manifest};
|
||||
use libips::actions::{File, Manifest, ActionError};
|
||||
|
||||
use anyhow::{Result};
|
||||
use std::collections::HashMap;
|
||||
|
|
@ -93,7 +93,7 @@ fn diff_component(
|
|||
.as_ref()
|
||||
.join("manifests/sample-manifest.p5m");
|
||||
|
||||
let manifests_res: Result<Vec<Manifest>> = manifest_files
|
||||
let manifests_res: Result<Vec<Manifest>, ActionError> = manifest_files
|
||||
.iter()
|
||||
.map(|f| Manifest::parse_file(f.to_string()))
|
||||
.collect();
|
||||
|
|
|
|||
27
ports.spec
Normal file
27
ports.spec
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
Name: ports
|
||||
Version: 0.1.0
|
||||
Release: 0
|
||||
Summary: Portable Software compilation System
|
||||
License: MPL-2.0
|
||||
VCS: https://github.com/OpenFlowLabs/ports.git
|
||||
|
||||
%description
|
||||
The ports Postable Software compilation system is a parser and interpreter for
|
||||
build instructions made in the Specfile format. It is inspired but not exactly
|
||||
equal to RPM. Mainly because it implements additional features such as git support
|
||||
and add more convinience commands usefull for packaging. It is mainly based on knowledge
|
||||
gained working with oi-userland and designed to make the proces of that system more
|
||||
automated/better.
|
||||
|
||||
%prep
|
||||
# Cargo or git will be automatially prepared
|
||||
|
||||
%build
|
||||
cargo install --path . --target-dir %{source_dir}/cargo --root %{proto_dir}/usr --bins
|
||||
|
||||
%files
|
||||
/usr/bin/ports
|
||||
|
||||
%changelog
|
||||
* Sat Apr 03 2020 Till Wegmueller <toasterson@gmail.com> 0.1.0-0
|
||||
- Initial RPM release
|
||||
18
ports/Cargo.toml
Normal file
18
ports/Cargo.toml
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
[package]
|
||||
name = "ports"
|
||||
version = "0.1.0"
|
||||
authors = ["Till Wegmueller <toasterson@gmail.com>"]
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.59"
|
||||
clap = {version = "3.2.16", features = [ "derive", "env" ] }
|
||||
specfile = {path = "../specfile"}
|
||||
shellexpand = "2.1.2"
|
||||
url = { version = "2.2.2", features = ["serde"]}
|
||||
reqwest = { version = "0.11", features = ["blocking"] }
|
||||
which = "4.3.0"
|
||||
libips = {path = "../libips"}
|
||||
thiserror = "*"
|
||||
93
ports/src/main.rs
Normal file
93
ports/src/main.rs
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
mod workspace;
|
||||
mod sources;
|
||||
|
||||
use anyhow::anyhow;
|
||||
use clap::{Parser, Subcommand};
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use specfile::parse;
|
||||
use specfile::macros;
|
||||
use std::collections::HashMap;
|
||||
use crate::workspace::Workspace;
|
||||
use anyhow::Result;
|
||||
|
||||
enum Verbose{
|
||||
Off,
|
||||
Some,
|
||||
On,
|
||||
Debug
|
||||
}
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
#[clap(version)]
|
||||
struct Cli {
|
||||
#[clap(subcommand)]
|
||||
pub command: Commands,
|
||||
|
||||
#[clap(short, long, env)]
|
||||
pub config: Option<PathBuf>,
|
||||
|
||||
#[clap(short, parse(from_occurrences))]
|
||||
pub verbose: i8,
|
||||
}
|
||||
|
||||
#[derive(Debug, Subcommand)]
|
||||
enum Commands {
|
||||
Package {
|
||||
#[clap(short, long)]
|
||||
target: PathBuf,
|
||||
|
||||
#[clap(value_parser)]
|
||||
specfile: PathBuf,
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let cli: Cli = Cli::parse();
|
||||
|
||||
if let Some(c) = cli.config {
|
||||
println!("Value for config: {}", c.display());
|
||||
}
|
||||
|
||||
let _verbose = match cli.verbose {
|
||||
0 => Verbose::Off,
|
||||
1 => Verbose::Some,
|
||||
2 => Verbose::On,
|
||||
3 | _ => Verbose::Debug,
|
||||
};
|
||||
|
||||
match cli.command {
|
||||
Commands::Package { target, specfile } => {
|
||||
run_package_command(specfile, target)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run_package_command<P: AsRef<Path>>(spec_file: P, _target: P) -> Result<()> {
|
||||
let content_string = fs::read_to_string(spec_file)?;
|
||||
let spec = parse(content_string)?;
|
||||
let mut ws = Workspace::new("")?;
|
||||
let downloaded = ws.get_sources(spec.sources)?;
|
||||
ws.unpack_all_sources(downloaded)?;
|
||||
|
||||
let mut macro_map= HashMap::<String, String>::new();
|
||||
for ws_macro in ws.get_macros() {
|
||||
macro_map.insert(
|
||||
ws_macro.0,
|
||||
ws_macro.1.to_str().ok_or(anyhow!("not string path {}", ws_macro.1.display()))?.to_owned()
|
||||
);
|
||||
}
|
||||
|
||||
let mp = macros::MacroParser {
|
||||
macros: macro_map
|
||||
};
|
||||
|
||||
let build_script = mp.parse(spec.build_script)?;
|
||||
ws.build(build_script)?;
|
||||
ws.package(spec.files)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
43
ports/src/sources.rs
Normal file
43
ports/src/sources.rs
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
use url::{Url, ParseError};
|
||||
use thiserror::Error;
|
||||
use std::{result::Result as StdResult, path::{Path, PathBuf}, fmt::Display};
|
||||
|
||||
type Result<T> = StdResult<T, SourceError>;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum SourceError {
|
||||
#[error("can't create source from url: {0}")]
|
||||
CantCreateSource(String),
|
||||
#[error("can not parse source url: {0}")]
|
||||
UrlParseError(#[from]ParseError)
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Source {
|
||||
pub url: Url,
|
||||
pub local_name: PathBuf,
|
||||
}
|
||||
|
||||
impl Display for Source {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", self.local_name.display())
|
||||
}
|
||||
}
|
||||
|
||||
impl Source {
|
||||
pub fn new<P: AsRef<Path>>(url_string: &str, local_base: P) -> Result<Source> {
|
||||
let url = Url::parse(url_string)?;
|
||||
let path = url.path().to_owned();
|
||||
let path_vec: Vec<_> = path.split("/").collect();
|
||||
match path_vec.last() {
|
||||
Some(str) => {
|
||||
let local_name = str.clone();
|
||||
Ok(Source {
|
||||
url,
|
||||
local_name: local_base.as_ref().join(local_name),
|
||||
})
|
||||
}
|
||||
None => Err(SourceError::CantCreateSource(url.into()))?
|
||||
}
|
||||
}
|
||||
}
|
||||
215
ports/src/workspace.rs
Normal file
215
ports/src/workspace.rs
Normal file
|
|
@ -0,0 +1,215 @@
|
|||
use std::fs::{create_dir_all, File};
|
||||
use crate::sources::{Source, SourceError};
|
||||
use std::process::{Command, Stdio};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::io::copy;
|
||||
use std::collections::HashMap;
|
||||
use std::io::prelude::*;
|
||||
use std::env;
|
||||
use libips::actions::{Manifest, File as FileAction, ActionError};
|
||||
use std::env::{set_current_dir, current_dir};
|
||||
use thiserror::Error;
|
||||
use std::result::Result as StdResult;
|
||||
use std::io::Error as IOError;
|
||||
|
||||
type Result<T> = StdResult<T, WorkspaceError>;
|
||||
|
||||
static DEFAULTWORKSPACEROOT: &str = "~/.ports/wks";
|
||||
static DEFAULTARCH: &str = "i386";
|
||||
static DEFAULTTAR: &str = "gtar";
|
||||
static DEFAULTSHEBANG: &'static [u8; 19usize] = b"#!/usr/bin/env bash";
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum WorkspaceError {
|
||||
#[error("command returned {command} exit code: {code}")]
|
||||
NonZeroCommandExitCode {
|
||||
command: String,
|
||||
code: i32,
|
||||
},
|
||||
#[error("source {0} cannot be extracted")]
|
||||
UnextractableSource(Source),
|
||||
#[error("status code invalid")]
|
||||
InvalidStatusCode,
|
||||
#[error("source {0} has no extension")]
|
||||
SourceHasNoExtension(Source),
|
||||
#[error("io error: {0}")]
|
||||
IOError(#[from] IOError),
|
||||
#[error("could not lookup variable {0}")]
|
||||
VariableLookupError(String),
|
||||
#[error("source error: {0}")]
|
||||
SourceError(#[from] SourceError),
|
||||
#[error("reqwest error: {0}")]
|
||||
ReqwestError(#[from] reqwest::Error),
|
||||
#[error("unrunable script {0}")]
|
||||
UnrunableScript(String),
|
||||
#[error("path lookup error: {0}")]
|
||||
PathLookupError(#[from] which::Error),
|
||||
#[error("ips action error: {0}")]
|
||||
IpsActionError(#[from] ActionError),
|
||||
}
|
||||
|
||||
|
||||
pub struct Workspace {
|
||||
root: PathBuf,
|
||||
source_dir: PathBuf,
|
||||
build_dir: PathBuf,
|
||||
proto_dir: PathBuf,
|
||||
}
|
||||
|
||||
fn init_root(ws: &Workspace) -> Result<()> {
|
||||
create_dir_all(&ws.root)?;
|
||||
create_dir_all(&ws.build_dir)?;
|
||||
create_dir_all(&ws.source_dir)?;
|
||||
create_dir_all(&ws.proto_dir)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
impl Workspace {
|
||||
pub fn new(root: &str) -> Result<Workspace> {
|
||||
|
||||
let root_dir = if root == "" {
|
||||
DEFAULTWORKSPACEROOT
|
||||
} else {
|
||||
root
|
||||
};
|
||||
|
||||
let expanded_root_dir = shellexpand::full(root_dir).map_err(|e|{
|
||||
WorkspaceError::VariableLookupError(format!("{}", e.cause))
|
||||
})?.to_string();
|
||||
|
||||
let ws = Workspace{
|
||||
root: Path::new(&expanded_root_dir).to_path_buf(),
|
||||
build_dir: Path::new(&expanded_root_dir).join("build").join(DEFAULTARCH),
|
||||
source_dir: Path::new(&expanded_root_dir).join("sources"),
|
||||
proto_dir: Path::new(&expanded_root_dir).join("build").join("proto"),
|
||||
};
|
||||
|
||||
init_root(&ws)?;
|
||||
|
||||
Ok(ws)
|
||||
}
|
||||
|
||||
pub fn expand_source_path(&self, fname: &str) -> PathBuf {
|
||||
self.source_dir.join(fname)
|
||||
}
|
||||
|
||||
pub fn get_proto_dir(&self) -> PathBuf {
|
||||
self.proto_dir.clone()
|
||||
}
|
||||
|
||||
pub fn get_build_dir(&self) -> PathBuf {
|
||||
self.build_dir.clone()
|
||||
}
|
||||
|
||||
pub fn get_macros(&self) -> HashMap<String, PathBuf> {
|
||||
[
|
||||
("proto_dir".to_owned(), self.proto_dir.clone()),
|
||||
("build_dir".to_owned(), self.build_dir.clone()),
|
||||
("source_dir".to_owned(), self.source_dir.clone()),
|
||||
].into()
|
||||
}
|
||||
|
||||
pub fn get_sources(&self, sources: Vec<String>) -> Result<Vec<Source>> {
|
||||
let mut src_vec: Vec<Source> = vec![];
|
||||
for src in sources {
|
||||
let src_struct = Source::new(&src, &self.source_dir)?;
|
||||
let bytes = reqwest::blocking::get(src_struct.url.as_str())?.bytes()?;
|
||||
let mut out = File::create(&src_struct.local_name)?;
|
||||
copy(&mut bytes.as_ref(), &mut out)?;
|
||||
|
||||
src_vec.push(src_struct);
|
||||
}
|
||||
|
||||
Ok(src_vec)
|
||||
}
|
||||
|
||||
pub fn unpack_all_sources(&self, sources: Vec<Source>) -> Result<()> {
|
||||
for src in sources {
|
||||
self.unpack_source(&src)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn unpack_source(&self, src: &Source) -> Result<()> {
|
||||
match Path::new(&src.local_name).extension() {
|
||||
Some(ext) => {
|
||||
if !ext.to_str().ok_or(WorkspaceError::SourceHasNoExtension(src.clone()))?.contains("tar") {
|
||||
return Err(WorkspaceError::UnextractableSource(src.clone()));
|
||||
}
|
||||
//TODO support inspecting the tar file to see if we have a top level directory or not
|
||||
let mut tar_cmd = Command::new(DEFAULTTAR)
|
||||
.args([
|
||||
"-C",
|
||||
&self.build_dir.to_str().ok_or(WorkspaceError::UnextractableSource(src.clone()))?,
|
||||
"-xaf", &src.local_name.to_str().ok_or(WorkspaceError::UnextractableSource(src.clone()))?,
|
||||
"--strip-components=1"
|
||||
])
|
||||
.spawn()?;
|
||||
|
||||
let status = tar_cmd.wait()?;
|
||||
if !status.success() {
|
||||
return Err(WorkspaceError::NonZeroCommandExitCode {command: "tar".to_owned(), code: status.code().ok_or(WorkspaceError::InvalidStatusCode)?})?;
|
||||
}
|
||||
}
|
||||
None => {
|
||||
return Err(WorkspaceError::UnextractableSource(src.clone()));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn build(&self, build_script: String) -> Result<()> {
|
||||
let build_script_path = self.build_dir.join("build_script.sh");
|
||||
let mut file = File::create(&build_script_path)?;
|
||||
file.write_all(DEFAULTSHEBANG)?;
|
||||
file.write_all(b"\n")?;
|
||||
file.write_all(build_script.as_bytes())?;
|
||||
file.write_all(b"\n")?;
|
||||
let bash = which::which("bash")?;
|
||||
let filtered_env : HashMap<String, String> =
|
||||
env::vars().filter(|&(ref k, _)|
|
||||
k == "TERM" || k == "TZ" || k == "LANG" || k == "PATH"
|
||||
).collect();
|
||||
|
||||
let mut shell = Command::new(bash)
|
||||
.args([
|
||||
"-ex",
|
||||
&build_script_path.to_str().ok_or(WorkspaceError::UnrunableScript("build_script".into()))?
|
||||
])
|
||||
.env_clear()
|
||||
.envs(&filtered_env)
|
||||
.stdout(Stdio::inherit())
|
||||
.stderr(Stdio::inherit())
|
||||
.spawn()?;
|
||||
|
||||
let status = shell.wait()?;
|
||||
if !status.success() {
|
||||
return Err(WorkspaceError::NonZeroCommandExitCode {command: "build_script".to_owned(), code: status.code().ok_or(WorkspaceError::InvalidStatusCode)?})?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn package(&self, file_list: Vec<String>) -> Result<()> {
|
||||
let mut manifest = Manifest::default();
|
||||
let cwd = current_dir()?;
|
||||
set_current_dir(Path::new(&self.proto_dir))?;
|
||||
for f in file_list {
|
||||
if f.starts_with("/") {
|
||||
let mut f_mut = f.clone();
|
||||
f_mut.remove(0);
|
||||
manifest.add_file(FileAction::read_from_path(Path::new(&f_mut))?)
|
||||
} else {
|
||||
manifest.add_file(FileAction::read_from_path(Path::new(&f))?)
|
||||
}
|
||||
}
|
||||
set_current_dir(cwd)?;
|
||||
|
||||
println!("{:?}", manifest);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
13
specfile/Cargo.toml
Normal file
13
specfile/Cargo.toml
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
[package]
|
||||
name = "specfile"
|
||||
version = "0.1.0"
|
||||
authors = ["Till Wegmueller <toasterson@gmail.com>"]
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
pest = "2.3.0"
|
||||
pest_derive = "2.3.0"
|
||||
anyhow = "1.0.59"
|
||||
thiserror = "*"
|
||||
164
specfile/src/lib.rs
Normal file
164
specfile/src/lib.rs
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
pub mod macros;
|
||||
|
||||
use pest::Parser;
|
||||
use pest_derive::Parser;
|
||||
use std::collections::HashMap;
|
||||
use anyhow::{Result};
|
||||
|
||||
#[derive(Parser)]
|
||||
#[grammar = "specfile.pest"]
|
||||
struct SpecFileParser;
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
pub struct SpecFile {
|
||||
pub name: String,
|
||||
pub version: String,
|
||||
pub release: String,
|
||||
pub summary: String,
|
||||
pub license: String,
|
||||
pub sources: Vec<String>,
|
||||
pub variables: HashMap<String, String>,
|
||||
pub description: String,
|
||||
pub prep_script: String,
|
||||
pub build_script: String,
|
||||
pub install_script: String,
|
||||
pub files: Vec<String>,
|
||||
pub changelog: String,
|
||||
}
|
||||
|
||||
enum KnownVariableControl {
|
||||
Name,
|
||||
Version,
|
||||
Release,
|
||||
Summary,
|
||||
License,
|
||||
None,
|
||||
}
|
||||
|
||||
fn append_newline_string(s: &str, section_line: i32) -> String {
|
||||
if section_line == 0 {
|
||||
return s.to_owned();
|
||||
}
|
||||
return "\n".to_owned() + s;
|
||||
}
|
||||
|
||||
pub fn parse(file_contents: String) -> Result<SpecFile> {
|
||||
let pairs = SpecFileParser::parse(Rule::file, &file_contents)?;
|
||||
let mut spec = SpecFile::default();
|
||||
|
||||
|
||||
for pair in pairs {
|
||||
// A pair can be converted to an iterator of the tokens which make it up:
|
||||
match pair.as_rule() {
|
||||
Rule::variable => {
|
||||
let mut var_control = KnownVariableControl::None;
|
||||
let mut var_name_tmp = String::new();
|
||||
for variable_rule in pair.clone().into_inner() {
|
||||
match variable_rule.as_rule() {
|
||||
Rule::variable_name => {
|
||||
match variable_rule.as_str() {
|
||||
"Name" => var_control = KnownVariableControl::Name,
|
||||
"Version" => var_control = KnownVariableControl::Version,
|
||||
"Release" => var_control = KnownVariableControl::Release,
|
||||
"Summary" => var_control = KnownVariableControl::Summary,
|
||||
"License" => var_control = KnownVariableControl::License,
|
||||
_ => var_control = {
|
||||
var_name_tmp = variable_rule.as_str().to_string();
|
||||
KnownVariableControl::None
|
||||
},
|
||||
}
|
||||
}
|
||||
Rule::variable_text => {
|
||||
match var_control {
|
||||
KnownVariableControl::Name => spec.name = variable_rule.as_str().to_string(),
|
||||
KnownVariableControl::Version => spec.version = variable_rule.as_str().to_string(),
|
||||
KnownVariableControl::Release => spec.release = variable_rule.as_str().to_string(),
|
||||
KnownVariableControl::Summary =>spec.summary = variable_rule.as_str().to_string(),
|
||||
KnownVariableControl::License => spec.license = variable_rule.as_str().to_string(),
|
||||
KnownVariableControl::None => {
|
||||
spec.variables.insert(var_name_tmp.clone(), variable_rule.as_str().to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
}
|
||||
Rule::section => {
|
||||
let mut section_name_tmp = String::new();
|
||||
let mut section_line = 0;
|
||||
for section_rule in pair.clone().into_inner() {
|
||||
match section_rule.as_rule() {
|
||||
Rule::section_name => {
|
||||
section_name_tmp = section_rule.as_str().to_string()
|
||||
}
|
||||
Rule::section_line => {
|
||||
for line_or_comment in section_rule.into_inner() {
|
||||
match line_or_comment.as_rule() {
|
||||
Rule::section_text => {
|
||||
match section_name_tmp.as_str() {
|
||||
"description" => {
|
||||
spec.description.push_str(append_newline_string(line_or_comment.as_str(), section_line).as_str());
|
||||
section_line = section_line + 1
|
||||
},
|
||||
"prep" => {
|
||||
spec.prep_script.push_str(append_newline_string(line_or_comment.as_str(), section_line).as_str());
|
||||
section_line = section_line + 1
|
||||
},
|
||||
"build" => {
|
||||
spec.build_script.push_str(append_newline_string(line_or_comment.as_str(), section_line).as_str());
|
||||
section_line = section_line + 1
|
||||
},
|
||||
"files" => spec.files.push(line_or_comment.as_str().trim_end().to_string()),
|
||||
"install" => {
|
||||
spec.install_script.push_str(append_newline_string(line_or_comment.as_str(), section_line).as_str());
|
||||
section_line = section_line + 1
|
||||
},
|
||||
"changelog" => {
|
||||
spec.changelog.push_str(append_newline_string(line_or_comment.as_str(), section_line).as_str());
|
||||
section_line = section_line + 1
|
||||
},
|
||||
_ => panic!(
|
||||
"Unknown Section: {:?}",
|
||||
line_or_comment.as_rule()
|
||||
),
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => panic!("Rule not known please update the code: {:?}", section_rule.as_rule()),
|
||||
}
|
||||
}
|
||||
}
|
||||
Rule::EOI => (),
|
||||
_ => panic!("Rule not known please update the code: {:?}", pair.as_rule()),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(spec)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::fs;
|
||||
use crate::parse;
|
||||
|
||||
#[test]
|
||||
fn it_works() {
|
||||
assert_eq!(2 + 2, 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let contents = fs::read_to_string("src/test_data/simple.spec");
|
||||
match contents {
|
||||
Ok(file) => {
|
||||
let spec = parse(file);
|
||||
assert!(spec.is_ok(), "parsing error {:?}", spec)
|
||||
},
|
||||
Err(e) => panic!("io error: {:}", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
19
specfile/src/macro.pest
Normal file
19
specfile/src/macro.pest
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
WHITESPACE = _{ " " | "\t" }
|
||||
char = { ASCII_ALPHANUMERIC | "." | "_" | "/" | "-" | "=" | ">" | "<" | "!" | "'" | "#" | "\"" }
|
||||
text = @{ char+ | WHITESPACE | NEWLINE }
|
||||
env_variable_char = { 'A'..'Z' | '0'..'9' }
|
||||
|
||||
macro_parameter = @{char+}
|
||||
macro_name = @{char+}
|
||||
macro_parameters = _{ ("," | macro_parameter)* }
|
||||
spec_macro_without_parameters = _{"%{" ~ macro_name ~ "}" | "%" ~ macro_name}
|
||||
spec_macro_with_parameters = _{"%{" ~ macro_name ~ "("~macro_parameters~")" ~ "}" | "%" ~ macro_name ~ "("~macro_parameters~")"}
|
||||
spec_macro = { (spec_macro_with_parameters|spec_macro_without_parameters) }
|
||||
spec_optional_macro = @{ "%{?" ~ char+ ~ "}" }
|
||||
function = { "%(" ~ (spec_macro | spec_optional_macro | text)* ~ ")" }
|
||||
text_with_macros = { function | spec_macro | spec_optional_macro }
|
||||
|
||||
file = {SOI ~ text* ~ (text | text_with_macros)+ ~ text* ~ EOI}
|
||||
|
||||
env_variable = @{"$" ~ (env_variable_char | "_")+}
|
||||
|
||||
99
specfile/src/macros.rs
Normal file
99
specfile/src/macros.rs
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
use pest::Parser;
|
||||
use pest_derive::Parser;
|
||||
use std::collections::HashMap;
|
||||
use thiserror::Error;
|
||||
use anyhow::Result;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum MacroParserError {
|
||||
#[error("macro does not exist: {macro_name}")]
|
||||
DoesNotExist {
|
||||
macro_name: String,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Parser)]
|
||||
#[grammar = "macro.pest"]
|
||||
struct InternalMacroParser;
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
pub struct MacroParser {
|
||||
pub macros: HashMap<String, String>
|
||||
}
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
pub struct Macro {
|
||||
pub name: String,
|
||||
pub parameters: Vec<String>
|
||||
}
|
||||
|
||||
impl MacroParser {
|
||||
pub fn parse(&self ,raw_string: String) -> Result<String> {
|
||||
let mut return_string = String::new();
|
||||
|
||||
for (i, line) in raw_string.lines().enumerate() {
|
||||
let mut replaced_line = String::new();
|
||||
let pairs = InternalMacroParser::parse(Rule::file, &line)?;
|
||||
|
||||
for pair in pairs {
|
||||
for test_pair in pair.into_inner() {
|
||||
match test_pair.as_rule() {
|
||||
Rule::text_with_macros => {
|
||||
for inner in test_pair.into_inner() {
|
||||
match inner.as_rule() {
|
||||
Rule::spec_macro => {
|
||||
for macro_pair in inner.clone().into_inner() {
|
||||
match macro_pair.as_rule() {
|
||||
Rule::macro_name => {
|
||||
replaced_line += self.get_variable(macro_pair.as_str())?;
|
||||
},
|
||||
Rule::macro_parameter => {
|
||||
println!("macro parameter: {}", macro_pair.as_str())
|
||||
},
|
||||
_ => panic!(
|
||||
"Unexpected macro match please update the code together with the peg grammar: {:?}",
|
||||
macro_pair.as_rule()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => panic!(
|
||||
"Unexpected inner match please update the code together with the peg grammar: {:?}",
|
||||
inner.as_rule()
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
Rule::EOI => (),
|
||||
Rule::text => {
|
||||
replaced_line += test_pair.as_str();
|
||||
replaced_line += " ";
|
||||
},
|
||||
_ => panic!(
|
||||
"Unexpected match please update the code together with the peg grammar: {:?}",
|
||||
test_pair.as_rule()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
replaced_line = replaced_line.trim_end().to_owned();
|
||||
|
||||
if i == 0 {
|
||||
return_string += &replaced_line;
|
||||
} else {
|
||||
return_string += "\n";
|
||||
return_string += &replaced_line;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(return_string)
|
||||
}
|
||||
|
||||
fn get_variable(&self, macro_name: &str) -> Result<&str> {
|
||||
if self.macros.contains_key(macro_name) {
|
||||
return Ok(self.macros[macro_name].as_str())
|
||||
}
|
||||
Err(MacroParserError::DoesNotExist {macro_name: macro_name.into()})?
|
||||
}
|
||||
}
|
||||
|
||||
22
specfile/src/specfile.pest
Normal file
22
specfile/src/specfile.pest
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
alpha = { 'a'..'z' | 'A'..'Z' }
|
||||
digit = { '0'..'9' }
|
||||
uppercase = { 'A'..'Z' }
|
||||
char = { ASCII_ALPHANUMERIC | "," | "." | "_" | "/" | "-" | "=" | ">" | "<" | "!" | "'" | "#" | ":" | "{" | "}" | "%" | "*" | "@" | "\"" }
|
||||
WHITESPACE = _{ " " | "\t" }
|
||||
text = @{ char+ | WHITESPACE }
|
||||
variable_name = @{uppercase ~ alpha+ ~ digit*}
|
||||
variable_text = @{ text+ }
|
||||
variable = {variable_name ~ ":" ~ variable_text }
|
||||
empty_variable = {variable_name ~ ":" }
|
||||
multiline_variable = {variable_name ~ ":" ~ NEWLINE? ~ (text ~ NEWLINE)+ }
|
||||
section_text = @{ text+ }
|
||||
comment_line = @{ "#" ~ section_text }
|
||||
section_line = { comment_line ~ NEWLINE | section_text ~ NEWLINE }
|
||||
section_name = @{ (ASCII_ALPHA_LOWER | ASCII_DIGIT)+ }
|
||||
section = {"%" ~ section_name ~ NEWLINE ~ section_line+ }
|
||||
|
||||
file = _{
|
||||
SOI ~
|
||||
(variable ~ NEWLINE+ | multiline_variable ~ NEWLINE+ | empty_variable ~ NEWLINE+ | section | NEWLINE )+ ~
|
||||
EOI
|
||||
}
|
||||
29
specfile/src/test_data/simple.spec
Normal file
29
specfile/src/test_data/simple.spec
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
Name: hello-world
|
||||
Version: 1
|
||||
Release: 1
|
||||
Summary: Most simple RPM package
|
||||
License: FIXME
|
||||
|
||||
%description
|
||||
This is my first RPM package, which does nothing.
|
||||
This is a second description line.
|
||||
|
||||
%prep
|
||||
# we have no source, so nothing here
|
||||
|
||||
%build
|
||||
cat > hello-world.sh <<EOF
|
||||
#!/usr/bin/bash
|
||||
echo Hello world
|
||||
EOF
|
||||
|
||||
%install
|
||||
mkdir -p %{buildroot}/usr/bin/
|
||||
install -m 755 hello-world.sh %{buildroot}/usr/bin/hello-world.sh
|
||||
|
||||
%files
|
||||
/usr/bin/hello-world.sh
|
||||
|
||||
%changelog
|
||||
# let's skip this for now
|
||||
|
||||
Loading…
Add table
Reference in a new issue