Adding ports and specfile crates. Switch to thiserror for libraries

This commit is contained in:
Till Wegmueller 2022-09-02 23:48:26 +02:00
parent 63b6a48341
commit 4ebecbd153
25 changed files with 990 additions and 180 deletions

3
.cargo/config.toml Normal file
View file

@ -0,0 +1,3 @@
[build]
#rustflags = ["-C", "link-arg=-fuse-ld=lld"]
target-dir = "/ws/target"

1
.gitignore vendored
View file

@ -90,3 +90,4 @@ Cargo.lock
# Prototype directory
sample_data/**/build/prototype/i386
.vagrant

3
.gitmodules vendored Normal file
View file

@ -0,0 +1,3 @@
[submodule "oi-userland"]
path = oi-userland
url = git@github.com:Toasterson/oi-userland.git

5
.vscode/dryrun.log vendored
View file

@ -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
View file

@ -6,29 +6,18 @@ make all --print-data-base --no-builtin-variables --no-builtin-rules --question
# 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
View file

@ -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"

View file

@ -6,6 +6,8 @@ members = [
"pkg6dev",
"pkg6repo",
"userland",
"specfile",
"ports",
]

19
Vagrantfile vendored Normal file
View 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

View file

@ -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()))
}
}

View file

@ -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{

View file

@ -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 {

View file

@ -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

@ -0,0 +1 @@
Subproject commit ca81f7dcc5ea1029defff41dbd9548940e8ba29a

View file

@ -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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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()})?
}
}

View 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
}

View 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