From 8ac62d17d0ac0d1ce65141c25e2dca0158a9e07e Mon Sep 17 00:00:00 2001 From: itsmanjeet Date: Thu, 20 Jun 2024 18:22:46 +0530 Subject: [PATCH] using pkgupd --- .vscode/settings.json | 73 --- Makefile | 28 +- elements/components/libyaml-cpp.yml | 4 +- .../components/{sysroot.yml => pkgupd.yml} | 5 +- elements/installer/image.yml | 80 ++- elements/system/deps.yml | 14 +- elements/system/image.yml | 58 ++ files/rofi/colors/default.rasi | 19 + files/rofi/themes/ApplicationLauncher.rasi | 161 ++++++ files/rofi/themes/Powermenu.rasi | 150 +++++ files/rofi/themes/QuickLauncher.rasi | 210 +++++++ files/scripts/Powermenu | 41 ++ files/scripts/StatusbarProvider | 118 ++++ files/sway/config | 38 ++ files/sway/config.d/autostart.conf | 27 + files/sway/config.d/background.conf | 1 + files/sway/config.d/bindings.conf | 84 +++ files/sway/config.d/color-scheme.conf | 6 + files/sway/config.d/defaults.conf | 7 + files/sway/config.d/devices.conf | 6 + files/sway/config.d/fonts.conf | 1 + files/sway/config.d/statusbar.conf | 12 + src/CMakeLists.txt | 3 +- src/ignite/ArchiveManager.cpp | 131 ----- src/ignite/ArchiveManager.h | 43 -- src/ignite/Builder.cpp | 537 ------------------ src/ignite/Builder.h | 79 --- src/ignite/CMakeLists.txt | 25 - src/ignite/Container.cpp | 43 -- src/ignite/Container.h | 41 -- src/ignite/Executor.cpp | 112 ---- src/ignite/Executor.h | 75 --- src/ignite/Ignite.cpp | 368 ------------ src/ignite/Ignite.h | 57 -- src/ignite/MetaInfo.cpp | 76 --- src/ignite/MetaInfo.h | 47 -- src/ignite/Resolver.h | 71 --- src/ignite/main.cpp | 165 ------ src/pkgupd | 1 + 39 files changed, 1009 insertions(+), 2008 deletions(-) delete mode 100644 .vscode/settings.json rename elements/components/{sysroot.yml => pkgupd.yml} (80%) create mode 100644 elements/system/image.yml create mode 100644 files/rofi/colors/default.rasi create mode 100644 files/rofi/themes/ApplicationLauncher.rasi create mode 100644 files/rofi/themes/Powermenu.rasi create mode 100644 files/rofi/themes/QuickLauncher.rasi create mode 100755 files/scripts/Powermenu create mode 100755 files/scripts/StatusbarProvider create mode 100644 files/sway/config create mode 100644 files/sway/config.d/autostart.conf create mode 100644 files/sway/config.d/background.conf create mode 100644 files/sway/config.d/bindings.conf create mode 100644 files/sway/config.d/color-scheme.conf create mode 100644 files/sway/config.d/defaults.conf create mode 100644 files/sway/config.d/devices.conf create mode 100644 files/sway/config.d/fonts.conf create mode 100644 files/sway/config.d/statusbar.conf delete mode 100644 src/ignite/ArchiveManager.cpp delete mode 100644 src/ignite/ArchiveManager.h delete mode 100644 src/ignite/Builder.cpp delete mode 100644 src/ignite/Builder.h delete mode 100644 src/ignite/CMakeLists.txt delete mode 100644 src/ignite/Container.cpp delete mode 100644 src/ignite/Container.h delete mode 100644 src/ignite/Executor.cpp delete mode 100644 src/ignite/Executor.h delete mode 100644 src/ignite/Ignite.cpp delete mode 100644 src/ignite/Ignite.h delete mode 100644 src/ignite/MetaInfo.cpp delete mode 100644 src/ignite/MetaInfo.h delete mode 100644 src/ignite/Resolver.h delete mode 100644 src/ignite/main.cpp create mode 160000 src/pkgupd diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index ebf97be5b..000000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,73 +0,0 @@ -{ - "files.associations": { - "any": "cpp", - "array": "cpp", - "atomic": "cpp", - "bit": "cpp", - "*.tcc": "cpp", - "bitset": "cpp", - "cctype": "cpp", - "chrono": "cpp", - "clocale": "cpp", - "cmath": "cpp", - "codecvt": "cpp", - "compare": "cpp", - "concepts": "cpp", - "condition_variable": "cpp", - "cstdarg": "cpp", - "cstddef": "cpp", - "cstdint": "cpp", - "cstdio": "cpp", - "cstdlib": "cpp", - "cstring": "cpp", - "ctime": "cpp", - "cwchar": "cpp", - "cwctype": "cpp", - "deque": "cpp", - "forward_list": "cpp", - "list": "cpp", - "map": "cpp", - "set": "cpp", - "string": "cpp", - "unordered_map": "cpp", - "vector": "cpp", - "exception": "cpp", - "algorithm": "cpp", - "functional": "cpp", - "iterator": "cpp", - "memory": "cpp", - "memory_resource": "cpp", - "numeric": "cpp", - "optional": "cpp", - "random": "cpp", - "ratio": "cpp", - "regex": "cpp", - "string_view": "cpp", - "system_error": "cpp", - "tuple": "cpp", - "type_traits": "cpp", - "utility": "cpp", - "fstream": "cpp", - "initializer_list": "cpp", - "iomanip": "cpp", - "iosfwd": "cpp", - "iostream": "cpp", - "istream": "cpp", - "limits": "cpp", - "mutex": "cpp", - "new": "cpp", - "numbers": "cpp", - "ostream": "cpp", - "ranges": "cpp", - "semaphore": "cpp", - "sstream": "cpp", - "stdexcept": "cpp", - "stop_token": "cpp", - "streambuf": "cpp", - "thread": "cpp", - "cinttypes": "cpp", - "typeinfo": "cpp", - "valarray": "cpp", - "variant": "cpp" - } -} \ No newline at end of file diff --git a/Makefile b/Makefile index 0cd6081d2..cd76e8fdb 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ OSTREE_BRANCH ?= $(shell uname -m)/os/$(CHANNEL) OSTREE_REPO ?= ostree-repo OSTREE_GPG ?= ostree-gpg VERSION ?= 2.0 -IGNITE ?= build/src/ignite/ignite +PKGUPD ?= build/src/pkgupd/bin/pkgupd CACHE_PATH ?= build/ DESTDIR ?= checkout/ APPMARKET_PATH ?= appmarket/ @@ -28,35 +28,35 @@ endef export OSTREE_GPG_CONFIG -export IGNITE +export PKGUPD export CACHE_PATH .PHONY: clean all docs version.yml channel.yml ostree-branch.yml apps -all: $(IGNITE) version.yml ostree-branch.yml channel.yml +all: $(PKGUPD) version.yml ostree-branch.yml channel.yml ifdef ELEMENT - $(IGNITE) cache-path=$(CACHE_PATH) build $(ELEMENT) + $(PKGUPD) ignite ignite.cache=$(CACHE_PATH) build $(ELEMENT) endif -status: $(IGNITE) version.yml ostree-branch.yml channel.yml +status: $(PKGUPD) version.yml ostree-branch.yml channel.yml ifdef ELEMENT - $(IGNITE) cache-path=$(CACHE_PATH) status $(ELEMENT) + $(PKGUPD) ignite ignite.cache=$(CACHE_PATH) status $(ELEMENT) else @echo "no ELEMENT specified" exit 1 endif -filepath: $(IGNITE) version.yml ostree-branch.yml channel.yml +filepath: $(PKGUPD) version.yml ostree-branch.yml channel.yml ifdef ELEMENT - @PKGUPD_NO_MESSAGE=1 $(IGNITE) cache-path=$(CACHE_PATH) filepath $(ELEMENT) + @PKGUPD_NO_MESSAGE=1 $(PKGUPD) ignite ignite.cache=$(CACHE_PATH) filepath $(ELEMENT) else @echo "no ELEMENT specified" exit 1 endif -checkout: $(IGNITE) version.yml ostree-branch.yml channel.yml +checkout: $(PKGUPD) version.yml ostree-branch.yml channel.yml ifdef ELEMENT - $(IGNITE) cache-path=$(CACHE_PATH) checkout $(ELEMENT) $(DESTDIR) + $(PKGUPD) ignite ignite.cache=$(CACHE_PATH) checkout $(ELEMENT) $(DESTDIR) else @echo "no ELEMENT specified" exit 1 @@ -66,8 +66,8 @@ endif build/build.ninja: CMakeLists.txt cmake -B build -$(IGNITE): build/build.ninja src/ignite/CMakeLists.txt - @cmake --build build --target ignite +$(PKGUPD): build/build.ninja src/pkgupd/CMakeLists.txt + @cmake --build build --target pkgupd clean: rm -rf $(DOCS_DIR) @@ -87,8 +87,8 @@ $(OSTREE_GPG)/key-config: files/rlxos.gpg: $(OSTREE_GPG)/key-config gpg --homedir=$(OSTREE_GPG) --export --armor >"$@" -update-app-market: $(IGNITE) version.yml ostree-branch.yml channel.yml - $(IGNITE) cache-path=$(CACHE_PATH) meta $(APPMARKET_PATH)/$(CHANNEL) +update-app-market: $(PKGUPD) version.yml ostree-branch.yml channel.yml + $(PKGUPD) ignite ignite.cache=$(CACHE_PATH) meta $(APPMARKET_PATH)/$(CHANNEL) ./scripts/extract-icons.sh $(APPMARKET_PATH)/$(CHANNEL)/apps/ $(APPMARKET_PATH)/$(CHANNEL)/icons/ update-ostree: files/rlxos.gpg diff --git a/elements/components/libyaml-cpp.yml b/elements/components/libyaml-cpp.yml index afb55974d..4ff6a20bf 100644 --- a/elements/components/libyaml-cpp.yml +++ b/elements/components/libyaml-cpp.yml @@ -6,14 +6,14 @@ configure: >- -DCMAKE_BUILD_TYPE=Release -DYAML_CPP_BUILD_TESTS=OFF -DYAML_CPP_BUILD_TOOLS=OFF - -DBUILD_SHARED_LIBS=ON - -DYAML_BUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release depends: - components/glibc.yml + build-depends: - components/cmake.yml - components/gcc.yml + sources: - https://github.com/jbeder/yaml-cpp/archive/yaml-cpp-%{version}.tar.gz diff --git a/elements/components/sysroot.yml b/elements/components/pkgupd.yml similarity index 80% rename from elements/components/sysroot.yml rename to elements/components/pkgupd.yml index 4b97f1b74..971f1a387 100644 --- a/elements/components/sysroot.yml +++ b/elements/components/pkgupd.yml @@ -1,5 +1,5 @@ -id: sysroot -version: 2.0.7 +id: pkgupd +version: 0.0.1 about: Package Management and Updater Daemon merge: [ elements/include/rlxos.inc ] @@ -7,7 +7,6 @@ depends: - components/glibc.yml - components/libyaml-cpp.yml - components/curl.yml - - components/ostree.yml build-depends: - components/git.yml diff --git a/elements/installer/image.yml b/elements/installer/image.yml index f1371642c..088edc5a6 100644 --- a/elements/installer/image.yml +++ b/elements/installer/image.yml @@ -1,12 +1,16 @@ id: ostree-installer -merge: [version.yml, ostree-branch.yml, elements/include/installer.inc] +merge: [version.yml, elements/include/installer.inc] about: OSTree Installer ISO include: - - system/repo.yml + - system/deps.yml + +capabilities: + - CAP_SYS_CHROOT + +include-root: /sysroot +include-parts: [ doc, devel ] -include-root: /source-repo -sysroot: /sysroot installer-volume-id: RLXOS kargs: >- @@ -19,38 +23,52 @@ force-rebuild: true strip: false script: |- - mkdir -p %{sysroot} - ostree admin init-fs --modern %{sysroot} - ostree admin os-init --sysroot=%{sysroot} rlxos + chroot %{include-root} /bin/bash -e << "EOT" + for i in %{datadir}/pkgupd/manifest/*/integration ; do + sh -e $i + done + + rm -rf /install-root - ostree config --repo=%{sysroot}/ostree/repo set sysroot.bootloader none + mkdir -p /proc /sysroot + ln -sv /sysroot/ostree /ostree - ostree pull-local --repo=%{sysroot}/ostree/repo %{include-root} %{ostree-branch} + update-ca-certificates - ostree admin deploy \ - --sysroot=%{sysroot} \ - --os=rlxos \ - %{kargs} \ - %{ostree-branch} + echo "root:root" | chpasswd - mkdir -p %{sysroot}/proc - cp -ar %{sysroot}/boot %{build-root}/ISO/ + echo -e "\nGTK_CSD=1" >> %{sysconfdir}/environment - # read ostree config - getconfig() { - cat /sysroot/boot/loader/entries/ostree-1-rlxos.conf | grep "$1" | cut -d ' ' -f2- - } + # TODO: should be enabled via systemd user-preset + systemctl enable --global appimaged.service + systemctl enable --global wob.socket + + # TODO: should be done in components/pam::integration + chmod 4755 %{bindir}/unix_chkpwd -v - KERNEL=$(getconfig linux) - INITRD=$(getconfig initrd) - KARGS=$(getconfig options) + ln -sfv %{datadir}/zoneinfo/UTC %{sysconfdir}/localtime + touch %{sysconfdir}/skel/.zshrc - for f in ISO/boot/grub/grub.cfg ISO/isolinux/isolinux.cfg ; do - m4 -D"__KERNEL__=/boot/$KERNEL" \ - -D"__INITRD__=/boot/$INITRD" \ - -D"__KARGS__=$KARGS" $f > ${f}.tmp - mv ${f}.tmp ${f} - done + kerver=$(ls -1 /lib/modules | head -n1) + cp /lib/modules/${kerver}/bzImage /lib/modules/${kerver}/vmlinuz + + dracut --reproducible -v --no-machineid \ + --kver ${kerver} \ + --add ostree \ + --add plymouth \ + --add dmsquash-live \ + --install grep \ + --install head \ + --install tail \ + --install less \ + --install lsof \ + --omit lvm \ + --install 'fsck.ext4' \ + %{libdir}/modules/${kerver}/initramfs -build-depends: - - components/ostree.yml + mv %{sysconfdir} %{prefix}/ + EOT + + mkdir -p %{install-root} + + mksquashfs diff --git a/elements/system/deps.yml b/elements/system/deps.yml index b6e3757a0..e41824db6 100644 --- a/elements/system/deps.yml +++ b/elements/system/deps.yml @@ -37,14 +37,13 @@ depends: - components/tzdata.yml - components/kbd.yml - components/branding.yml - - components/ostree.yml - components/cups.yml - components/vim.yml - components/nano.yml - components/squashfs-tools.yml - components/wget.yml - components/sudo.yml - - components/sysroot.yml + - components/pkgupd.yml - components/dmidecode.yml - components/libsmbios.yml - components/libgtop.yml @@ -98,19 +97,9 @@ depends: - components/flatpak.yml - components/power-profiles-daemon.yml - components/networkmanager.yml - - components/webkitgtk.yml - - components/enchant.yml - - components/quickjs.yml - - components/gtkmm.yml - - components/gtk-layer-shell.yml - - components/gjs.yml - components/ntfs-3g.yml - components/bluez.yml - - components/meta-enlightenment.yml - - # AppImage - - components/appimaged.yml - kernel/linux.yml @@ -119,5 +108,4 @@ depends: - system/etc-skel.yml - system/etc-sysctl.yml - system/etc-default-useradd.yml - - system/pre-installed.yml - system/initial-setup-config.yml diff --git a/elements/system/image.yml b/elements/system/image.yml new file mode 100644 index 000000000..e9dd5f355 --- /dev/null +++ b/elements/system/image.yml @@ -0,0 +1,58 @@ +id: system-image +merge: [ version.yml ] +about: System Image + +include: + - system/deps.yml + +capabilities: + - CAP_SYS_CHROOT + +include-root: /sysroot +include-parts: [ doc, devel ] + +kargs: >- + --karg=root=live:LABEL=RLXOS + --karg=quiet + --karg=splash + --karg=rd.live=1 + --karg=rd.live.overlay.overlayfs=1 + +force-rebuild: true +strip: false + +script: |- + chroot %{include-root} /bin/bash -e << "EOT" + for i in %{datadir}/pkgupd/manifest/*/integration ; do + sh -e $i + done + + rm -rf /install-root + + mkdir -p /proc + + update-ca-certificates + + echo "root:root" | chpasswd + + echo -e "\nGTK_CSD=1" >> %{sysconfdir}/environment + + # TODO: should be enabled via systemd user-preset + systemctl enable --global appimaged.service + systemctl enable --global wob.socket + + # TODO: should be done in components/pam::integration + chmod 4755 %{bindir}/unix_chkpwd -v + + ln -sfv %{datadir}/zoneinfo/UTC %{sysconfdir}/localtime + touch %{sysconfdir}/skel/.zshrc + + kerver=$(ls -1 /lib/modules | head -n1) + cp /lib/modules/${kerver}/bzImage /lib/modules/${kerver}/vmlinuz + + EOT + + mkdir -p %{install-root} + + mksquashfs %{sysroot} %{install-root}/system.img -noappend + cp %{include-root}%{libdir}/modules/*/vmlinuz %{install-root}/vmlinuz diff --git a/files/rofi/colors/default.rasi b/files/rofi/colors/default.rasi new file mode 100644 index 000000000..04d84488c --- /dev/null +++ b/files/rofi/colors/default.rasi @@ -0,0 +1,19 @@ +* { + background-color: #EEF1FF; + background-secondary-color: #D2DAFF; + background-selected-color: #BBC7FF; + + foreground-color: #344C64; + foreground-secondary-color: #577B8D; + foreground-selected-color: #344C64; + + border-color: #B1B2FF; + border-color-alt: #B2FFB1; + highlight-color: #B1B2FF; + + warning-color: #F27835; + error-color: #FC5951; + success-color: #80D5B3; + + font: 'IBM Plex 12'; +} \ No newline at end of file diff --git a/files/rofi/themes/ApplicationLauncher.rasi b/files/rofi/themes/ApplicationLauncher.rasi new file mode 100644 index 000000000..7adca4b85 --- /dev/null +++ b/files/rofi/themes/ApplicationLauncher.rasi @@ -0,0 +1,161 @@ +configuration { + modi: "drun"; + show-icons: true; + display-drun: ""; + drun-display-format: "{name}"; +} + +@import "../colors/default.rasi" + +window { + transparency: "real"; + location: center; + anchor: center; + fullscreen: true; + x-offset: 0px; + y-offset: 0px; + enabled: true; + margin: 0; + padding: 0; + border: 0; + border-radius: 0; + border-color: @border-color; + background-color: @background-color; + cursor: "default"; +} + +mainbox { + enabled: true; + spacing: 100px; + margin: 0; + padding: 150px 20px; + border: 0px solid; + border-radius: 0px 0px 0px 0px; + border-color: @border-color; + background-color: transparent; + children: [ "inputbar", "listview" ]; +} + +inputbar { + enabled: true; + spacing: 10px; + margin: 0% 28%; + padding: 10px; + border: 1px solid; + border-radius: 6px; + border-color: @border-color; + background-color: @background-secondary-color; + text-color: @foreground-secondary-color; + children: [ "prompt", "entry" ]; +} + +prompt { + enabled: true; + background-color: transparent; + text-color: inherit; +} + +textbox-prompt-colon { + enabled: true; + expand: false; + str: "::"; + background-color: transparent; + text-color: inherit; +} + +entry { + enabled: true; + background-color: transparent; + text-color: inherit; + cursor: text; + placeholder: "Search"; + placeholder-color: inherit; +} + +listview { + enabled: true; + columns: 7; + lines: 4; + cycle: true; + dynamic: true; + padding: 100px 225px; + scrollbar: true; + layout: vertical; + reverse: false; + fixed-height: true; + fixed-columns: true; + + spacing: 0px; + margin: 0px; + padding: 0px; + border: 0px solid; + border-radius: 0px; + border-color: @border-color; + background-color: transparent; + text-color: @foreground-color; + cursor: "default"; +} + +scrollbar { + handle-width: 5px ; + handle-color: @border-color; + border-radius: 0px; + background-color: @background-secondary-color; +} + +element { + enabled: true; + spacing: 15px; + margin: 0px; + padding: 35px 10px; + border: 0px solid; + border-radius: 15px; + border-color: @border-color; + background-color: transparent; + text-color: @foreground-color; + orientation: vertical; + cursor: pointer; +} + +element normal.normal { + background-color: transparent; + text-color: @foreground-color; +} + +element selected.normal { + background-color: @background-selected-color; + text-color: @foreground-selected-color; +} + +element-icon { + background-color: transparent; + text-color: inherit; + size: 72px; + cursor: inherit; +} + +element-text { + background-color: transparent; + text-color: inherit; + highlight: inherit; + cursor: inherit; + vertical-align: 0.5; + horizontal-align: 0.5; +} + +error-message { + padding: 100px; + border: 0px solid; + border-radius: 0px; + border-color: @border-color; + background-color: @background-color; + text-color: @foreground-color; +} + +textbox { + background-color: transparent; + text-color: @foreground-color; + vertical-align: 0.5; + horizontal-align: 0.0; + highlight: none; +} \ No newline at end of file diff --git a/files/rofi/themes/Powermenu.rasi b/files/rofi/themes/Powermenu.rasi new file mode 100644 index 000000000..14edaf2d4 --- /dev/null +++ b/files/rofi/themes/Powermenu.rasi @@ -0,0 +1,150 @@ +configuration { + show-icons: false; +} + +@import "../colors/default.rasi" + +window { + transparency: "real"; + location: center; + anchor: center; + fullscreen: false; + width: 800px; + x-offset: 0px; + y-offset: 0px; + enabled: true; + margin: 0px; + padding: 0px; + border: 3px solid; + border-radius: 0px; + border-color: @border-color; + cursor: "default"; + background-color: @background-color; +} + +/*****----- Main Box -----*****/ +mainbox { + enabled: true; + spacing: 15px; + margin: 0px; + padding: 30px; + border: 0px solid; + border-radius: 0px; + border-color: @border-color; + background-color: transparent; + children: [ "inputbar", "listview" ]; +} + +/*****----- Inputbar -----*****/ +inputbar { + enabled: true; + spacing: 15px; + margin: 0px; + padding: 0px; + border: 0px; + border-radius: 0px; + border-color: @border-color; + background-color: transparent; + text-color: @foreground-color; + children: [ "textbox-prompt-colon", "prompt"]; +} + +dummy { + background-color: transparent; +} + +textbox-prompt-colon { + enabled: true; + expand: false; + str: ""; + padding: 12px 16px; + border-radius: 0px; + background-color: @background-secondary-color; + text-color: @foreground-secondary-color; +} +prompt { + enabled: true; + padding: 12px; + border-radius: 0px; + background-color: @background-secondary-color; + text-color: @foreground-secondary-color; +} + +/*****----- Message -----*****/ +message { + enabled: true; + margin: 0px; + padding: 12px; + border: 0px solid; + border-radius: 0px; + border-color: @border-color; + background-color: @background-secondary-color; + text-color: @foreground-color; +} +textbox { + background-color: inherit; + text-color: inherit; + vertical-align: 0.5; + horizontal-align: 0.5; + placeholder-color: @foreground-color; + blink: true; + markup: true; +} +error-message { + padding: 12px; + border: 0px solid; + border-radius: 0px; + border-color: @border-color; + background-color: @background-color; + text-color: @foreground-color; +} + +/*****----- Listview -----*****/ +listview { + enabled: true; + columns: 5; + lines: 1; + cycle: true; + dynamic: true; + scrollbar: false; + layout: vertical; + reverse: false; + fixed-height: true; + fixed-columns: true; + + spacing: 15px; + margin: 0px; + padding: 0px; + border: 0px solid; + border-radius: 0px; + border-color: @border-color; + background-color: transparent; + text-color: @foreground-color; + cursor: "default"; +} + +/*****----- Elements -----*****/ +element { + enabled: true; + spacing: 0px; + margin: 0px; + padding: 40px 10px; + border: 0px solid; + border-radius: 0px; + border-color: @border-color; + background-color: @background-secondary-color; + text-color: @foreground-color; + cursor: pointer; +} +element-text { + font: "feather bold 32"; + background-color: transparent; + text-color: inherit; + cursor: inherit; + vertical-align: 0.5; + horizontal-align: 0.5; +} +element selected.normal { + background-color: var(background-selected-color); + text-color: var(foreground-selected-color); +} \ No newline at end of file diff --git a/files/rofi/themes/QuickLauncher.rasi b/files/rofi/themes/QuickLauncher.rasi new file mode 100644 index 000000000..c81a3bbff --- /dev/null +++ b/files/rofi/themes/QuickLauncher.rasi @@ -0,0 +1,210 @@ +configuration { + modi: "drun,run,filebrowser"; + show-icons: true; + display-drun: ""; + display-run: ""; + display-filebrowser: ""; + display-window: ""; + drun-display-format: "{name} [({generic})]"; + window-format: "{w} · {c} · {t}"; +} + +@import "../colors/default.rasi" + +window { + transparency: "real"; + location: center; + anchor: center; + fullscreen: false; + width: 600px; + x-offset: 0px; + y-offset: 0px; + enabled: true; + margin: 0px; + padding: 0px; + border: 3px solid; + border-radius: 0px; + border-color: @border-color; + cursor: "default"; + background-color: @background-color; +} + +mainbox { + enabled: true; + spacing: 10px; + margin: 0px; + padding: 10px; + border: 0px solid; + border-radius: 0px 0px 0px 0px; + border-color: @border-color; + background-color: transparent; + children: [ "inputbar", "message", "listview", "mode-switcher" ]; +} + +inputbar { + enabled: true; + spacing: 10px; + margin: 0px; + padding: 10px; + border: 0px 0px 1px 0px; + border-radius: 0px; + border-color: @border-color; + background-color: @background-secondary-color; + text-color: @foreground-color; + children: [ "prompt", "entry" ]; +} + +prompt { + enabled: true; + background-color: inherit; + text-color: inherit; +} + +textbox-prompt-colon { + enabled: true; + expand: false; + str: "::"; + background-color: inherit; + text-color: inherit; +} + +entry { + enabled: true; + background-color: inherit; + text-color: inherit; + cursor: text; + placeholder: "Search..."; + placeholder-color: inherit; +} + +listview { + enabled: true; + columns: 1; + lines: 8; + cycle: true; + dynamic: true; + scrollbar: false; + layout: vertical; + reverse: false; + fixed-height: true; + fixed-columns: true; + + spacing: 0px; + margin: 0px; + padding: 0px; + border: 0px solid; + border-radius: 0px; + border-color: @border-color; + background-color: transparent; + text-color: @foreground-color; + cursor: "default"; +} + +scrollbar { + handle-width: 5px ; + handle-color: @border-color; + border-radius: 0px; + background-color: @background-secondary-color; +} + +element { + enabled: true; + spacing: 10px; + margin: 0px; + padding: 10px; + border: 0px solid; + border-radius: 0px; + border-color: @border-color; + background-color: transparent; + text-color: @foreground-color; + cursor: pointer; +} + +element normal.normal { + background-color: var(background-color); + text-color: var(foreground-color); +} + +element selected.normal { + background-color: var(background-selected-color); + text-color: var(foreground-selected-color); +} + +element-icon { + background-color: transparent; + text-color: inherit; + size: 24px; + cursor: inherit; +} + +element-text { + background-color: transparent; + text-color: inherit; + highlight: inherit; + cursor: inherit; + vertical-align: 0.5; + horizontal-align: 0.0; +} + + +mode-switcher{ + enabled: true; + spacing: 10px; + margin: 0px; + padding: 0px; + border: 0px solid; + border-radius: 0px; + border-color: @border-color; + background-color: transparent; + text-color: @foreground-color; +} + +button { + padding: 10px; + border: 0px solid; + border-radius: 0px; + border-color: @border-color; + background-color: @background-secondary-color; + text-color: inherit; + cursor: pointer; +} + +button selected { + background-color: var(background-selected-color); + text-color: var(foreground-selected-color); +} + +message { + enabled: true; + margin: 0px; + padding: 0px; + border: 0px solid; + border-radius: 0px 0px 0px 0px; + border-color: @border-color; + background-color: transparent; + text-color: @foreground-color; +} + +textbox { + padding: 10px; + border: 0px solid; + border-radius: 0px; + border-color: @border-color; + background-color: @background-secondary-color; + text-color: @foreground-color; + vertical-align: 0.5; + horizontal-align: 0.0; + highlight: none; + placeholder-color: @foreground-color; + blink: true; + markup: true; +} + +error-message { + padding: 10px; + border: 0px solid; + border-radius: 0px; + border-color: @border-color; + background-color: @background-color; + text-color: @foreground-color; +} \ No newline at end of file diff --git a/files/scripts/Powermenu b/files/scripts/Powermenu new file mode 100755 index 000000000..c703870ec --- /dev/null +++ b/files/scripts/Powermenu @@ -0,0 +1,41 @@ +#!/bin/sh + +UPTIME="$(uptime -p | sed -e 's/up //g')" +HOSTNAME="$(hostname)" + +SHUTDOWN='' +REBOOT='' +SUSPEND='' +LOCK='' +LOGOUT='' + +YES='' +NO='' + +ConfirmCommand() { + rofi -theme-str 'window {location: center; anchor: center; fullscreen: false; width: 350px;}' \ + -theme-str 'mainbox {children: [ "message", "listview" ];}' \ + -theme-str 'listview {columns: 2; lines: 1;}' \ + -theme-str 'element-text {horizontal-align: 0.5;}' \ + -theme-str 'textbox {horizontal-align: 0.5;}' \ + -dmenu \ + -p 'Confirmation' \ + -mesg 'Are you Sure?' \ + -theme Powermenu +} + +Confirm() { + local _selected="$(echo -e "$YES\n$NO" | ConfirmCommand)" + if [ $_selected = "$YES" ] ; then + $@ + fi +} + +SELECTED="$(echo -e "$LOGOUT\n$SUSPEND\n$LOCK\n$REBOOT\n$SHUTDOWN" | rofi -dmenu -p "Uptime: $UPTIME" -mesg "Uptime: $UPTIME" -theme Powermenu)" +case $SELECTED in + $SHUTDOWN) Confirm systemctl poweroff ;; + $REBOOT) Confirm systemctl reboot ;; + $SUSPEND) Confirm systemctl suspend ;; + $LOGOUT) swaymsg exit ;; + $LOCK) swaylock ;; +esac \ No newline at end of file diff --git a/files/scripts/StatusbarProvider b/files/scripts/StatusbarProvider new file mode 100755 index 000000000..77ab9f71f --- /dev/null +++ b/files/scripts/StatusbarProvider @@ -0,0 +1,118 @@ +#!/bin/env python3 + +import time +import json +import os +import subprocess +import dbus + +from datetime import datetime, timedelta + +class Clock: + FORMAT = '%Y/%m/%d %H:%M' + + def generate(self): + return { + 'full_text': datetime.now().strftime(self.FORMAT), + 'name': 'clock', + 'instance': '0' + } + + +class PowerManager: + ADDRESS = 'org.freedesktop.UPower' + OBJECT_PATH = '/org/freedesktop/UPower' + PROPERTIES = 'org.freedesktop.DBus.Properties' + + def __init__(self): + self.bus = dbus.SystemBus() + self.proxy = self.bus.get_object(self.ADDRESS, + self.OBJECT_PATH) + self.interface = dbus.Interface(self.proxy, self.ADDRESS) + + def get_devices(self, types: list): + devices = [] + for device in self.interface.EnumerateDevices(): + ty = self.get_device_property(device, 'Type') + if types == None or ty in types: + devices.append(device) + + return devices + + + def get_device_property(self, device, property): + proxy = self.bus.get_object(self.ADDRESS, device) + interface = dbus.Interface(proxy, self.PROPERTIES) + return interface.Get(self.ADDRESS + '.Device', property) + + def get_battery_device(self): + for device in self.get_devices([2]): + return device + + def get_powersupply(self): + for device in self.get_devices([1]): + powerSupply = self.get_device_property(device, 'PowerSupply') + online = self.get_device_property(device, 'Online') + if powerSupply == 1 and online == 1: + return device + + return None + + def generate(self): + battery = self.get_battery_device() + if battery is None: + return None + + percentage = self.get_device_property(battery, 'Percentage') + powerSupply = self.get_powersupply() + icon = '🔋' + fulltext = f'{percentage}%' + if powerSupply is not None: + icon = '⚡' + extra = self.get_device_property(battery, 'TimeToFull') + else: + extra = self.get_device_property(battery, 'TimeToEmpty') + + if extra > 0: + fulltext += f' ({timedelta(seconds=extra)})' + + + return { + 'full_text': f'{icon} {fulltext}', + 'name': 'Battery', + 'instance': '0' + } + +class NetworkManager: + ADDRESS = 'org.freedesktop.NetworkManager' + OBJECT_PATH = '/org/freedesktop/NetworkManager' + PROPERTIES = 'org.freedesktop.DBus.Properties' + + def __init__(self): + self.bus = dbus.SystemBus() + self.proxy = self.bus.get_object(self.ADDRESS, + self.OBJECT_PATH) + self.interface = dbus.Interface(self.proxy, self.ADDRESS) + +class StatusGenertor: + def __init__(self, blocks: list): + self.blocks = blocks + + def generate(self): + blocks = [] + for block in self.blocks: + block = block.generate() + if block is not None: + blocks.append(block) + + return json.dumps(blocks) + + +statusGenerator = StatusGenertor([PowerManager(), Clock()]) + +print('{"version": 1, "click_events": true}') +print('[') + +while True: + print(statusGenerator.generate()+',') + time.sleep(1) \ No newline at end of file diff --git a/files/sway/config b/files/sway/config new file mode 100644 index 000000000..f76cead17 --- /dev/null +++ b/files/sway/config @@ -0,0 +1,38 @@ +include /etc/sway/config.d/color-scheme.conf +include /etc/sway/config.d/fonts.conf +include /etc/sway/config.d/defaults.conf +include /etc/sway/config.d/devices.conf +include /etc/sway/config.d/background.conf +include /etc/sway/config.d/bindings.conf +include /etc/sway/config.d/statusbar.conf +include /etc/sway/config.d/autostart.conf + +titlebar_border_thickness 2 +titlebar_padding 5 +title_align center +default_border pixel 3 + +blur on +blur_xray off +blur_passes 2 +blur_radius 5 + +shadows on +shadows_on_csd on +shadow_blur_radius 20 +shadow_color #0000007F + +default_dim_inactive 0.0 +dim_inactive_colors.unfocused #000000AA +dim_inactive_colors.urgent #900000AA + +scratchpad_minimize enable + +floating_modifier $Mod normal + +# class border background foreground indicator child_border +client.focused $BackgroundColor $BackgroundColor $ForegroundColor $HighlightColor $BorderColor +client.focused_inactive $BackgroundSecondaryColor $BackgroundSecondaryColor $ForegroundSecondaryColor $HighlightColor $BackgroundSecondaryColor +client.unfocused $BackgroundSecondaryColor $BackgroundSecondaryColor $ForegroundSecondaryColor $HighlightColor $BackgroundSecondaryColor +client.urgent $BackgroundSecondaryColor $BackgroundSecondaryColor $ForegroundSecondaryColor $HighlightColor $BackgroundSecondaryColor +client.placeholder $BackgroundSecondaryColor $BackgroundSecondaryColor $ForegroundSecondaryColor $HighlightColor $BackgroundSecondaryColor diff --git a/files/sway/config.d/autostart.conf b/files/sway/config.d/autostart.conf new file mode 100644 index 000000000..2c7d4da51 --- /dev/null +++ b/files/sway/config.d/autostart.conf @@ -0,0 +1,27 @@ +exec swayidle -w \ + timeout 300 'swaylock -f' \ + timeout 600 'swaymsg "output * dpms off"' \ + resume 'swaymsg "output * dpms on"' \ + before-sleep 'swaylock -f' + +exec systemctl --user set-environment XDG_CURRENT_DESKTOP=sway +exec systemctl --user import-environment DISPLAY \ + SWAYSOCK \ + WAYLAND_DISPLAY \ + XDG_CURRENT_DESKTOP + +exec hash dbus-update-activation-environment 2>/dev/null && \ + dbus-update-activation-environment --systemd DISPLAY \ + SWAYSOCK \ + XDG_CURRENT_DESKTOP=sway \ + WAYLAND_DISPLAY + +set $schema org.gnome.desktop.interface +exec_always { + gsettings set org.gtk.Settings.FileChooser window-size "(1000, 500)" + gsettings set $schema gtk-theme "Qogir-Light" + gsettings set $schema.wm.preferences theme "Qogir-Light" + gsettings set $schema icon-theme "Qogir" + gsettings set $schema cursor-theme "Qogir" + gsettings set $schema font-name "IBM Plex 12" +} \ No newline at end of file diff --git a/files/sway/config.d/background.conf b/files/sway/config.d/background.conf new file mode 100644 index 000000000..767538c1b --- /dev/null +++ b/files/sway/config.d/background.conf @@ -0,0 +1 @@ +output * bg "/usr/share/backgrounds/default.jpg" fill \ No newline at end of file diff --git a/files/sway/config.d/bindings.conf b/files/sway/config.d/bindings.conf new file mode 100644 index 000000000..8aefc67ce --- /dev/null +++ b/files/sway/config.d/bindings.conf @@ -0,0 +1,84 @@ +set $Mod Mod4 + +bindswitch --reload --locked lid:on output * disabled +bindswitch --reload --locked lid:off output * enabled + +bindswitch tablet:on exec TabletMode on +bindswitch tablet:off exec TabletMode off + +bindsym $Mod+Return exec $Terminal +bindsym $Mod+d exec $QuickLauncher +bindsym $Mod+a exec $ApplicationLauncher + +bindsym $Mod+Shift+q kill +bindsym $Mod+Shift+c reload + +bindsym $Mod+Shift+e exec $Powermenu + +bindsym $Mod+Left focus left +bindsym $Mod+Right focus right +bindsym $Mod+Up focus up +bindsym $Mod+Down focus down + +bindsym $Mod+1 workspace number 1 +bindsym $Mod+2 workspace number 2 +bindsym $Mod+3 workspace number 3 +bindsym $Mod+4 workspace number 4 +bindsym $Mod+5 workspace number 5 +bindsym $Mod+6 workspace number 6 +bindsym $Mod+7 workspace number 7 +bindsym $Mod+8 workspace number 8 +bindsym $Mod+9 workspace number 9 +bindsym $Mod+0 workspace number 10 + +bindsym $Mod+Shift+1 move container to workspace number 1 +bindsym $Mod+Shift+2 move container to workspace number 2 +bindsym $Mod+Shift+3 move container to workspace number 3 +bindsym $Mod+Shift+4 move container to workspace number 4 +bindsym $Mod+Shift+5 move container to workspace number 5 +bindsym $Mod+Shift+6 move container to workspace number 6 +bindsym $Mod+Shift+7 move container to workspace number 7 +bindsym $Mod+Shift+8 move container to workspace number 8 +bindsym $Mod+Shift+9 move container to workspace number 9 +bindsym $Mod+Shift+0 move container to workspace number 10 + +bindsym $Mod+b splith +bindsym $Mod+v splitv + +bindsym $Mod+s layout stacking +bindsym $Mod+w layout tabbed +bindsym $Mod+e layout toggle split + +bindsym $Mod+f fullscreen +bindsym $Mod+Shift+space floating toggle +bindsym $Mod+space focus mode_toggle + +bindsym XF86AudioMute exec pactl set-sink-mute `pactl list sinks short | grep -E 'RUNNING|IDLE' | awk '{print $1}'` toggle +bindsym XF86AudioRaiseVolume exec pamixer -ui 5 && pamixer --get-volume > $WOBSOCK +bindsym XF86AudioLowerVolume exec pamixer -ud 5 && pamixer --get-volume > $WOBSOCK + +bindsym XF86AudioPrev exec playerctl previous +bindsym XF86AudioPlay exec playerctl play-pause +bindsym XF86AudioNext exec playerctl next + +bindsym XF86MonBrightnessUp exec brightnessctl s +5% | sed -En 's/.*\(([0-9]+)%\).*/\1/p' > $WOBSOCK +bindsym XF86MonBrightnessDown exec brightnessctl s 5%- | sed -En 's/.*\(([0-9]+)%\).*/\1/p' > $WOBSOCK + +bindsym Print exec grimshot save screen ~/Pictures/$(date '+%Y-%m-%d-%T')-screenshot.png +bindsym Shift+Print exec grimshot save area ~/Pictures/$(date '+%Y-%m-%d-%T')-screenshot.png + +bindsym $Mod+Shift+minus move scratchpad +bindsym $Mod+minus scratchpad show + +bindgesture swipe:3:up exec $ApplicationLauncher + +bindgesture swipe:3:right workspace prev +bindgesture swipe:3:left workspace next + +mode "resize" { + bindsym Left resize shrink width 10px + bindsym Right resize grow width 10px + bindsym Up resize shrink height 10px + bindsym Down resize grow height 10px +} +bindsym $Mod+r mode "resize" diff --git a/files/sway/config.d/color-scheme.conf b/files/sway/config.d/color-scheme.conf new file mode 100644 index 000000000..77faaf0ba --- /dev/null +++ b/files/sway/config.d/color-scheme.conf @@ -0,0 +1,6 @@ +set $BackgroundColor #EEF1FF +set $BackgroundSecondaryColor #D2DAFF +set $ForegroundColor #344C64 +set $ForegroundSecondaryColor #577B8D +set $BorderColor #B1B2FF +set $HighlightColor #B1B2FF diff --git a/files/sway/config.d/defaults.conf b/files/sway/config.d/defaults.conf new file mode 100644 index 000000000..46298e7f6 --- /dev/null +++ b/files/sway/config.d/defaults.conf @@ -0,0 +1,7 @@ +set $Terminal foot +set $QuickLauncher 'rofi -modi run,drun,filebrowser,window -show drun -theme QuickLauncher' +set $Powermenu 'Powermenu' +set $ApplicationLauncher 'rofi -show drun -theme ApplicationLauncher' + +set $WOBSOCK $XDG_RUNTIME_DIR/wob.sock +seat seat0 xcursor_theme Qogir 24 \ No newline at end of file diff --git a/files/sway/config.d/devices.conf b/files/sway/config.d/devices.conf new file mode 100644 index 000000000..2c1bb3111 --- /dev/null +++ b/files/sway/config.d/devices.conf @@ -0,0 +1,6 @@ +input "type:touchpad" { + dwt enabled + tap enabled + middle_emulation enabled + natural_scroll enabled +} \ No newline at end of file diff --git a/files/sway/config.d/fonts.conf b/files/sway/config.d/fonts.conf new file mode 100644 index 000000000..2d15c4bad --- /dev/null +++ b/files/sway/config.d/fonts.conf @@ -0,0 +1 @@ +font pango: IBM Plex Sans Regular 12 \ No newline at end of file diff --git a/files/sway/config.d/statusbar.conf b/files/sway/config.d/statusbar.conf new file mode 100644 index 000000000..c24cc7fac --- /dev/null +++ b/files/sway/config.d/statusbar.conf @@ -0,0 +1,12 @@ +bar { + position top + status_command /bin/StatusbarProvider + + colors { + statusline $ForegroundColor + background $BackgroundColor + focused_workspace $BackgroundSecondaryColor $BackgroundSecondaryColor $ForegroundSecondaryColor + active_workspace $BackgroundSecondaryColor $BackgroundSecondaryColor $ForegroundSecondaryColor + inactive_workspace $BackgroundColor $BackgroundColor $ForegroundColor + } +} \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bc2f44bc7..02f7de353 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,7 +1,6 @@ include_directories(common) include_directories(external) -add_subdirectory(ignite) -add_subdirectory(sysroot) +add_subdirectory(pkgupd) add_subdirectory(srclang) add_subdirectory(initial-setup) add_subdirectory(welcome-tour) \ No newline at end of file diff --git a/src/ignite/ArchiveManager.cpp b/src/ignite/ArchiveManager.cpp deleted file mode 100644 index ec61174ac..000000000 --- a/src/ignite/ArchiveManager.cpp +++ /dev/null @@ -1,131 +0,0 @@ -#include "ArchiveManager.h" - -#include "Executor.h" -#include - -void ArchiveManager::get(const std::filesystem::path& filepath, - const std::string& input_path, std::string& output) { - auto [status, out] = Executor("/bin/tar") - .arg("--zstd") - .arg("-O") - .arg("-xPf") - .arg(filepath) - .arg(input_path) - .output(); - if (status != 0) { - throw std::runtime_error( - "failed to get_available data from " + filepath.string()); - } - output = std::move(out); -} - -void ArchiveManager::extract(const std::filesystem::path& filepath, - const std::string& input_path, - const std::filesystem::path& output_path) { - std::ofstream writer(output_path); - int status = Executor("/bin/tar") - .arg("--zstd") - .arg("-O") - .arg("-xPf") - .arg(filepath) - .arg(input_path) - .start() - .wait(&writer); - if (status != 0) { - throw std::runtime_error( - "failed to get_available data from " + filepath.string()); - } -} - -MetaInfo ArchiveManager::info(const std::filesystem::path& input_path) { - std::string content; - get(input_path, "./info", content); - - return MetaInfo::from_data(content); -} - -void ArchiveManager::list(const std::filesystem::path& filepath, - std::vector& files) { - std::stringstream output; - int status = Executor("/usr/bin/tar") - .arg("--zstd") - .arg("-tf") - .arg(filepath) - .start() - .wait(&output); - if (status != 0) { - throw std::runtime_error("failed to list file from archive " + - filepath.string() + ": " + output.str()); - } - - std::stringstream ss(output.str()); - std::string file; - - while (std::getline(ss, file, '\n')) { files.push_back(file); } -} - -void ArchiveManager::extract(const std::filesystem::path& filepath, - const std::string& output_path, std::vector& files_list) { - std::stringstream output; - if (!std::filesystem::exists(output_path)) { - std::error_code code; - std::filesystem::create_directories(output_path, code); - if (code) { - throw std::runtime_error("failed to create required directory '" + - output_path + "': " + code.message()); - } - } - - auto exe = "/bin/tar"; - if (filepath.has_extension() && filepath.extension() == ".zip") { - exe = "/bin/bsdtar"; - } - - int status = Executor(exe) - .arg("-xvPf") - .arg(filepath) - .arg("-C") - .arg(output_path) - .start() - .wait(&output); - - std::stringstream ss(output.str()); - for (std::string f; std::getline(ss, f);) { - if (f.starts_with("./")) f = f.substr(2); - if (f.starts_with("x ")) f = f.substr(2); - if (f.empty()) continue; - files_list.emplace_back(f); - } - DEBUG("EXTRACTED: " << files_list.size() << " file(s)"); - - if (status != 0) { - throw std::runtime_error( - "failed to extract " + filepath.string() + " :" + output.str()); - } -} - -void ArchiveManager::compress( - const std::filesystem::path& filepath, const std::string& input_path) { - auto [status, output] = Executor("/bin/tar") - .arg("--zstd") - .arg("-cPf") - .arg(filepath) - .arg("-C") - .arg(input_path) - .arg(".") - .output(); - if (status != 0) { - throw std::runtime_error( - "failed to execute command for compression: " + output); - } -} - -bool ArchiveManager::is_archive(const std::filesystem::path& filepath) { - for (auto const& ext : {".tar", ".zip", ".gz", ".xz", ".bzip2", ".tgz", - ".txz", ".bz2", ".zst", ".zstd", ".lz"}) { - if (filepath.has_extension() && filepath.extension() == ext) { - return true; - } - } - return false; -} diff --git a/src/ignite/ArchiveManager.h b/src/ignite/ArchiveManager.h deleted file mode 100644 index 0179e380e..000000000 --- a/src/ignite/ArchiveManager.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef PKGUPD_ARCHIVE_MANAGER_HXX -#define PKGUPD_ARCHIVE_MANAGER_HXX - -#include "MetaInfo.h" - -/** - * This class represent rlxos compressed Package, - * @brief It provides various methods to handle, read, compress and extract - * rlxos packages - */ -class ArchiveManager { -public: - /** - * @brief Provides the file data of specified file in the package - * @param filepath path to the file in Package (must be started from ./) - * @return content of file - */ - static void get(const std::filesystem::path& filepath, - const std::string& input_path, std::string& output); - - static void extract(const std::filesystem::path& filepath, - const std::string& input_path, - const std::filesystem::path& output_path); - - static MetaInfo info(const std::filesystem::path& filepath); - - /** - * List all files in the archive - */ - static void list( - const std::filesystem::path& filepath, std::vector&); - - static void extract(const std::filesystem::path& filepath, - const std::string& input_path, - std::vector& files_list); - - static void compress(const std::filesystem::path& filepath, - const std::string& input_path); - - static bool is_archive(const std::filesystem::path& filepath); -}; - -#endif diff --git a/src/ignite/Builder.cpp b/src/ignite/Builder.cpp deleted file mode 100644 index 223c19692..000000000 --- a/src/ignite/Builder.cpp +++ /dev/null @@ -1,537 +0,0 @@ -/* - * Copyright (c) 2023 Manjeet Singh . - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "Builder.h" - -#include "../external/Curl.h" -#include "ArchiveManager.h" -#include "Executor.h" -#include -#include -#include -#include - -Builder::BuildInfo::BuildInfo( - const std::string &filepath, const std::filesystem::path &search_path) { - config.search_path.push_back(search_path); - config.node["cache"] = "none"; - update_from_file(filepath); - if (config.node["build-depends"]) { - for (auto const &dep: config.node["build-depends"]) { - build_time_depends.push_back(dep.as()); - }; - } - if (config.node["sources"]) { - for (auto const &dep: config.node["sources"]) - sources.emplace_back(dep.as()); - } - element_id = std::filesystem::relative(filepath, search_path / "elements") - .replace_extension(); -} - -std::vector split(const std::string &str, char del) { - std::stringstream ss(str); - std::vector l; - for (std::string s; std::getline(ss, s, del);) { l.push_back(s); } - return l; -} - -std::string replace(std::string v, char old, char n) { - for (auto &i: v) { - if (i == old) i = n; - } - return v; -} - -std::string Builder::BuildInfo::resolve(const std::string &data, - const std::map &variables) { - std::regex pattern(R"(\%\{([^}]+)\})"); - std::smatch match; - std::string result = data; - - while (std::regex_search(result, match, pattern)) { - if (match.size() > 1) { - std::string variable = match.str(1); - auto it = variables.find(variable); - if (it != variables.end()) { - result.replace(match[0].first, match[0].second, it->second); - // TODO: a better way to handle this hack - } else if (variable.starts_with("version:")) { - auto data = variable.substr(variable.find_first_of(':') + 1); - auto version = variables.at("version"); - try { - auto nth = std::stoi(data) - 1; - int count = 0, position = 0; - while (count <= nth) { - position += 1; - position = version.find('.', position); - if (position == std::string::npos) { - throw std::string( - "invalid variable value spliting for " + - std::to_string(nth) + "th position"); - } - count++; - } - result.replace(match[0].first, match[0].second, - version.substr(0, position)); - } catch (const std::string &error) { - throw std::runtime_error(error); - } catch (...) { - result.replace(match[0].first, match[0].second, - replace(version, '.', data[0])); - } - } else { - throw std::runtime_error( - "undefined variable '" + variable + "'"); - } - } - } - return result; -} - -void Builder::BuildInfo::resolve( - const Config &global, const std::map &extra) { - for (auto &source: sources) { source = resolve(source, global, extra); } -} - -std::string Builder::BuildInfo::resolve(const std::string &value, - const Config &global, - const std::map &extra) const { - std::map variables = extra; - if (global.node["variables"]) { - for (auto const &v: global.node["variables"]) { - variables[v.first.as()] = v.second.as(); - } - } - - if (this->config.node["variables"]) { - for (auto const &v: this->config.node["variables"]) { - variables[v.first.as()] = v.second.as(); - } - } - - for (auto const &i: this->config.node) { - if (i.second.IsScalar()) { - try { - variables[i.first.as()] = - i.second.as(); - } catch (...) {} - } - } - - variables["build-dir"] = "_pkgupd_build_dir"; - - return resolve(value, variables); -} - -std::optional Builder::prepare_sources( - const std::filesystem::path &source_dir, - const std::filesystem::path &build_root, - bool with_build_dir) { - std::optional subdir; - - std::filesystem::create_directories(build_root); - - for (auto url: build_info.sources) { - auto filename = std::filesystem::path(url).filename().string(); - if (auto idx = url.find("::"); idx != std::string::npos) { - filename = url.substr(0, idx); - url = url.substr(idx + 2); - } - - auto filepath = source_dir / filename; - if (!std::filesystem::exists(filepath)) { - if (url.starts_with("http")) { - Executor("/bin/wget") - .arg(url) - .arg("-O") - .arg(filepath.string() + ".tmp") - .execute(); - std::filesystem::rename(filepath.string() + ".tmp", filepath); - } else { - std::filesystem::copy( - (container ? container->base_dir - : std::filesystem::current_path()) / - url, - filepath, - std::filesystem::copy_options::recursive | - std::filesystem::copy_options:: - overwrite_existing); - } - } - if (ArchiveManager::is_archive(filepath)) { - std::vector files_list; - - ArchiveManager::extract(filepath, - build_root / (subdir ? *subdir : std::filesystem::path("")), - files_list); - if (!subdir && !with_build_dir) { - std::string dir = files_list.front(); - auto idx = dir.find('/'); - if (idx != std::string::npos) { dir = dir.substr(0, idx); } - subdir = dir; - } - } else { - std::filesystem::copy_file(filepath, - build_root / - (subdir ? *subdir : std::filesystem::path("")) / - filename, - std::filesystem::copy_options::overwrite_existing); - } - } - return subdir; -} - -void Builder::compile_source(const std::filesystem::path &build_root, - const std::filesystem::path &install_root) { - std::vector env; - if (config.node["environ"]) { - for (auto const &e: config.node["environ"]) { - env.push_back(e.as()); - } - } - - if (build_info.config.node["environ"]) { - for (auto const &e: build_info.config.node["environ"]) { - env.push_back(e.as()); - } - } - std::map extra_variables; - - auto resolved_install_root = - (container ? container->host_root : std::filesystem::path("")) / - install_root / build_info.package_name(); - auto resolved_build_root = - (container ? container->host_root : std::filesystem::path("")) / - build_root; - extra_variables["install-root"] = std::filesystem::path("/") / - install_root / build_info.package_name(); - extra_variables["build-root"] = std::filesystem::path("/") / build_root; - - if (auto pre_script = build_info.config.get("pre-script", ""); - !pre_script.empty()) { - pre_script = build_info.resolve(pre_script, config, extra_variables); - PROCESS("Executing pre compilation script") - DEBUG(pre_script); - - Executor("/bin/sh") - .arg("-ec") - .arg(pre_script) - .path(extra_variables["build-root"]) - .environ(env) - .container(container) - .execute(); - } - - if (build_info.config.get("build-type", "") == "import") { - auto source = resolved_build_root / - build_info.config.get("source", ""); - auto target = resolved_install_root / - build_info.config.get("target", ""); - std::filesystem::create_directories(target); - Executor("/bin/cp") - .arg("-rap") - .arg(source / ".") - .arg("-t") - .arg(target) - .execute(); - } else { - auto script = build_info.config.get("script", ""); - if (script.empty()) { - auto compiler = get_compiler(resolved_build_root); - script = compiler.script; - } - - script = build_info.resolve(script, config, extra_variables); - - PROCESS("Executing compilation script") - DEBUG(script); - - if (script.length() > 500) { - auto script_path = resolved_build_root / "pkgupd_exec_script.sh"; - { - std::ofstream script_writer(script_path); - script_writer << script; - } - - Executor("/bin/sh") - .arg("-e") - .arg("pkgupd_exec_script.sh") - .path(extra_variables["build-root"]) - .environ(env) - .container(container) - .execute(); - - } else { - Executor("/bin/sh") - .arg("-ec") - .arg(script) - .path(extra_variables["build-root"]) - .environ(env) - .container(container) - .execute(); - } - } - - if (auto post_script = - build_info.config.get("post-script", ""); - !post_script.empty()) { - post_script = build_info.resolve(post_script, config, extra_variables); - PROCESS("Executing pre compilation script") - DEBUG(post_script); - - Executor("/bin/sh") - .arg("-ec") - .arg(post_script) - .path(extra_variables["build-root"]) - .environ(env) - .container(container) - .execute(); - } - - if (build_info.config.get("strip", true)) { - for (auto const &iter: std::filesystem::recursive_directory_iterator( - resolved_install_root)) { - if (!iter.is_regular_file()) continue; - // if file is executable and writable or - // if file ends with .so and .a - // TODO check if it cover all cases - if (((iter.path().has_extension() && - (iter.path().extension() == ".so" || - iter.path().extension() == ".a")) || - (access(iter.path().c_str(), X_OK) == 0)) && - access(iter.path().c_str(), W_OK) == 0) { - - auto [status, mime_type] = Executor("/bin/file") - .arg("-b") - .arg("--mime-type") - .arg(iter.path()) - .output(); - if (status != 0) { - ERROR("failed to read MIME TYPE for " + - iter.path().string() + ": " + mime_type); - continue; - } - - std::vector mime_to_strip; - if (config.node["strip-mimetype"]) { - for (auto const &i: config.node["strip-mimetype"]) { - mime_to_strip.emplace_back(i.as()); - } - } - - if (build_info.config.node["strip-mimetype"]) { - for (auto const &i: - build_info.config.node["strip-mimetype"]) { - mime_to_strip.emplace_back(i.as()); - } - } - - if (std::find(mime_to_strip.begin(), mime_to_strip.end(), - mime_type) == mime_to_strip.end()) { - continue; - } - - // Some .so are GNU linker scripts, skip them - DEBUG("MIME_TYPE: '" << mime_type << "'") - - auto dbg_file_path = iter.path().string() + ".dbg"; - // Copy debugging symbols to dbg directory - Executor("/bin/objcopy") - .arg("--only-keep-debug") - .arg(iter.path()) - .arg(dbg_file_path) - .silent() - .execute(); - - std::string strip_args = "--strip-all"; - if (iter.path().has_extension()) { - if (iter.path().extension() == ".a") { - strip_args = "--strip-debug"; - } else { - strip_args = "--strip-unneeded"; - } - } - - // Strip out the debugging symbols - Executor("/bin/strip") - .arg(strip_args) - .arg(iter.path()) - .execute(); - - // Link to the extracted debugging symbols - Executor("/bin/objcopy") - .arg("--add-gnu-debuglink=" + - iter.path().filename().string() + ".dbg") - .arg(iter.path()) - .path(iter.path().parent_path()) - .execute(); - } - } - } -} - -void Builder::pack(const std::filesystem::path &install_root, - const std::filesystem::path &package) { - auto install_root_package = install_root / build_info.package_name(); - auto install_root_devel = - install_root / (build_info.package_name() + ".devel"); - auto install_root_dbg = install_root / (build_info.package_name() + ".dbg"); - auto install_root_doc = install_root / (build_info.package_name() + ".doc"); - - for (auto const &i: - {install_root_dbg, install_root_devel, install_root_doc}) { - std::filesystem::create_directories(i); - } - - std::vector keep_files; - if (build_info.config.node["keep-files"]) { - for (auto const &i: build_info.config.node["keep-files"]) { - keep_files.push_back(std::regex(i.as())); - } - } - - auto keep_file = [&keep_files](const std::string &filename) -> bool { - for (auto const &i: keep_files) { - if (std::regex_match(filename, i)) { return true; } - } - return false; - }; - - auto replace_directory = [&](const std::filesystem::path &filepath, - const std::filesystem::path &old_parent, - const std::filesystem::path &new_parent) - -> std::filesystem::path { - auto relative_path = std::filesystem::relative(filepath, old_parent); - return new_parent / relative_path; - }; - - auto move_file = [&](const std::filesystem::path &filepath, - const std::filesystem::path &new_path) { - auto replaced_path = - replace_directory(filepath, install_root_package, new_path); - std::filesystem::create_directories(replaced_path.parent_path()); - std::filesystem::rename(filepath, replaced_path); - }; - - for (auto const &devel: - {"usr/include", "usr/lib/cmake", "usr/lib/pkgconfig"}) { - if (auto path = install_root_package / devel; - std::filesystem::exists(path)) { - move_file(path, install_root_devel); - } - } - - for (auto const &dbg: {"usr/src", "usr/lib/debug"}) { - if (auto path = install_root_package / dbg; - std::filesystem::exists(path)) { - move_file(path, install_root_dbg); - } - } - - for (auto const &dbg: {"usr/share/doc", "usr/share/man"}) { - if (auto path = install_root_package / dbg; - std::filesystem::exists(path)) { - move_file(path, install_root_doc); - } - } - - for (auto const &i: std::filesystem::recursive_directory_iterator( - install_root_package)) { - if (i.is_directory()) { - if (i.path().empty() && - build_info.config.get("clean-empty-dir", true)) { - std::filesystem::remove(i.path()); - } - } else if (!keep_files.empty() && keep_file(i.path().filename())) { - continue; - } else if (i.path().has_extension() && i.path().extension() == ".la") { - std::filesystem::remove(i.path()); - } else if (i.path().has_extension() && i.path().extension() == ".a") { - move_file(i.path(), install_root_devel); - } else if (i.path().has_extension() && i.path().extension() == ".dbg") { - move_file(i.path(), install_root_dbg); - } - } - - PROCESS("Compressing " << build_info.name()); - - std::ofstream user_map(install_root / "user-map"); - user_map << "+" << getuid() << " root:0\n" - << config.get("user-map", "") << '\n' - << build_info.config.get("user-map", "") << '\n'; - user_map.close(); - - std::ofstream group_map(install_root / "group-map"); - group_map << "+" << getgid() << " root:0\n" - << config.get("group-map", "") << '\n' - << build_info.config.get("group-map", "") << '\n'; - group_map.close(); - - for (auto const &i: std::map{ - {"", install_root_package}, - {".dbg", install_root_dbg}, - {".devel", install_root_devel}, - {".doc", install_root_doc}, - }) { - Executor("/bin/tar") - .arg("--zstd") - .arg("--owner-map=" + (install_root / "user-map").string()) - .arg("--group-map=" + (install_root / "group-map").string()) - .arg("-cPf") - .arg(package.string() + i.first) - .arg("-C") - .arg(i.second) - .arg(".") - .execute(); - } -} - -Builder::Compiler Builder::get_compiler( - const std::filesystem::path &build_root) { - std::string build_type; - if (build_info.config.node["build-type"]) { - build_type = build_info.config.node["build-type"].as(); - } else { - for (auto const &[id, compiler]: compilers) { - if (std::filesystem::exists(build_root / compiler.file)) { - build_type = id; - break; - } - } - } - - if (build_type.empty() || !compilers.contains(build_type)) { - throw std::runtime_error( - "unknown build-type or failed to detect build-type '" + - build_type + "' at " + build_root.string()); - } - return compilers[build_type]; -} - -Builder::Builder(const Config &config, const Builder::BuildInfo &build_info, - const std::optional &container) - : config{config}, build_info{build_info}, container{container} { - if (config.node["compiler"]) { - for (auto const &c: config.node["compiler"]) { - compilers[c.first.as()] = Compiler{ - c.second["file"].as(), - c.second["script"].as(), - }; - } - } -} diff --git a/src/ignite/Builder.h b/src/ignite/Builder.h deleted file mode 100644 index 209087215..000000000 --- a/src/ignite/Builder.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2023 Manjeet Singh . - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#ifndef PKGUPD_BUILDER_H -#define PKGUPD_BUILDER_H - -#include "Container.h" -#include "MetaInfo.h" -#include -#include -#include - -class Builder { -public: - struct BuildInfo : MetaInfo { - std::vector build_time_depends, sources; - std::string element_id; - - BuildInfo() = default; - - explicit BuildInfo(const std::string &filepath, - const std::filesystem::path &search_path = {}); - - static std::string resolve(const std::string &data, - const std::map &variables); - - void resolve(const Config &global, - const std::map &extra = {}); - - std::string resolve(const std::string &value, - const Config &global, - const std::map &extra = {}) const; - }; - - struct Compiler { - std::string file; - std::string script; - }; - -private: - const Config &config; - const BuildInfo &build_info; - std::map compilers; - - std::optional container; - -public: - explicit Builder(const Config &config, const BuildInfo &build_info, - const std::optional &container); - - std::optional prepare_sources( - const std::filesystem::path &source_dir, - const std::filesystem::path &build_root, - bool with_build_dir); - - Compiler get_compiler(const std::filesystem::path &build_root); - - void compile_source(const std::filesystem::path &build_root, - const std::filesystem::path &install_root); - - void pack(const std::filesystem::path &install_root, - const std::filesystem::path &package); -}; - -#endif // PKGUPD_BUILDER_H diff --git a/src/ignite/CMakeLists.txt b/src/ignite/CMakeLists.txt deleted file mode 100644 index 0f0fdfe46..000000000 --- a/src/ignite/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -cmake_minimum_required(VERSION 3.20) -project(ignite - VERSION "2.0.0" - DESCRIPTION "Ignite build root" - LANGUAGES CXX) - -set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -add_executable(ignite - ArchiveManager.cpp ArchiveManager.h - Builder.cpp Builder.h - Container.cpp Container.h - Executor.cpp Executor.h - Ignite.cpp Ignite.h - MetaInfo.cpp MetaInfo.h - Resolver.h - main.cpp) - -find_package(yaml-cpp REQUIRED) -find_library(CURL curl REQUIRED) - -target_link_libraries(ignite PUBLIC - yaml-cpp - ${CURL}) \ No newline at end of file diff --git a/src/ignite/Container.cpp b/src/ignite/Container.cpp deleted file mode 100644 index 79a74940e..000000000 --- a/src/ignite/Container.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2023 Manjeet Singh . - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "Container.h" - -#include "Executor.h" - -std::vector Container::args() const { - std::vector a = {"/bin/bwrap", "--bind", host_root, "/", "--proc", "/proc", "--dev", "/dev", - "--ro-bind", "/etc/resolv.conf", "/etc/resolv.conf", "--unshare-all", "--share-net", - "--uid", "0", "--gid", "0", "--die-with-parent"}; - for (auto const &[dest, source]: binds) { - a.insert(a.end(), {"--bind", source, dest}); - } - for (auto const &[dest, source]: ro_binds) { - a.insert(a.end(), {"--ro-bind", source, dest}); - } - - for (auto const &c: capabilites) { a.insert(a.end(), {"--cap-add", c}); } - - for (auto const &e: environ) { - auto idx = e.find('='); - auto key = e.substr(0, idx); - auto value = e.substr(idx + 1); - a.insert(a.end(), {"--setenv", key, value}); - } - - return a; -} diff --git a/src/ignite/Container.h b/src/ignite/Container.h deleted file mode 100644 index 182721b9c..000000000 --- a/src/ignite/Container.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2023 Manjeet Singh . - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#ifndef PKGUPD_CONTAINER_H -#define PKGUPD_CONTAINER_H - -#include -#include -#include -#include - -struct Container { - const std::string runtime{"/bin/bwrap"}; - std::string image{}; - std::vector environ; - std::vector> binds, ro_binds; - std::vector capabilites; - - std::filesystem::path host_root; - std::filesystem::path base_dir; - std::string name; - std::ostream* logger; - - [[nodiscard]] std::vector args() const; -}; - -#endif // PKGUPD_CONTAINER_H diff --git a/src/ignite/Executor.cpp b/src/ignite/Executor.cpp deleted file mode 100644 index 972e2925c..000000000 --- a/src/ignite/Executor.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2023 Manjeet Singh . - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "Executor.h" - -#include -#include - -enum { - READ = 0, WRITE = 1 -}; - -Executor &Executor::start() { - if (pipe(pipe_fd) == -1) { - throw std::runtime_error("pipe creating failed"); - } - - pid = fork(); - if (pid == -1) { - throw std::runtime_error("failed to fork new process"); - } else if (pid == 0) { - close(pipe_fd[READ]); - - dup2(pipe_fd[WRITE], STDOUT_FILENO); - dup2(pipe_fd[WRITE], STDERR_FILENO); - - close(pipe_fd[WRITE]); - - if (path_) - if (chdir(path_->c_str()) == -1) - throw std::runtime_error("failed to switch path to " + *path_); - clearenv(); - - std::vector args; - for (auto const &c: args_) args.emplace_back(c.c_str()); - args.push_back(nullptr); - - std::vector env; - for (auto const &c: environ_) env.emplace_back(c.c_str()); - env.push_back(nullptr); - - if (execve(args_[0].c_str(), (char *const *) args.data(), (char *const *) env.data()) == -1) { - perror("execution failed"); - } - exit(EXIT_FAILURE); - } - return *this; -} - -int Executor::wait(std::ostream *out) { - close(pipe_fd[WRITE]); - - char buffer[BUFSIZ] = {0}; - ssize_t bytes_read; - while ((bytes_read = read(pipe_fd[READ], buffer, sizeof(buffer))) > 0) { - if (out) out->write(buffer, bytes_read); - if (logger_) logger_->write(buffer, bytes_read); - } - - close(pipe_fd[READ]); - int status; - waitpid(pid, &status, 0); - - return WEXITSTATUS(status); -} - -int Executor::run() { - start(); - return wait(silent_ ? nullptr : &std::cout); -} - -std::tuple Executor::output() { - std::stringstream output; - start(); - int status = wait(&output); - std::string output_data = output.str(); - output_data.shrink_to_fit(); - if (output_data.ends_with("\n")) output_data.pop_back(); - return {status, output_data}; -} - -void Executor::execute() { - std::stringstream ss; - for (auto const &a: args_) { ss << a << " "; } - if (!silent_) { - DEBUG("COMMAND : " << ss.str()); - DEBUG("PATH : " << (path_ ? *path_ : ".")); - - if (logger_) { - *logger_ << "COMMAND : " << ss.str() << std::endl; - *logger_ << "path : " << (path_ ? *path_ : ".") << std::endl; - } - } - - if (int status = run(); status != 0) { - throw std::runtime_error("failed to execute command (" + ss.str() + "): exit code " + std::to_string(status)); - } -} diff --git a/src/ignite/Executor.h b/src/ignite/Executor.h deleted file mode 100644 index f951a19e9..000000000 --- a/src/ignite/Executor.h +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef PKGUPD_EXEC_H -#define PKGUPD_EXEC_H - -#include "../common/Colors.h" -#include "Container.h" -#include -#include -#include -#include -#include -#include -#include - -class Executor { - - std::vector args_; - std::optional path_{}; - std::vector environ_; - pid_t pid = -1; - int pipe_fd[2]{}; - std::ostream* logger_{nullptr}; - bool silent_{false}; - -public: - explicit Executor(const std::string& binary) { args_.push_back(binary); } - - Executor& container(const std::optional& container) { - if (container) { - std::string path = path_ ? *path_ : "/"; - auto a = container->args(); - a.insert(a.end(), {"--chdir", path}); - args_.insert(args_.begin(), a.begin(), a.end()); - path_.reset(); - logger_ = container->logger; - } - return *this; - } - - Executor& arg(const std::string& a) { - args_.emplace_back(a); - return *this; - } - - Executor& path(const std::string& p) { - path_ = p; - return *this; - } - - Executor& silent() { - silent_ = true; - return *this; - } - - Executor& environ(const std::string& env) { - environ_.push_back(env); - return *this; - } - - Executor& environ(const std::vector& env) { - environ_.insert(environ_.end(), env.begin(), env.end()); - return *this; - } - - Executor& start(); - - int wait(std::ostream* out = nullptr); - - int run(); - - void execute(); - - std::tuple output(); -}; - -#endif diff --git a/src/ignite/Ignite.cpp b/src/ignite/Ignite.cpp deleted file mode 100644 index 5f0984a8e..000000000 --- a/src/ignite/Ignite.cpp +++ /dev/null @@ -1,368 +0,0 @@ -/* - * Copyright (c) 2023 Manjeet Singh . - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "Ignite.h" - -#include "../external/picosha2.h" -#include "Executor.h" -#include -#include - -Ignite::Ignite(std::filesystem::path project_path, std::filesystem::path cache_path) : project_path( - std::move(project_path)), cache_path( - cache_path.empty() ? this->project_path / "cache" : std::move(cache_path)) { - std::string arch; -#ifdef __x86_64__ - arch = "x86_64"; -#endif - auto config_file = this->project_path / ("config-" + arch + ".yml"); - if (!std::filesystem::exists(config_file)) { - throw std::runtime_error("failed to load configuration file '" + config_file.string() + "'"); - } - config.update_from_file(config_file); -} - -void Ignite::load() { - PROCESS("Loading elements") - for (auto const &i: std::filesystem::recursive_directory_iterator(project_path / "elements")) { - if (i.is_regular_file() && i.path().has_extension() && i.path().extension() == ".yml") { - auto element_path = std::filesystem::relative(i.path(), project_path / "elements"); - try { - pool[element_path.string()] = Builder::BuildInfo(i.path(), project_path); - } catch (const std::exception &exception) { - throw std::runtime_error("failed to load '" + element_path.string() + " because " + exception.what()); - } - } - } - DEBUG("TOTAL ELEMENTS: " << pool.size()); -} - -void Ignite::resolve(const std::vector &id, std::vector &output, bool devel, bool include_depends, - bool include_extra) { - std::map visited; - - std::function dfs = [&](const std::string &i) { - visited[i] = true; - auto build_info = pool.find(i); - if (build_info == pool.end()) { - throw std::runtime_error("MISSING " + i); - } - - auto depends = build_info->second.depends; - if (devel) { - depends.insert(depends.end(), build_info->second.build_time_depends.begin(), - build_info->second.build_time_depends.end()); - } - if (include_extra) { - if (build_info->second.config.node["include"]) { - for (auto const &i: build_info->second.config.node["include"]) { - depends.push_back(i.as()); - } - } - } - - if (include_depends) { - for (const auto &depend: depends) { - if (visited[depend]) continue; - try { - dfs(depend); - } catch (const std::exception &exception) { - throw std::runtime_error(std::string(exception.what()) + "\n\tTRACEBACK " + i); - } - } - } - - build_info->second.cache = hash(build_info->second); - auto cached = std::filesystem::exists(cachefile(build_info->second)); - - for (auto depend: depends) { - auto idx = std::find_if(output.begin(), output.end(), [&depend](const auto &val) -> bool { - return std::get<0>(val) == depend; - }); - if (idx == output.end()) { - if (auto in_pool = pool.find(depend); in_pool == pool.end()) { - throw std::runtime_error("internal error " + depend + " not in a pool for " + i); - } else { - auto local_build_info = in_pool->second; - local_build_info.cache = hash(local_build_info); - if (!std::filesystem::exists(cachefile(local_build_info))) { - cached = false; - break; - } - } - - } else { - if (!std::get<2>(*idx)) { - cached = false; - break; - } - } - } - - output.emplace_back(i, build_info->second, cached); - }; - - for (auto const &i: id) { dfs(i); } -} - -std::string Ignite::hash(const Builder::BuildInfo &build_info) { - std::string hash_sum; - - { - std::stringstream ss; - ss << build_info.config.node; - picosha2::hash256_hex_string(ss.str(), hash_sum); - } - - std::vector includes; - if (build_info.config.node["include"]) { - for (auto const &i: build_info.config.node["include"]) { - includes.push_back(i.as()); - } - } - - for (auto const &d: {build_info.depends, build_info.build_time_depends, includes}) { - for (auto const &i: d) { - { - auto depend_build_info = pool.find(i); - if (depend_build_info == pool.end()) { - throw std::runtime_error("missing required element '" + i + " for " + build_info.id); - } - std::stringstream ss; - ss << depend_build_info->second.config.node; - picosha2::hash256_hex_string(ss.str() + hash_sum, hash_sum); - } - } - } - - return hash_sum; -} - -void Ignite::build(const Builder::BuildInfo &build_info) { - auto container = setup_container(build_info, ContainerType::Build); - std::shared_ptr _(nullptr, [&container](...) { - // for (auto const& i : - // std::filesystem::recursive_directory_iterator(container.host_root)) { - // if (i.is_regular_file()) { - // if (access(i.path().c_str(), W_OK) != 0) { - // std::error_code code; - // std::filesystem::permissions(i.path(), - // std::filesystem::perms::owner_write, code); - // } - // } - // } - // std::filesystem::remove_all(container.host_root); - // TODO: std:filesystem failed to clean container host_root - // completely???? - Executor("/bin/rm").arg("-r").arg("-f").arg(container.host_root).execute(); - }); - std::ofstream logger(cache_path / "logs" / (build_info.package_name(build_info.element_id) + ".log")); - container.logger = &logger; - - auto package_path = cachefile(build_info); - auto builder = Builder(config, build_info, container); - auto subdir = builder.prepare_sources( - cache_path / "sources", - container.host_root / "build-root", - build_info.config.get("build-dir", "") != ""); - if (!subdir) subdir = "."; - - auto build_root = - std::filesystem::path("build-root") / build_info.config.get("build-dir", subdir->string()); - build_root = build_info.resolve(build_root.string(), config); - try { - builder.compile_source(build_root, "install-root"); - builder.pack(container.host_root / "install-root", package_path); - } catch (const std::exception &exception) { - ERROR(exception.what()) - PROCESS("Entering rescue shell"); - Executor("/bin/sh").container(container).execute(); - throw; - } -} - -Container Ignite::setup_container(const Builder::BuildInfo &build_info, const ContainerType container_type) { - auto env = std::vector < std::string > {"NOCONFIGURE=1", "HOME=/", "SHELL=/bin/sh", "TERM=dumb", "USER=nishu", - "LOGNAME=nishu", "LC_ALL=C", "TZ=UTC", "SOURCE_DATA_EPOCH=918239400"}; - if (auto n = config.node["environ"]; n) { - for (auto const &i: n) env.push_back(i.as()); - } - if (auto n = build_info.config.node["environ"]; n) { - for (auto const &i: n) env.push_back(i.as()); - } - - auto host_root = (cache_path / "temp" / build_info.package_name(build_info.element_id)); - std::filesystem::create_directories(host_root); - - std::vector capabilities; - if (build_info.config.node["capabilities"]) { - for (auto const &i: build_info.config.node["capabilities"]) { - capabilities.push_back(i.as()); - } - } - - auto container = Container{.environ = env, .binds = - {{"/sources", cache_path / "sources"}, - {"/cache", cache_path / "cache"}, - {"/files", project_path / "files"}, - {"/patches", project_path / "patches"}, - - }, .ro_binds = {{"/rlxos", - project_path}}, .capabilites = capabilities, .host_root = host_root, .base_dir = project_path, .name = build_info.package_name( - build_info.element_id),}; - for (auto const &i: {"sources", "cache"}) { - std::filesystem::create_directories(cache_path / i); - } - config.node["dir.build"] = host_root.string(); - - // TODO: temporary fix for glib and dependent packages to resolve - // -Werror=missing-include-dir - std::filesystem::create_directories(host_root / "usr" / "local" / "include"); - - std::vector states; - auto depends = build_info.depends; - if (container_type == ContainerType::Build) { - depends.insert(depends.end(), build_info.build_time_depends.begin(), build_info.build_time_depends.end()); - } - - resolve(depends, states, true, true, false); - for (auto const &[path, info, cached]: states) { - integrate(container, info, ""); - } - - if (container_type == ContainerType::Shell) { - integrate(container, build_info, ""); - } - - // Add Included elements to provided path - if (build_info.config.node["include"]) { - states.clear(); - - std::vector include; - for (auto const &i: build_info.config.node["include"]) { - include.push_back(build_info.resolve(i.as(), config)); - } - - resolve(include, states, false, build_info.config.get("include-depends", true), false); - - if (build_info.config.node["include-upon"]) { - std::vector sub_states; - resolve({build_info.config.node["include-upon"].as()}, sub_states, false, true, false); - states.erase(std::remove_if(states.begin(), states.end(), [&sub_states](const State &state) -> bool { - return std::find_if(sub_states.begin(), sub_states.end(), [&state](const State &other_state) -> bool { - return std::get<0>(state) == std::get<0>(other_state); - }) != sub_states.end(); - }), states.end()); - } - - auto include_parts = std::vector(); - for (auto const &i: build_info.config.node["include-parts"]) - include_parts.push_back(i.as()); - - auto include_core = build_info.config.get("include-core", true); - - for (auto const &[path, info, cached]: states) { - auto installation_path = std::filesystem::path("install-root") / build_info.package_name(); - installation_path = build_info.config.get(info.name() + "-include-path", - build_info.config.get( - "include-root", - installation_path.string())); - integrate(container, info, installation_path, include_parts, !include_core); - } - } - - return container; -} - -std::filesystem::path Ignite::cachefile(const Builder::BuildInfo &build_info) { - return cache_path / "cache" / build_info.package_name(build_info.element_id); -} - -void Ignite::integrate(Container &container, const Builder::BuildInfo &build_info, const std::filesystem::path &root, - std::vector extras, bool skip_core) { - auto container_root = - container.host_root / (root.has_root_path() ? std::filesystem::path(root.string().substr(1)) : root); - PROCESS("Integrating " << build_info.id); - std::filesystem::create_directories(container_root); - - auto cache_file_path = cachefile(build_info); - for (auto &e: extras) e.insert(e.begin(), '.'); - if (!skip_core) { extras.insert(extras.begin(), {""}); } - for (auto const &i: extras) { - auto sub_cache_file_path = cache_file_path.string() + i; - if (!std::filesystem::exists(sub_cache_file_path)) { - throw std::runtime_error(build_info.id + " not yet cached at " + sub_cache_file_path); - } - try { - auto extractor = Executor("/bin/tar") - .arg("-xPhf") - .arg(sub_cache_file_path) - .arg("-C") - .arg(container_root); - - if (root.empty()) { - extractor - .arg("--exclude=./etc/hosts") - .arg("--exclude=./etc/hostname") - .arg("--exclude=./etc/resolve.conf") - .arg("--exclude=./proc") - .arg("--exclude=./run") - .arg("--exclude=./sys") - .arg("--exclude=./dev"); - } - - extractor.execute(); - - } catch (const std::exception &exception) { - throw std::runtime_error("failed to integrate " + build_info.package_name(build_info.element_id) + i + " " + - exception.what()); - } - } - - if (root.empty() && !build_info.integration.empty()) { - DEBUG("INTEGRATION SCRIPT"); - auto integration_script = build_info.resolve(build_info.integration, config); - Executor("/bin/sh").arg("-ec").arg(integration_script).container(container).execute(); - } else { - auto meta_info = build_info; - meta_info.id = build_info.element_id; - - auto data_dir = container_root / "usr" / "share" / "pkgupd" / "manifest" / meta_info.name(); - std::filesystem::create_directories(data_dir); - - { - std::ofstream writer(data_dir / "info"); - writer << meta_info.str(); - } - if (!build_info.integration.empty()) { - auto integration_script = build_info.resolve(build_info.integration, config); - { - std::ofstream writer(data_dir / "integration"); - writer << integration_script; - } - } - - std::ofstream writer(data_dir / "files"); - int status = Executor("/bin/tar").arg("-tf").arg(cache_file_path).arg("--exclude=./etc/hosts").arg( - "--exclude=./etc/hostname").arg("--exclude=./etc/resolve.conf").arg("--exclude=./proc").arg( - "--exclude=./run").arg("--exclude=./sys").arg("--exclude=./dev").start().wait(&writer); - writer.close(); - if (status != 0) { - throw std::runtime_error("failed to read tar files from " + cache_file_path.string()); - } - } -} diff --git a/src/ignite/Ignite.h b/src/ignite/Ignite.h deleted file mode 100644 index 0d4ac12dc..000000000 --- a/src/ignite/Ignite.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2023 Manjeet Singh . - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#ifndef PKGUPD_IGNITE_H -#define PKGUPD_IGNITE_H - -#include "Builder.h" -#include "Container.h" - -struct Ignite { - const static std::vector SUB_PACKAGES; - std::map pool; - std::filesystem::path project_path, cache_path; - - Config config; - - using State = std::tuple; - - explicit Ignite(std::filesystem::path project_path, std::filesystem::path cache_path = {}); - - void load(); - - std::string hash(const Builder::BuildInfo &build_info); - - std::filesystem::path cachefile(const Builder::BuildInfo &build_info); - - void resolve(const std::vector &id, std::vector &output, bool devel = true, - bool include_depends = true, bool include_extra = true); - - enum class ContainerType { - Build, Shell, - }; - - Container - setup_container(const Builder::BuildInfo &build_info, ContainerType container_type = ContainerType::Shell); - - void integrate(Container &container, const Builder::BuildInfo &build_info, const std::filesystem::path &root = {}, - std::vector extras = {"devel"}, bool skip_core = false); - - void build(const Builder::BuildInfo &build_info); -}; - -#endif // PKGUPD_IGNITE_H diff --git a/src/ignite/MetaInfo.cpp b/src/ignite/MetaInfo.cpp deleted file mode 100644 index 018745be2..000000000 --- a/src/ignite/MetaInfo.cpp +++ /dev/null @@ -1,76 +0,0 @@ -#include "MetaInfo.h" - -#include "../common/Config.h" -#include - -void MetaInfo::update_from_data(const std::string &data, const std::string &filepath) { - config.update_from(data, filepath); - - id = config.get("id"); - version = config.get("version"); - about = config.get("about", ""); - cache = config.get("cache"); - - if (config.node["depends"]) { - for (auto const &dep: config.node["depends"]) { - depends.emplace_back(dep.as()); - } - } - if (config.node["backup"]) { - for (auto const &b: config.node["backup"]) - backup.push_back(b.as()); - } - if (config.node["integration"]) { - integration = config.node["integration"].as(); - } -} - -std::string MetaInfo::name() const { - auto name = this->id; - for (auto &c: name) - if (c == '/') c = '-'; - return name; -} - -std::string MetaInfo::package_name(std::string eid) const { - if (eid.empty()) eid = id; - for (auto &c: eid) - if (c == '/') c = '-'; - return eid + "-" + version + "-" + cache + ".pkg"; -} - -std::string MetaInfo::str() const { - std::stringstream ss; - ss << "id: " << id << "\n"; - - ss << "version: " << version << "\n" << "about: " << about << "\n" << "cache: " << cache << "\n"; - - if (!depends.empty()) { - ss << "depends:\n"; - for (auto const &i: depends) - ss << "- " << std::filesystem::path(i).replace_extension() << "\n"; - } - - if (!backup.empty()) { - ss << "backup:\n"; - for (auto const &i: backup) ss << "- " << i << "\n"; - } - - if (!integration.empty()) { - ss << "script: |-\n"; - std::string line; - std::stringstream script(integration); - while (std::getline(script, line)) { ss << " " << line << '\n'; } - ss << std::endl; - } - - return ss.str(); -} - -void MetaInfo::update_from_file(const std::string &filepath) { - std::ifstream reader(filepath); - if (!reader.good()) - throw std::runtime_error("failed to read file '" + filepath + "'"); - update_from_data(std::string((std::istreambuf_iterator(reader)), (std::istreambuf_iterator())), - filepath); -} diff --git a/src/ignite/MetaInfo.h b/src/ignite/MetaInfo.h deleted file mode 100644 index 31cc30abb..000000000 --- a/src/ignite/MetaInfo.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef LIBPKGUPD_METAINFO_HXX -#define LIBPKGUPD_METAINFO_HXX - -#include "../common/Config.h" - -/** - * @brief PackageInfo holds all the information of rlxos packages - * their dependencies and required user groups - */ - -struct MetaInfo { - std::string id, version, about; - std::string integration, cache; - - std::vector depends, backup; - Config config; - - MetaInfo() = default; - - explicit MetaInfo(std::string id, std::string version = "") : id(std::move(id)), version(std::move(version)) {} - - virtual ~MetaInfo() = default; - - static MetaInfo from_file(const std::string &filepath) { - MetaInfo metaInfo; - metaInfo.update_from_file(filepath); - return metaInfo; - } - - static MetaInfo from_data(const std::string &data, const std::string &filepath = "") { - MetaInfo metaInfo; - metaInfo.update_from_data(data, filepath); - return metaInfo; - } - - void update_from_data(const std::string &data, const std::string &filepath); - - void update_from_file(const std::string &filepath); - - [[nodiscard]] std::string name() const; - - [[nodiscard]] virtual std::string str() const; - - [[nodiscard]] std::string package_name(std::string eid = "") const; -}; - -#endif diff --git a/src/ignite/Resolver.h b/src/ignite/Resolver.h deleted file mode 100644 index 1090fb88a..000000000 --- a/src/ignite/Resolver.h +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef _LIBPKGUPD_RESOLVEDEPENDS_HH_ -#define _LIBPKGUPD_RESOLVEDEPENDS_HH_ - -#include "../defines.hxx" -#include -#include - -template class Resolver { -public: - std::map visited{}; - using GetPackageFunctionType = - std::function(const std::string& id)>; - using SkipPackageFunctionType = std::function; - using PackageDependsFunctionType = - std::function(Information pkg)>; - -private: - GetPackageFunctionType mGetPackageFunction; - SkipPackageFunctionType mSkipPackageFunction; - PackageDependsFunctionType mPackageDependsFunction; - - std::stringstream error; - - bool resolve(const std::string& id, std::vector& list) { - visited[id] = true; - auto meta_info = mGetPackageFunction(id); - if (!meta_info) { - error << "MISSING " << id; - return false; - } - if (mSkipPackageFunction(*meta_info)) { return true; } - - for (auto dep : mPackageDependsFunction(*meta_info)) { - if (dep.ends_with(".yml")) { - dep = dep.substr(0, dep.length() - 4); - } - if (auto iter = visited.find(dep); - iter != visited.end() && iter->second) { - continue; - } - - if (!resolve(dep, list)) { - error << "\n TRACEBACK " << id; - return false; - } - } - - list.emplace_back(*meta_info); - return true; - } - -public: - Resolver(GetPackageFunctionType get_fun, SkipPackageFunctionType skip_fun, - PackageDependsFunctionType depends_func) - : mGetPackageFunction{get_fun}, mSkipPackageFunction{skip_fun}, - mPackageDependsFunction{depends_func} {} - - void depends(const std::vector& ids, - std::vector& list) { - for (auto const& id : ids) { - if (!resolve(id, list)) { - throw std::runtime_error("failed to resolve dependency for '" + - id + "'\n" + traceback()); - } - } - } - - std::string traceback() const { return error.str(); } -}; - -#endif diff --git a/src/ignite/main.cpp b/src/ignite/main.cpp deleted file mode 100644 index 61c1cf17c..000000000 --- a/src/ignite/main.cpp +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (c) 2024 Manjeet Singh . - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include "../common/Application.h" -#include "../external/json.h" -#include "ArchiveManager.h" -#include "Executor.h" -#include "Ignite.h" -#include "../external/Curl.h" - -struct IgniteApp : Application { - IgniteApp() : Application("ignite", "Project Management tool") { - REGISTER_COMMAND(IgniteApp, status, "Display status of element", 1); - REGISTER_COMMAND(IgniteApp, build, "Build component from element file", 1); - REGISTER_COMMAND(IgniteApp, checkout, "Checkout cached component", 2); - REGISTER_COMMAND(IgniteApp, meta, "Generate metadata", 1); - REGISTER_COMMAND(IgniteApp, pull, "Pull already built cache from server", 1); - REGISTER_COMMAND(IgniteApp, filepath, "Print filepath of cached artifact", 1); - } - - void init() override { - auto project_path = ctxt["project-path"].value_or(std::filesystem::current_path().string()); - auto cache_path = ctxt["cache-path"].value_or(project_path + "/build"); - backend = std::make_unique(project_path, cache_path); - - backend->load(); - } - - void filepath() { - auto source = ctxt.args[0]; - - std::vector> status; - backend->resolve({source}, status); - - auto [path, build_info, cached] = status.back(); - if (!cached) { throw std::runtime_error(path + " not cached yet"); } - - build_info.cache = backend->hash(build_info); - std::cout << backend->cachefile(build_info).string() << std::endl; - } - - void pull() { - auto element = ctxt.args[0]; - std::vector> status; - backend->resolve({ctxt.args[0]}, status, true, true, true); - - auto artifact_server = ctxt["artifact-server"]; - if (!artifact_server) { - artifact_server = backend->config.get("artifact-server"); - } - - for (auto &[path, build_info, cached]: status) { - build_info.cache = backend->hash(build_info); - auto cache_file = backend->cachefile(build_info); - auto filename = cache_file.filename(); - for (auto const &ext: {"", ".devel", ".doc", ".dbg"}) { - if (std::filesystem::exists(cache_file.string() + ext)) continue; - PROCESS("GETTING " << filename.string() << ext); - Curl().url(*artifact_server + "/cache/" + filename.string() + ext).download(cache_file.string() + ext); - } - - } - } - - void meta() { - std::filesystem::path target_path = ctxt.args[0]; - - nlohmann::json data; - auto meta_json = target_path / "meta.json"; - std::filesystem::remove_all(target_path / "apps"); - std::filesystem::create_directories(target_path / "apps"); - - for (auto [path, build_info]: backend->pool) { - build_info.cache = backend->hash(build_info); - auto cache_file = backend->cachefile(build_info); - if (std::filesystem::exists(cache_file)) { - auto depends = std::vector(); - for (std::filesystem::path depend: build_info.depends) { - depends.push_back(depend.replace_extension()); - } - - auto type = build_info.config.get("type", "component"); - - data.push_back({{"id", std::filesystem::path(path).replace_extension()}, - {"version", build_info.version}, - {"about", build_info.about}, - {"cache", build_info.cache}, - {"depends", depends}, - {"type", type}, - {"integration", build_info.integration}, - {"backup", build_info.backup},}); - if (type == "app") { - PROCESS("Adding App " << data.back()["id"].get()); - Executor("/bin/tar").arg("-xf").arg(cache_file).arg("-C").arg(target_path / "apps").execute(); - } - } - } - - std::ofstream writer(meta_json); - writer << data; - } - - void checkout() { - auto source = ctxt.args[0]; - auto target = ctxt.args[1]; - std::filesystem::create_directories(target); - - std::vector> status; - backend->resolve({source}, status); - - auto [path, build_info, cached] = status.back(); - if (!cached) { throw std::runtime_error(path + " not cached yet"); } - - std::vector files; - ArchiveManager::extract(backend->cachefile(build_info), target, files); - } - - void build() { - std::vector> status; - backend->resolve({ctxt.args[0]}, status, true, true, true); - - int count = 0; - for (auto &[path, build_info, cached]: status) { - if (cached) { continue; } - PROCESS("Building " << path) - build_info.resolve(backend->config); - backend->build(build_info); - count++; - } - if (count == 0) { - INFO("Component already cached") - } - } - - void status() { - std::vector> status; - backend->resolve({ctxt.args[0]}, status, true, true, true); - for (auto const &[path, build_info, cached]: status) { - if (cached) { - MESSAGE(" " GREEN("CACHED"), path); - } else { - MESSAGE(" " BLUE("WAITING"), path); - } - } - } - -private: - std::unique_ptr backend{nullptr}; -}; - -int main(int argc, char **argv) { return IgniteApp().run(argc, argv); } \ No newline at end of file diff --git a/src/pkgupd b/src/pkgupd new file mode 160000 index 000000000..1e8a41d69 --- /dev/null +++ b/src/pkgupd @@ -0,0 +1 @@ +Subproject commit 1e8a41d69f25c03dba47d6146ce4a1347f1f3b0d