mirror of
https://gitlab.redox-os.org/redox-os/redox.git
synced 2026-11-05 04:06:38 +08:00
Merge branch 'csv-export' into 'master'
repo: Export as CSV, fix all invalid dependencies See merge request redox-os/redox!2285
This commit is contained in:
commit
67a88b9c76
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -895,7 +895,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "redox_installer"
|
||||
version = "0.2.42"
|
||||
source = "git+https://gitlab.redox-os.org/redox-os/installer.git#1c2534e44c68ace0a21db2a1bc9503945a38c809"
|
||||
source = "git+https://gitlab.redox-os.org/redox-os/installer.git#d7409a2cc6ebd44eab9f0c57551bb0b2798d21e1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"arg_parser",
|
||||
|
||||
@ -18,7 +18,7 @@ repo-tree: $(FSTOOLS_TAG) $(CONTAINER_TAG)
|
||||
ifeq ($(PODMAN_BUILD),1)
|
||||
$(PODMAN_RUN) make $@
|
||||
else
|
||||
@$(REPO_BIN) cook-tree $(COOKBOOK_OPTS) --with-package-deps
|
||||
@$(REPO_BIN) cook-list $(COOKBOOK_OPTS) --with-package-deps
|
||||
endif
|
||||
|
||||
# List all recipes in a push-tree fashion specified by the filesystem config
|
||||
@ -26,7 +26,7 @@ image-tree: $(FSTOOLS_TAG) $(CONTAINER_TAG)
|
||||
ifeq ($(PODMAN_BUILD),1)
|
||||
$(PODMAN_RUN) make $@
|
||||
else
|
||||
@$(REPO_BIN) push-tree $(COOKBOOK_OPTS)
|
||||
@$(REPO_BIN) push-list $(COOKBOOK_OPTS)
|
||||
endif
|
||||
|
||||
# Clean specific target to all recipes, similar to repo_clean but more specific
|
||||
@ -115,7 +115,7 @@ rt.%: $(FSTOOLS_TAG) FORCE
|
||||
ifeq ($(PODMAN_BUILD),1)
|
||||
$(PODMAN_RUN) make $@
|
||||
else
|
||||
$(REPO_BIN) cook-tree $(foreach f,$(subst $(comma), ,$*),$(f)) $(COOKBOOK_OPTS)
|
||||
$(REPO_BIN) cook-list $(foreach f,$(subst $(comma), ,$*),$(f)) $(COOKBOOK_OPTS)
|
||||
endif
|
||||
|
||||
MOUNTED_TAG=$(MOUNT_DIR)~
|
||||
@ -147,7 +147,7 @@ pt.%: $(FSTOOLS_TAG) FORCE
|
||||
ifeq ($(PODMAN_BUILD),1)
|
||||
$(PODMAN_RUN) make $@
|
||||
else
|
||||
$(REPO_BIN) push-tree $(foreach f,$(subst $(comma), ,$*),$(f)) $(COOKBOOK_OPTS)
|
||||
$(REPO_BIN) push-list $(foreach f,$(subst $(comma), ,$*),$(f)) $(COOKBOOK_OPTS)
|
||||
endif
|
||||
|
||||
# Push all recipes specified by the filesystem config
|
||||
|
||||
@ -2,4 +2,4 @@
|
||||
[source]
|
||||
tar = "https://7-zip.org/a/7z2301-src.tar.xz"
|
||||
[build]
|
||||
template = "custom"
|
||||
template = "cmake"
|
||||
|
||||
@ -5,7 +5,7 @@ git = "https://github.com/facebook/rocksdb"
|
||||
rev = "v10.7.5"
|
||||
shallow_clone = true
|
||||
[build]
|
||||
template = "custom"
|
||||
template = "cmake"
|
||||
dependencies = [
|
||||
"zlib",
|
||||
"lz4",
|
||||
|
||||
@ -9,7 +9,7 @@ cargopackages = [
|
||||
"allocscope-view",
|
||||
]
|
||||
dependencies = [
|
||||
"libiberty",
|
||||
# "libiberty",
|
||||
"ncursesw",
|
||||
"sqlite3",
|
||||
"libunwind",
|
||||
|
||||
@ -10,5 +10,5 @@ dependencies = [
|
||||
"libgc",
|
||||
"readline",
|
||||
"libffi",
|
||||
"libintl",
|
||||
"gettext",
|
||||
]
|
||||
|
||||
@ -3,4 +3,4 @@
|
||||
git = "https://github.com/ispc/ispc"
|
||||
rev = "bd2c42d42e0cc3da1baf92160b82d4dc820a02ee"
|
||||
[build]
|
||||
template = "custom"
|
||||
template = "cmake"
|
||||
|
||||
@ -13,7 +13,7 @@ dependencies = [
|
||||
"glew",
|
||||
"zlib",
|
||||
"freeglut",
|
||||
"glm",
|
||||
# "glm",
|
||||
"curl",
|
||||
"ngspice",
|
||||
]
|
||||
|
||||
@ -5,7 +5,7 @@ tar = "http://lttng.org/files/lttng-ust/lttng-ust-2.13.6.tar.bz2"
|
||||
template = "configure"
|
||||
dependencies = [
|
||||
"libxml2",
|
||||
"lttng",
|
||||
# "lttng",
|
||||
"liburcu",
|
||||
"libuuid",
|
||||
"popt",
|
||||
|
||||
@ -4,7 +4,7 @@ git = "https://github.com/probe-rs/probe-rs"
|
||||
[build]
|
||||
template = "custom"
|
||||
dependencies = [
|
||||
"libudev",
|
||||
# "libudev",
|
||||
]
|
||||
script = """
|
||||
cookbook_cargo --features cli
|
||||
|
||||
@ -26,7 +26,7 @@ cmakeflags = [
|
||||
]
|
||||
dependencies = [
|
||||
"libhidapi",
|
||||
"mbedtls",
|
||||
# "mbedtls",
|
||||
"sdl3",
|
||||
"libusb",
|
||||
"lz4",
|
||||
@ -36,7 +36,7 @@ dependencies = [
|
||||
"xxhash",
|
||||
"bzip2",
|
||||
"libenet",
|
||||
"pugixml",
|
||||
# "pugixml",
|
||||
"glslang",
|
||||
"libfmt",
|
||||
]
|
||||
|
||||
@ -7,5 +7,5 @@ rev = "8b2aea09d431bd5497ae223c141ebaee7bdd481f"
|
||||
template = "cmake"
|
||||
dependencies = [
|
||||
"libfuse3",
|
||||
"mbedtls",
|
||||
# "mbedtls",
|
||||
]
|
||||
|
||||
@ -6,7 +6,7 @@ template = "configure"
|
||||
dependencies = [
|
||||
"libfuse3",
|
||||
"zlib",
|
||||
"liblzma",
|
||||
# "liblzma",
|
||||
"lz4",
|
||||
"zstd",
|
||||
]
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
[build]
|
||||
template = "custom"
|
||||
dev-dependencies = [
|
||||
"host:lhasa",
|
||||
# "host:lhasa",
|
||||
"host:unzip-rs",
|
||||
"host:7zip",
|
||||
]
|
||||
|
||||
@ -12,7 +12,7 @@ dependencies = [
|
||||
"sdl2-image",
|
||||
"freealut",
|
||||
"freetype2",
|
||||
"opus",
|
||||
# "opus",
|
||||
"opusfile",
|
||||
"libjpeg",
|
||||
"openal",
|
||||
|
||||
@ -15,11 +15,11 @@ dependencies = [
|
||||
"libpng",
|
||||
"libjpeg",
|
||||
"libwebp",
|
||||
"freetype",
|
||||
"freetype2",
|
||||
"openal",
|
||||
"libogg",
|
||||
"libvorbis",
|
||||
"opus",
|
||||
# "opus",
|
||||
"opusfile",
|
||||
]
|
||||
script = """
|
||||
|
||||
@ -18,7 +18,7 @@ dependencies = [
|
||||
"libxml2",
|
||||
"ffmpeg6",
|
||||
"libjpeg",
|
||||
"portaudio",
|
||||
# "portaudio",
|
||||
"boost",
|
||||
"nlohmann-json",
|
||||
"aubio",
|
||||
|
||||
@ -18,8 +18,8 @@ dependencies = [
|
||||
"bzip2",
|
||||
"libogg",
|
||||
"libvorbis",
|
||||
"pulseaudio",
|
||||
"libiberty",
|
||||
# "pulseaudio",
|
||||
# "libiberty",
|
||||
"gtk3",
|
||||
"libmad",
|
||||
]
|
||||
|
||||
@ -16,7 +16,7 @@ dependencies = [
|
||||
"libpng",
|
||||
"freetype2",
|
||||
"libfmt",
|
||||
"libcurl",
|
||||
"curl",
|
||||
"openal",
|
||||
"libogg",
|
||||
"libvorbis",
|
||||
|
||||
@ -14,7 +14,7 @@ dependencies = [
|
||||
"sdl3",
|
||||
"physicsfs",
|
||||
"libpng",
|
||||
"libjpeg-turbo",
|
||||
# "libjpeg-turbo",
|
||||
"libtheora",
|
||||
"libvorbis",
|
||||
"libogg",
|
||||
|
||||
@ -13,7 +13,7 @@ dependencies = [
|
||||
# "gck2",
|
||||
# "gcr4",
|
||||
"gdk-pixbuf",
|
||||
"gio2",
|
||||
# "gio2",
|
||||
# "gio-unix2",
|
||||
# "glib2",
|
||||
# "granite7",
|
||||
|
||||
@ -13,13 +13,13 @@ dependencies = [
|
||||
"expat",
|
||||
"freetype2",
|
||||
"fontconfig",
|
||||
"libjpeg-turbo",
|
||||
# "libjpeg-turbo",
|
||||
"libpng",
|
||||
"libwebp",
|
||||
"zlib",
|
||||
"qt5-base",
|
||||
"qt5-gui",
|
||||
"qt5-widgets",
|
||||
# "qt5-gui",
|
||||
# "qt5-widgets",
|
||||
"qt5-3d",
|
||||
"qt5-multimedia",
|
||||
"qscintilla",
|
||||
|
||||
@ -6,6 +6,6 @@ rev = "be0accfd0b246e2b03355b8ee7710a22c1b49240"
|
||||
[build]
|
||||
template = "cmake"
|
||||
dependencies = [
|
||||
"glfw",
|
||||
"glfw3",
|
||||
"onetbb",
|
||||
]
|
||||
|
||||
@ -12,7 +12,7 @@ dependencies = [
|
||||
"libfmt",
|
||||
"freetype2",
|
||||
"glew",
|
||||
"imath",
|
||||
"libimath",
|
||||
"lz4",
|
||||
"libffi",
|
||||
"libjpeg",
|
||||
|
||||
@ -10,6 +10,6 @@ dependencies = [
|
||||
"onetbb",
|
||||
"librkcommon",
|
||||
"mesa",
|
||||
"glfw",
|
||||
"open-image-denoise",
|
||||
"glfw3",
|
||||
# "open-image-denoise",
|
||||
]
|
||||
|
||||
@ -11,5 +11,5 @@ dependencies = [
|
||||
"ispc",
|
||||
"onetbb",
|
||||
"openvkl",
|
||||
"open-image-denoise",
|
||||
# "open-image-denoise",
|
||||
]
|
||||
|
||||
@ -16,7 +16,7 @@ dependencies = [
|
||||
"liblcms",
|
||||
"libpng",
|
||||
"librsvg",
|
||||
"libsigc++",
|
||||
# "libsigc++",
|
||||
"libtiff",
|
||||
"zlib",
|
||||
]
|
||||
|
||||
@ -34,7 +34,7 @@ dependencies = [
|
||||
"kxmlgui6",
|
||||
"knotifications6",
|
||||
"kguiaddons6",
|
||||
"ktextwidgets6",
|
||||
# "ktextwidgets6",
|
||||
"kiconthemes6",
|
||||
"solid6",
|
||||
"kfilemetadata6",
|
||||
|
||||
@ -7,5 +7,5 @@ dependencies = [
|
||||
"glib",
|
||||
"gobject-introspection",
|
||||
"sqlite3",
|
||||
"gdkpixbuf",
|
||||
"gdk-pixbuf",
|
||||
]
|
||||
|
||||
@ -5,7 +5,7 @@ tar = "https://download.gnome.org/sources/libhandy/1.8/libhandy-1.8.3.tar.xz"
|
||||
[build]
|
||||
template = "meson"
|
||||
mesonflags = [
|
||||
"-Dtests=false"
|
||||
"-Dtests=false",
|
||||
"-Dintrospection=false",
|
||||
]
|
||||
dependencies = [
|
||||
|
||||
@ -4,12 +4,12 @@ tar = "https://download.kde.org/stable/frameworks/6.27/kxmlgui-6.27.0.tar.xz"
|
||||
[build]
|
||||
template = "cmake"
|
||||
cmakeflags = [
|
||||
"-DBUILD_DESIGNERPLUGIN=OFF"
|
||||
"-DBUILD_DESIGNERPLUGIN=OFF",
|
||||
"-DUSE_DBUS_DEFAULT=OFF",
|
||||
"-DBUILD_PYTHON_BINDINGS=OFF",
|
||||
]
|
||||
dependencies = [
|
||||
"qt6-base"
|
||||
"qt6-base",
|
||||
"kcoreaddons6",
|
||||
"kitemviews6",
|
||||
"kconfig6",
|
||||
|
||||
@ -15,7 +15,7 @@ dependencies = [
|
||||
"knotifications6",
|
||||
"kio6",
|
||||
"kservice6",
|
||||
"kprison6",
|
||||
# "kprison6",
|
||||
"kitemmodels6",
|
||||
"kcmutils6",
|
||||
]
|
||||
|
||||
@ -2,4 +2,4 @@
|
||||
[source]
|
||||
tar = "https://www.slicot.org/objects/software/shared/slicot45.tar.gz"
|
||||
[build]
|
||||
template = "custom"
|
||||
template = "cmake"
|
||||
|
||||
@ -2,4 +2,4 @@
|
||||
[source]
|
||||
tar = "https://github.com/arvidn/libtorrent/releases/download/v2.0.11/libtorrent-rasterbar-2.0.11.tar.gz"
|
||||
[build]
|
||||
template = "custom"
|
||||
template = "cmake"
|
||||
|
||||
@ -3,4 +3,4 @@
|
||||
git = "https://github.com/P-H-C/phc-winner-argon2"
|
||||
shallow_clone = true
|
||||
[build]
|
||||
template = "custom"
|
||||
template = "cmake"
|
||||
|
||||
@ -2,4 +2,4 @@
|
||||
[source]
|
||||
tar = "https://botan.randombit.net/releases/Botan-3.2.0.tar.xz"
|
||||
[build]
|
||||
template = "custom"
|
||||
template = "cmake"
|
||||
|
||||
@ -2,4 +2,4 @@
|
||||
[source]
|
||||
tar = "https://kernel.org/pub/linux/libs/security/linux-privs/libcap2/libcap-2.69.tar.xz"
|
||||
[build]
|
||||
template = "custom"
|
||||
template = "cmake"
|
||||
|
||||
@ -6,10 +6,10 @@ template = "meson"
|
||||
dependencies = [
|
||||
"libzim",
|
||||
"libicu",
|
||||
"pugixml",
|
||||
# "pugixml",
|
||||
"mustache",
|
||||
"curl",
|
||||
"microhttpd",
|
||||
"libmicrohttpd",
|
||||
"zlib",
|
||||
]
|
||||
[package]
|
||||
|
||||
@ -5,4 +5,4 @@
|
||||
[source]
|
||||
tar = "https://github.com/zeux/pugixml/releases/download/v1.15/pugixml-1.15.tar.gz"
|
||||
[build]
|
||||
template = "custom"
|
||||
template = "cmake"
|
||||
|
||||
@ -10,7 +10,7 @@ cmakeflags = [
|
||||
]
|
||||
dependencies = [
|
||||
"expat",
|
||||
"imath",
|
||||
"libimath",
|
||||
"zlib",
|
||||
"yaml-cpp",
|
||||
"minizip-ng",
|
||||
|
||||
@ -10,7 +10,7 @@ cmakeflags = [
|
||||
"-DOIIO_BUILD_TESTS=OFF",
|
||||
]
|
||||
dependencies = [
|
||||
"imath",
|
||||
"libimath",
|
||||
"libtiff",
|
||||
"libjpeg",
|
||||
"openexr",
|
||||
|
||||
@ -8,10 +8,10 @@ git = "https://github.com/movableink/webkit"
|
||||
template = "cmake"
|
||||
dependencies = [
|
||||
"qt5-base",
|
||||
"qt5-guiaddons",
|
||||
# "qt5-guiaddons",
|
||||
"qt5-connectivity",
|
||||
"qt5-networkauth",
|
||||
"qt5-positioning",
|
||||
# "qt5-positioning",
|
||||
"qt5-sensors",
|
||||
"qt5-declarative",
|
||||
"qt5-webchannel",
|
||||
|
||||
@ -4,4 +4,4 @@ git = "https://github.com/brCreate/QScintilla"
|
||||
rev = "6608e9a434b027f42e0c5961443d0f08047f0cd3"
|
||||
shallow_clone = true
|
||||
[build]
|
||||
template = "custom"
|
||||
template = "cmake"
|
||||
|
||||
@ -2,4 +2,4 @@
|
||||
[source]
|
||||
tar = "http://miniupnp.free.fr/files/miniupnpc-2.2.4.tar.gz"
|
||||
[build]
|
||||
template = "custom"
|
||||
template = "cmake"
|
||||
|
||||
@ -2,4 +2,4 @@
|
||||
[source]
|
||||
tar = "https://ftp.mozilla.org/pub/security/nss/releases/NSS_3_9_2_RTM/src/nss-3.9.2.tar.gz"
|
||||
[build]
|
||||
template = "custom"
|
||||
template = "cmake"
|
||||
|
||||
@ -7,5 +7,5 @@ rev = "eea87b1d893ae58e0b08bc381730c502024ae71f"
|
||||
template = "cmake"
|
||||
dependencies = [
|
||||
"fftw",
|
||||
"mbedtls",
|
||||
# "mbedtls",
|
||||
]
|
||||
|
||||
@ -8,5 +8,5 @@ rev = "374200deefd8e1b96fab7328525fd593a808a641"
|
||||
template = "cmake"
|
||||
dependencies = [
|
||||
"fftw",
|
||||
"mbedtls",
|
||||
# "mbedtls",
|
||||
]
|
||||
|
||||
@ -15,7 +15,7 @@ dependencies = [
|
||||
"gtk3",
|
||||
"libgcrypt",
|
||||
"libssh",
|
||||
"libvte",
|
||||
# "libvte",
|
||||
"libjpeg",
|
||||
"gnutls3",
|
||||
"libsodium",
|
||||
|
||||
@ -10,5 +10,5 @@ dependencies = [
|
||||
"taglib",
|
||||
"sqlite3",
|
||||
"libpeas",
|
||||
"totem-plparser",
|
||||
"totem-pl-parser",
|
||||
]
|
||||
|
||||
@ -13,7 +13,7 @@ dependencies = [
|
||||
"libxrandr",
|
||||
"libxfixes",
|
||||
"libxdamage",
|
||||
"pulseaudio",
|
||||
# "pulseaudio",
|
||||
"libva",
|
||||
"libcap",
|
||||
"libwayland",
|
||||
|
||||
@ -12,5 +12,5 @@ cmakeflags = [
|
||||
]
|
||||
dependencies = [
|
||||
"qt6-base",
|
||||
"libgdal",
|
||||
"gdal",
|
||||
]
|
||||
|
||||
@ -2,4 +2,4 @@
|
||||
[source]
|
||||
tar = "https://aubio.org/pub/aubio-0.4.7.tar.bz2"
|
||||
[build]
|
||||
template = "custom"
|
||||
template = "cmake"
|
||||
|
||||
@ -5,7 +5,7 @@ rev = "3ef25e881cec9ee823d9cf93346c2d6feb089007"
|
||||
[build]
|
||||
template = "custom"
|
||||
dependencies = [
|
||||
"pulseaudio",
|
||||
# "pulseaudio",
|
||||
"libsndfile",
|
||||
"qt6-base",
|
||||
]
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
[source]
|
||||
tar = "https://mirrors.edge.kernel.org/pub/software/utils/pciutils/pciutils-3.9.0.tar.xz"
|
||||
[build]
|
||||
template = "custom"
|
||||
template = "cmake"
|
||||
dependencies = [
|
||||
"zlib",
|
||||
]
|
||||
|
||||
@ -10,5 +10,5 @@ dependencies = [
|
||||
"qt6-base",
|
||||
"kcoreaddons6",
|
||||
"knotifications6",
|
||||
"kl18n6",
|
||||
# "kl18n6",
|
||||
]
|
||||
|
||||
@ -8,7 +8,7 @@ rev = "116f1d16f6dc33ab8b0f6010a44e7b23eadeb8ca"
|
||||
template = "cmake"
|
||||
dependencies = [
|
||||
"fontconfig",
|
||||
"freetyoe2",
|
||||
"freetype2",
|
||||
"harfbuzz",
|
||||
"libssh2",
|
||||
"ncursesw",
|
||||
|
||||
@ -5,7 +5,7 @@ rev = "50f8f1c8bc019a4c0fd098b9ac674b94cfc6af0d"
|
||||
[build]
|
||||
template = "custom"
|
||||
dependencies = [
|
||||
"libbrotili",
|
||||
"libbrotli",
|
||||
"openssl3",
|
||||
"curl",
|
||||
"sqlite3",
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
git = "https://github.com/jordansissel/xdotool"
|
||||
rev = "eb489de1b4fb3fd0cd935d68ae16ecd4c653ac7d"
|
||||
[build]
|
||||
template = "custom"
|
||||
template = "cmake"
|
||||
dependencies = [
|
||||
"libx11",
|
||||
"libxi",
|
||||
|
||||
@ -12,7 +12,7 @@ dependencies = [
|
||||
"libcap",
|
||||
"curl",
|
||||
"libopus",
|
||||
"pulseaudio",
|
||||
# "pulseaudio",
|
||||
"qt5-3d",
|
||||
"qt5-x11extras",
|
||||
"qt5-tools",
|
||||
|
||||
@ -8,6 +8,6 @@ shallow_clone = true
|
||||
template = "meson"
|
||||
dependencies = [
|
||||
"libwayland",
|
||||
"wayland-scanner",
|
||||
# "wayland-scanner",
|
||||
"wayland-protocols",
|
||||
]
|
||||
|
||||
@ -17,7 +17,7 @@ dependencies = [
|
||||
"gtk3",
|
||||
"pango",
|
||||
"sqlite3",
|
||||
"nss-nspr",
|
||||
# "nss-nspr",
|
||||
"startup-notification",
|
||||
"zlib",
|
||||
"ffmpeg6",
|
||||
|
||||
@ -7,7 +7,7 @@ use cookbook::cook::fs::{
|
||||
};
|
||||
use cookbook::cook::package::{package, package_handle_push};
|
||||
use cookbook::cook::pty::{PtyOut, flush_pty, write_to_pty};
|
||||
use cookbook::cook::tree::{self, WalkTreeEntry};
|
||||
use cookbook::cook::tree::{self, DisplayOptions, TreeData, TreeItem, TreeOptions, WalkTreeEntry};
|
||||
use cookbook::cook::tui::join_logs;
|
||||
use cookbook::cook::{fetch_repo, ident};
|
||||
use cookbook::recipe::{
|
||||
@ -41,9 +41,9 @@ const REPO_HELP_STR: &str = r#"
|
||||
clean delete recipe artifacts
|
||||
clean-target delete recipe artifacts for one target
|
||||
push extract package into sysroot
|
||||
find find path of recipe packages
|
||||
cook-tree show tree of recipe build
|
||||
push-tree show tree of recipe packages
|
||||
repo-list show list of recipes
|
||||
cook-list show list of recipes to build
|
||||
push-list show list of recipes to package
|
||||
capture-rev write lock to git recipes
|
||||
change-rule override rule to recipes
|
||||
change-rule-local override rule to specific recipes
|
||||
@ -53,12 +53,14 @@ const REPO_HELP_STR: &str = r#"
|
||||
--repo=<repo_dir> the "repo" folder, default to $PWD/repo
|
||||
--with-package-deps include package deps (always implied in push command)
|
||||
--all apply to all recipes in <cookbook_dir>
|
||||
--all-binaries apply to all recipes in <cookbook_dir> that is configured as "binary"
|
||||
--all-compiled apply to all compiled recipes in <cookbook_dir>
|
||||
--all-binaries apply to all compiled recipes in <cookbook_dir> that is configured as "binary"
|
||||
--category=<category> apply to all recipes in <cookbook_dir>/<category>
|
||||
--filesystem=<filesystem> override recipes config using installer file
|
||||
--repo-binary override recipes config to use repo_binary
|
||||
--sysroot=<sysroot_dir> used in "push", the "root" dir, default to $PWD/sysroot
|
||||
--no-metadata used in "push", do not write pkgar_head or etc dir
|
||||
--display=<format> used in "*-list", either "name", "path", "csv", "tree"
|
||||
--set-rule=<rule> used in "change-rule", set wanted config rule
|
||||
--rollback used in "capture-rev", allow git to rollback
|
||||
--unset used in "capture-rev" and "change-rule", unset locks
|
||||
@ -87,12 +89,12 @@ struct CliConfig {
|
||||
category: Option<PathBuf>,
|
||||
filesystem: Option<redox_installer::Config>,
|
||||
set_rule: Option<String>,
|
||||
display: DisplayOptions,
|
||||
unset: bool,
|
||||
no_metadata: bool,
|
||||
with_rollback: bool,
|
||||
with_package_deps: bool,
|
||||
all: bool,
|
||||
binaries_only: bool,
|
||||
all: Option<AllOption>,
|
||||
cook: CookConfig,
|
||||
}
|
||||
|
||||
@ -100,37 +102,62 @@ struct CliConfig {
|
||||
enum CliCommand {
|
||||
Fetch,
|
||||
Cook,
|
||||
CookTree,
|
||||
Unfetch,
|
||||
Clean,
|
||||
CleanTarget,
|
||||
Push,
|
||||
PushTree,
|
||||
Find,
|
||||
CookList,
|
||||
PushList,
|
||||
RepoList,
|
||||
CaptureRev,
|
||||
ChangeRule,
|
||||
ChangeRuleLocal,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
enum AllOption {
|
||||
All,
|
||||
AllCompiled,
|
||||
AllBinaries,
|
||||
}
|
||||
|
||||
impl CliCommand {
|
||||
pub fn is_informational(&self) -> bool {
|
||||
*self == CliCommand::PushTree || *self == CliCommand::CookTree || *self == CliCommand::Find
|
||||
*self == CliCommand::PushList
|
||||
|| *self == CliCommand::CookList
|
||||
|| *self == CliCommand::RepoList
|
||||
}
|
||||
pub fn is_tree(&self) -> bool {
|
||||
self.is_informational()
|
||||
}
|
||||
pub fn is_change_rule(&self) -> bool {
|
||||
*self == CliCommand::ChangeRuleLocal
|
||||
|| *self == CliCommand::CaptureRev
|
||||
|| *self == CliCommand::ChangeRule
|
||||
}
|
||||
pub fn is_building(&self) -> bool {
|
||||
*self == CliCommand::Fetch
|
||||
|| *self == CliCommand::Cook
|
||||
|| *self == CliCommand::CookTree
|
||||
|| *self == CliCommand::CookList
|
||||
|| *self == CliCommand::CaptureRev
|
||||
|| *self == CliCommand::ChangeRule
|
||||
}
|
||||
pub fn is_pushing(&self) -> bool {
|
||||
*self == CliCommand::Push || *self == CliCommand::PushTree
|
||||
*self == CliCommand::Push || *self == CliCommand::PushList
|
||||
}
|
||||
pub fn is_cleaning(&self) -> bool {
|
||||
*self == CliCommand::Clean
|
||||
|| *self == CliCommand::CleanTarget
|
||||
|| *self == CliCommand::Unfetch
|
||||
}
|
||||
pub fn to_tree(&self) -> TreeOptions {
|
||||
match self {
|
||||
CliCommand::CookList => TreeOptions::Cook,
|
||||
CliCommand::PushList => TreeOptions::Push,
|
||||
CliCommand::RepoList => TreeOptions::Repo,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for CliCommand {
|
||||
@ -146,9 +173,11 @@ impl FromStr for CliCommand {
|
||||
"clean" => Ok(CliCommand::Clean),
|
||||
"clean-target" => Ok(CliCommand::CleanTarget),
|
||||
"push" => Ok(CliCommand::Push),
|
||||
"push-tree" => Ok(CliCommand::PushTree),
|
||||
"cook-tree" => Ok(CliCommand::CookTree),
|
||||
"find" => Ok(CliCommand::Find),
|
||||
"repo-tree" => Ok(CliCommand::RepoList),
|
||||
"push-tree" => Ok(CliCommand::PushList),
|
||||
"cook-tree" => Ok(CliCommand::CookList),
|
||||
// alias for scripts
|
||||
"find" => Ok(CliCommand::RepoList),
|
||||
"capture-rev" => Ok(CliCommand::CaptureRev),
|
||||
"change-rule" => Ok(CliCommand::ChangeRule),
|
||||
"change-rule-local" => Ok(CliCommand::ChangeRuleLocal),
|
||||
@ -166,9 +195,9 @@ impl ToString for CliCommand {
|
||||
CliCommand::Clean => "clean".to_string(),
|
||||
CliCommand::CleanTarget => "clean-target".to_string(),
|
||||
CliCommand::Push => "push".to_string(),
|
||||
CliCommand::PushTree => "push-tree".to_string(),
|
||||
CliCommand::CookTree => "cook-tree".to_string(),
|
||||
CliCommand::Find => "find".to_string(),
|
||||
CliCommand::PushList => "push-tree".to_string(),
|
||||
CliCommand::CookList => "cook-tree".to_string(),
|
||||
CliCommand::RepoList => "repo-tree".to_string(),
|
||||
CliCommand::CaptureRev => "capture-rev".to_string(),
|
||||
CliCommand::ChangeRule => "change-rule".to_string(),
|
||||
CliCommand::ChangeRuleLocal => "change-rule-local".to_string(),
|
||||
@ -190,11 +219,11 @@ impl CliConfig {
|
||||
None
|
||||
},
|
||||
category: None,
|
||||
display: DisplayOptions::Tree,
|
||||
sysroot_dir: current_dir.join("sysroot"),
|
||||
with_package_deps: false,
|
||||
cook: get_config().cook.clone(),
|
||||
all: false,
|
||||
binaries_only: false,
|
||||
all: None,
|
||||
unset: false,
|
||||
no_metadata: false,
|
||||
filesystem: None,
|
||||
@ -255,21 +284,15 @@ fn main_inner() -> Result<()> {
|
||||
}
|
||||
return publish_packages(&recipes, &config.repo_dir);
|
||||
}
|
||||
if command == CliCommand::PushTree {
|
||||
return handle_tree(&recipes, false, &config);
|
||||
if command.is_tree() {
|
||||
return handle_tree(&recipes, command.to_tree(), &config);
|
||||
}
|
||||
if command == CliCommand::CookTree {
|
||||
return handle_tree(&recipes, true, &config);
|
||||
if command.is_change_rule() {
|
||||
return handle_change_rule(&recipes, &config, &command);
|
||||
}
|
||||
if command == CliCommand::Push {
|
||||
return handle_push(&recipes, &config);
|
||||
}
|
||||
if matches!(
|
||||
command,
|
||||
CliCommand::ChangeRule | CliCommand::ChangeRuleLocal | CliCommand::CaptureRev
|
||||
) {
|
||||
return handle_change_rule(&recipes, &config, &command);
|
||||
}
|
||||
|
||||
let verbose = config.cook.verbose;
|
||||
for recipe in &recipes {
|
||||
@ -414,10 +437,6 @@ fn repo_inner(config: &CliConfig, command: &CliCommand, recipe: &CookRecipe) ->
|
||||
CliCommand::Unfetch | CliCommand::Clean | CliCommand::CleanTarget => {
|
||||
handle_clean(recipe, config, command)?
|
||||
}
|
||||
CliCommand::Find => {
|
||||
println!("{}", recipe.dir.display());
|
||||
false
|
||||
}
|
||||
_ => unreachable!(),
|
||||
})
|
||||
}
|
||||
@ -456,6 +475,7 @@ fn parse_args(args: Vec<String>) -> Result<(CliConfig, CliCommand, Vec<CookRecip
|
||||
"--sysroot" => config.sysroot_dir = PathBuf::from(value),
|
||||
"--category" => config.category = Some(PathBuf::from(value)),
|
||||
"--set-rule" => config.set_rule = Some(value.into()),
|
||||
"--display" => config.display = DisplayOptions::from_str(value)?,
|
||||
"--filesystem" => {
|
||||
config.filesystem = Some({
|
||||
let r = redox_installer::Config::from_file(&PathBuf::from(value));
|
||||
@ -476,12 +496,9 @@ fn parse_args(args: Vec<String>) -> Result<(CliConfig, CliCommand, Vec<CookRecip
|
||||
"--no-metadata" => config.no_metadata = true,
|
||||
"--rollback" => config.with_rollback = true,
|
||||
"--unset" => config.unset = true,
|
||||
"--all" => config.all = true,
|
||||
"--all-binaries" => {
|
||||
// TODO: an option to just set binaries_only?
|
||||
config.all = true;
|
||||
config.binaries_only = true;
|
||||
}
|
||||
"--all" => config.all = Some(AllOption::All),
|
||||
"--all-compiled" => config.all = Some(AllOption::AllCompiled),
|
||||
"--all-binaries" => config.all = Some(AllOption::AllBinaries),
|
||||
_ => bail_options_err!("Error: Unknown flag: {}", arg),
|
||||
}
|
||||
}
|
||||
@ -518,6 +535,9 @@ fn parse_args(args: Vec<String>) -> Result<(CliConfig, CliCommand, Vec<CookRecip
|
||||
config.set_rule = split.next().map(|s| s.to_string());
|
||||
cmd
|
||||
} else {
|
||||
if command == "find" {
|
||||
config.display = DisplayOptions::Path;
|
||||
}
|
||||
str::parse(&command)?
|
||||
};
|
||||
if command.is_informational() {
|
||||
@ -528,13 +548,13 @@ fn parse_args(args: Vec<String>) -> Result<(CliConfig, CliCommand, Vec<CookRecip
|
||||
let mut preloaded_recipes: BTreeMap<PackageName, CookRecipe> = BTreeMap::new();
|
||||
|
||||
if recipe_names.is_empty() {
|
||||
if config.all || config.category.is_some() {
|
||||
let all_recipes_path = match command.is_cleaning() || config.category.is_some() {
|
||||
true => {
|
||||
// some wip recipes have broken toml
|
||||
if config.all.is_some() || config.category.is_some() {
|
||||
let all_recipes_path = match (&config.all, config.category.is_some()) {
|
||||
(Some(AllOption::All), _) | (None, true) => {
|
||||
// everything in recipes
|
||||
staged_pkg::list()
|
||||
}
|
||||
false => {
|
||||
_ => {
|
||||
// get the list from repo/TARGET/repo.toml
|
||||
staged_pkg::list_repo(&config.repo_dir)?
|
||||
}
|
||||
@ -557,7 +577,11 @@ fn parse_args(args: Vec<String>) -> Result<(CliConfig, CliCommand, Vec<CookRecip
|
||||
|
||||
for path in all_recipes_path {
|
||||
// TODO: Allow selecting recipes from category as host?
|
||||
let recipe = CookRecipe::from_path(&path, !command.is_cleaning(), false)?;
|
||||
let recipe = match CookRecipe::from_path(&path, !command.is_cleaning(), false) {
|
||||
Ok(recipe) => recipe,
|
||||
Err(_) if matches!(config.all, Some(AllOption::All)) => continue,
|
||||
Err(e) => return Err(e.into()),
|
||||
};
|
||||
let recipe_name = recipe.name.clone();
|
||||
preloaded_recipes.insert(recipe_name.clone(), recipe);
|
||||
recipe_names.push(recipe_name);
|
||||
@ -665,9 +689,8 @@ fn parse_args(args: Vec<String>) -> Result<(CliConfig, CliCommand, Vec<CookRecip
|
||||
CookRecipe::get_package_deps_recursive(&binary_recipe_names, true)?;
|
||||
}
|
||||
|
||||
let mut recipes = if config.binaries_only {
|
||||
// This codepath is only true if combined with `config.all`,
|
||||
// otherwise it will be confusing for users because we don't warn
|
||||
let mut recipes = if matches!(config.all, Some(AllOption::AllBinaries)) {
|
||||
// Removes all source-compiled recipes
|
||||
Vec::new()
|
||||
} else if command.is_building() || command.is_pushing() {
|
||||
// Pushing do not need dev deps, so does binary recipes at building
|
||||
@ -883,7 +906,7 @@ fn handle_clean(recipe: &CookRecipe, config: &CliConfig, command: &CliCommand) -
|
||||
{
|
||||
remove_all(&tar)?;
|
||||
cached = false;
|
||||
} else if config.all {
|
||||
} else if config.all.is_some() {
|
||||
remove_all(&tar)?;
|
||||
cached = false;
|
||||
}
|
||||
@ -902,31 +925,25 @@ fn handle_push(recipes: &Vec<CookRecipe>, config: &CliConfig) -> Result<()> {
|
||||
}
|
||||
let recipe_map: HashMap<&PackageName, &CookRecipe> =
|
||||
recipes.iter().map(|r| (&r.name, r)).collect();
|
||||
let mut total_size: u64 = 0;
|
||||
let mut total_count: u64 = 0;
|
||||
let mut visited: HashSet<PackageName> = HashSet::new();
|
||||
let num_recipes = recipes.len();
|
||||
PUSH_CONFIG
|
||||
.set(config.clone())
|
||||
.unwrap_or_else(|_| panic!("PUSH_CONFIG is initialized"));
|
||||
let handle_push_inner = move |package_name: &PackageName,
|
||||
_prefix: &str,
|
||||
_is_last: bool,
|
||||
entry: &WalkTreeEntry|
|
||||
-> Result<bool> {
|
||||
let handle_push_inner = move |item: TreeItem| -> Result<bool> {
|
||||
let package_name = &item.recipe.name;
|
||||
if package_name.is_host() {
|
||||
return Ok(true); // TODO: skip altogether from recipes list
|
||||
}
|
||||
let r = match entry {
|
||||
WalkTreeEntry::Built(archive_path, _) => {
|
||||
let r = match item.entry {
|
||||
WalkTreeEntry::Built(_) => {
|
||||
let config = PUSH_CONFIG.get().unwrap();
|
||||
let install_path = &config.sysroot_dir;
|
||||
let archive_path = item.recipe.stage_paths().1;
|
||||
let mut state = if !config.no_metadata {
|
||||
Some(PackageState::from_sysroot(&install_path).map_err(Error::from)?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let r = package_handle_push(state.as_mut(), archive_path, &install_path);
|
||||
let r = package_handle_push(state.as_mut(), &archive_path, &install_path);
|
||||
if matches!(r, Ok(false)) && state.is_some() {
|
||||
state
|
||||
.unwrap()
|
||||
@ -963,16 +980,17 @@ fn handle_push(recipes: &Vec<CookRecipe>, config: &CliConfig) -> Result<()> {
|
||||
}
|
||||
}
|
||||
};
|
||||
for (i, recipe) in recipes.iter().enumerate() {
|
||||
|
||||
let mut data = TreeData::new();
|
||||
for recipe in recipes.iter() {
|
||||
tree::walk_tree_entry(
|
||||
&recipe.name,
|
||||
&recipe_map,
|
||||
None,
|
||||
"",
|
||||
i == num_recipes - 1,
|
||||
false,
|
||||
&mut visited,
|
||||
&mut total_size,
|
||||
&mut total_count,
|
||||
false, // don't care
|
||||
TreeOptions::Push,
|
||||
&mut data,
|
||||
handle_push_inner,
|
||||
)?;
|
||||
}
|
||||
@ -981,9 +999,9 @@ fn handle_push(recipes: &Vec<CookRecipe>, config: &CliConfig) -> Result<()> {
|
||||
println!("");
|
||||
println!(
|
||||
"Pushed {} of {} {}",
|
||||
tree::format_size(total_size),
|
||||
total_count,
|
||||
if total_count == 1 {
|
||||
tree::format_size(data.total_size),
|
||||
data.total_count,
|
||||
if data.total_count == 1 {
|
||||
"package"
|
||||
} else {
|
||||
"packages"
|
||||
@ -994,51 +1012,37 @@ fn handle_push(recipes: &Vec<CookRecipe>, config: &CliConfig) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_tree(recipes: &Vec<CookRecipe>, is_build_tree: bool, _config: &CliConfig) -> Result<()> {
|
||||
fn handle_tree(recipes: &Vec<CookRecipe>, cmd: TreeOptions, config: &CliConfig) -> Result<()> {
|
||||
let recipe_map: HashMap<&PackageName, &CookRecipe> =
|
||||
recipes.iter().map(|r| (&r.name, r)).collect();
|
||||
let mut total_size: u64 = 0;
|
||||
let mut total_count: u64 = 0;
|
||||
let mut visited: HashSet<PackageName> = HashSet::new();
|
||||
let roots: Vec<&CookRecipe> = recipes.iter().filter(|r| !r.is_deps).collect();
|
||||
let num_roots = roots.len();
|
||||
for (i, root) in roots.iter().enumerate() {
|
||||
tree::display_tree_entry(
|
||||
&root.name,
|
||||
&recipe_map,
|
||||
"",
|
||||
i == num_roots - 1,
|
||||
is_build_tree,
|
||||
&mut visited,
|
||||
&mut total_size,
|
||||
&mut total_count,
|
||||
)?;
|
||||
}
|
||||
let roots: Vec<PackageName> = recipes.iter().map(|s| s.name.clone()).collect();
|
||||
let data = tree::display_tree_entry(&roots[..], &recipe_map, cmd, config.display)?;
|
||||
|
||||
println!("");
|
||||
if is_build_tree {
|
||||
println!(
|
||||
"Build summary: {} need build, {} may rebuild, with total of {} {}",
|
||||
total_size,
|
||||
roots.len(),
|
||||
visited.len(),
|
||||
if visited.len() == 1 {
|
||||
"recipe"
|
||||
} else {
|
||||
"recipes"
|
||||
},
|
||||
);
|
||||
} else {
|
||||
println!(
|
||||
"Estimated image size: {} of {} {}",
|
||||
tree::format_size(total_size),
|
||||
visited.len(),
|
||||
if visited.len() == 1 {
|
||||
"package"
|
||||
} else {
|
||||
"packages"
|
||||
},
|
||||
);
|
||||
if matches!(config.display, DisplayOptions::Tree) {
|
||||
println!("");
|
||||
match cmd {
|
||||
TreeOptions::Repo => {}
|
||||
TreeOptions::Cook => println!(
|
||||
"Build summary: {} need build with total of {} {}",
|
||||
data.total_notbuilt,
|
||||
data.visited.len(),
|
||||
if data.visited.len() == 1 {
|
||||
"recipe"
|
||||
} else {
|
||||
"recipes"
|
||||
},
|
||||
),
|
||||
TreeOptions::Push => println!(
|
||||
"Estimated image size: {} of {} {}",
|
||||
tree::format_size(data.total_size),
|
||||
data.visited.len(),
|
||||
if data.visited.len() == 1 {
|
||||
"package"
|
||||
} else {
|
||||
"packages"
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
380
src/cook/tree.rs
380
src/cook/tree.rs
@ -1,126 +1,302 @@
|
||||
use pkg::{Package, PackageName};
|
||||
use std::{
|
||||
collections::{HashMap, HashSet},
|
||||
fmt::Write,
|
||||
path::PathBuf,
|
||||
str::FromStr,
|
||||
};
|
||||
|
||||
use crate::Result;
|
||||
use crate::cook::fs;
|
||||
use crate::recipe::CookRecipe;
|
||||
use crate::{Error, Result};
|
||||
|
||||
pub enum WalkTreeEntry<'a> {
|
||||
Built(&'a PathBuf, u64),
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum WalkTreeEntry {
|
||||
Built(u64),
|
||||
NotBuilt,
|
||||
Deduped,
|
||||
Missing,
|
||||
}
|
||||
|
||||
pub fn display_tree_entry(
|
||||
package_name: &PackageName,
|
||||
recipe_map: &HashMap<&PackageName, &CookRecipe>,
|
||||
prefix: &str,
|
||||
is_last: bool,
|
||||
is_build_tree: bool,
|
||||
visited: &mut HashSet<PackageName>,
|
||||
total_size: &mut u64,
|
||||
total_count: &mut u64,
|
||||
) -> Result<()> {
|
||||
walk_tree_entry(
|
||||
package_name,
|
||||
recipe_map,
|
||||
prefix,
|
||||
is_last,
|
||||
is_build_tree,
|
||||
visited,
|
||||
total_size,
|
||||
total_count,
|
||||
display_pkg_fn,
|
||||
)
|
||||
impl WalkTreeEntry {
|
||||
pub fn is_valid(&self) -> bool {
|
||||
return matches!(self, WalkTreeEntry::Built(_) | WalkTreeEntry::NotBuilt);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TreeData {
|
||||
/// list of deduped packages
|
||||
pub visited: HashSet<PackageName>,
|
||||
/// list of dependents, if requested
|
||||
pub dependents: HashMap<PackageName, HashSet<PackageName>>,
|
||||
/// total package size, only valid if tree_opt is push
|
||||
pub total_size: u64,
|
||||
/// count of packages that not exist in recipe_map
|
||||
pub total_missing: u64,
|
||||
/// count of packages that don't have package.toml
|
||||
pub total_notbuilt: u64,
|
||||
/// total packages
|
||||
pub total_count: u64,
|
||||
}
|
||||
|
||||
pub struct TreeItem<'a> {
|
||||
/// the recipe data
|
||||
pub recipe: &'a CookRecipe,
|
||||
/// prefix for tree
|
||||
pub prefix: &'a str,
|
||||
/// last item on tree?
|
||||
pub is_last: bool,
|
||||
/// recipe status
|
||||
pub entry: WalkTreeEntry,
|
||||
/// dependencies, if not deduped
|
||||
pub dependencies: Option<&'a HashSet<&'a PackageName>>,
|
||||
/// dependents, if supplied
|
||||
pub dependents: Option<&'a HashSet<PackageName>>,
|
||||
}
|
||||
|
||||
impl TreeData {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
visited: HashSet::new(),
|
||||
dependents: HashMap::new(),
|
||||
total_size: 0,
|
||||
total_count: 0,
|
||||
total_missing: 0,
|
||||
total_notbuilt: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum DisplayOptions {
|
||||
Name,
|
||||
Path,
|
||||
Csv,
|
||||
Tree,
|
||||
}
|
||||
|
||||
impl Default for DisplayOptions {
|
||||
fn default() -> Self {
|
||||
Self::Tree
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for DisplayOptions {
|
||||
type Err = Error;
|
||||
|
||||
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
|
||||
match s {
|
||||
"name" => Ok(DisplayOptions::Name),
|
||||
"path" => Ok(DisplayOptions::Path),
|
||||
"csv" => Ok(DisplayOptions::Csv),
|
||||
"tree" => Ok(DisplayOptions::Tree),
|
||||
_ => Err(Error::Options(format!("unknown display: {s}"))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum TreeOptions {
|
||||
Repo,
|
||||
Cook,
|
||||
Push,
|
||||
}
|
||||
|
||||
impl FromStr for TreeOptions {
|
||||
type Err = Error;
|
||||
|
||||
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
|
||||
match s {
|
||||
"repo" => Ok(TreeOptions::Repo),
|
||||
"cook" => Ok(TreeOptions::Cook),
|
||||
"push" => Ok(TreeOptions::Push),
|
||||
_ => Err(Error::Options(format!("unknown tree: {s}"))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn display_tree_entry(
|
||||
package_roots: &[PackageName],
|
||||
recipe_map: &HashMap<&PackageName, &CookRecipe>,
|
||||
tree_opt: TreeOptions,
|
||||
display_opt: DisplayOptions,
|
||||
) -> Result<TreeData> {
|
||||
let mut data = TreeData::new();
|
||||
let num_roots = package_roots.len() - 1;
|
||||
let dependents = if matches!(display_opt, DisplayOptions::Csv) {
|
||||
Some(build_dependents(recipe_map, tree_opt))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
for (i, name) in package_roots.iter().enumerate() {
|
||||
walk_tree_entry(
|
||||
name,
|
||||
recipe_map,
|
||||
dependents.as_ref(),
|
||||
"",
|
||||
i == num_roots,
|
||||
tree_opt,
|
||||
&mut data,
|
||||
match display_opt {
|
||||
DisplayOptions::Name => display_name_fn,
|
||||
DisplayOptions::Path => display_path_fn,
|
||||
DisplayOptions::Csv => display_csv_fn,
|
||||
DisplayOptions::Tree => display_tree_fn,
|
||||
},
|
||||
)?;
|
||||
}
|
||||
Ok(data)
|
||||
}
|
||||
|
||||
pub fn build_dependents(
|
||||
recipe_map: &HashMap<&PackageName, &CookRecipe>,
|
||||
tree_opt: TreeOptions,
|
||||
) -> HashMap<PackageName, HashSet<PackageName>> {
|
||||
let mut dependents_map: HashMap<PackageName, HashSet<PackageName>> = HashMap::new();
|
||||
for cook_recipe in recipe_map.values() {
|
||||
let mut all_deps_set: HashSet<&PackageName> = HashSet::new();
|
||||
let pkg_meta: Package;
|
||||
match tree_opt {
|
||||
TreeOptions::Repo => {
|
||||
// no dependency recursion
|
||||
}
|
||||
TreeOptions::Cook => {
|
||||
// recursion from recipe.toml
|
||||
all_deps_set.extend(cook_recipe.recipe.build.dependencies.iter());
|
||||
all_deps_set.extend(cook_recipe.recipe.build.dev_dependencies.iter());
|
||||
all_deps_set.extend(cook_recipe.recipe.package.dependencies.iter());
|
||||
}
|
||||
TreeOptions::Push => {
|
||||
// recursion from package.toml
|
||||
if let Ok(pkg) = Package::from_file(&cook_recipe.stage_paths().2) {
|
||||
pkg_meta = pkg;
|
||||
all_deps_set.extend(pkg_meta.depends.iter());
|
||||
}
|
||||
}
|
||||
}
|
||||
for dep in all_deps_set {
|
||||
dependents_map
|
||||
.entry(dep.clone())
|
||||
.or_default()
|
||||
.insert(cook_recipe.name.clone());
|
||||
}
|
||||
}
|
||||
dependents_map
|
||||
}
|
||||
|
||||
/// Does tree recursion to `op` call.
|
||||
/// Tree recursion is different than recursion in [`CookRecipe`],
|
||||
/// this version does call `op` from root then to their deps.
|
||||
/// dependents can be precalculated with [`build_dependents`].
|
||||
pub fn walk_tree_entry(
|
||||
package_name: &PackageName,
|
||||
recipe_map: &HashMap<&PackageName, &CookRecipe>,
|
||||
dependents_map: Option<&HashMap<PackageName, HashSet<PackageName>>>,
|
||||
prefix: &str,
|
||||
is_last: bool,
|
||||
is_build_tree: bool,
|
||||
visited: &mut HashSet<PackageName>,
|
||||
total_size: &mut u64,
|
||||
total_count: &mut u64,
|
||||
op: fn(&PackageName, &str, bool, &WalkTreeEntry) -> Result<bool>,
|
||||
tree_opt: TreeOptions,
|
||||
data: &mut TreeData,
|
||||
op: fn(TreeItem) -> Result<bool>,
|
||||
) -> Result<()> {
|
||||
let cook_recipe = match recipe_map.get(package_name) {
|
||||
Some(r) => r,
|
||||
None => {
|
||||
// Data not provided, will not be processed by the build system
|
||||
op(package_name, prefix, is_last, &WalkTreeEntry::Missing)?;
|
||||
op(TreeItem {
|
||||
recipe: &CookRecipe::dummy(package_name),
|
||||
prefix,
|
||||
is_last,
|
||||
entry: WalkTreeEntry::Missing,
|
||||
dependencies: None,
|
||||
dependents: None,
|
||||
})?;
|
||||
data.total_missing += 1;
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
|
||||
let (_, pkg_path, pkg_toml) = cook_recipe.stage_paths();
|
||||
|
||||
let deduped = visited.contains(package_name);
|
||||
let entry = if deduped {
|
||||
WalkTreeEntry::Deduped
|
||||
let deduped = data.visited.contains(package_name);
|
||||
let pkg_meta: Package;
|
||||
|
||||
let (entry, dependencies) = if deduped {
|
||||
(WalkTreeEntry::Deduped, None)
|
||||
} else {
|
||||
match (std::fs::metadata(&pkg_path), pkg_toml.is_file()) {
|
||||
(Ok(meta), _) => WalkTreeEntry::Built(&pkg_path, meta.len()),
|
||||
(Err(_), true) => WalkTreeEntry::Built(&pkg_path, 0),
|
||||
let entry = match (std::fs::metadata(&pkg_path), pkg_toml.is_file()) {
|
||||
(Ok(meta), _) => WalkTreeEntry::Built(meta.len()),
|
||||
(Err(_), true) => WalkTreeEntry::Built(0),
|
||||
(Err(_), false) => WalkTreeEntry::NotBuilt,
|
||||
};
|
||||
let mut all_deps_set: HashSet<&PackageName> = HashSet::new();
|
||||
match tree_opt {
|
||||
TreeOptions::Repo => {
|
||||
// no dependency recursion
|
||||
}
|
||||
TreeOptions::Cook => {
|
||||
// recursion from recipe.toml
|
||||
all_deps_set.extend(cook_recipe.recipe.build.dependencies.iter());
|
||||
all_deps_set.extend(cook_recipe.recipe.build.dev_dependencies.iter());
|
||||
all_deps_set.extend(cook_recipe.recipe.package.dependencies.iter());
|
||||
}
|
||||
TreeOptions::Push => {
|
||||
// recursion from package.toml
|
||||
if let Ok(pkg) = Package::from_file(&pkg_toml) {
|
||||
pkg_meta = pkg;
|
||||
all_deps_set.extend(pkg_meta.depends.iter());
|
||||
}
|
||||
}
|
||||
}
|
||||
(entry, Some(all_deps_set))
|
||||
};
|
||||
|
||||
let cached = op(package_name, prefix, is_last, &entry)?;
|
||||
let dependents = dependents_map.and_then(|s| s.get(&cook_recipe.name));
|
||||
|
||||
let cached = op(TreeItem {
|
||||
recipe: cook_recipe,
|
||||
prefix,
|
||||
is_last,
|
||||
entry,
|
||||
dependencies: dependencies.as_ref(),
|
||||
dependents,
|
||||
})?;
|
||||
|
||||
if deduped || cached {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
visited.insert(package_name.clone());
|
||||
data.visited.insert(package_name.clone());
|
||||
if !cached {
|
||||
if is_build_tree {
|
||||
if matches!(entry, WalkTreeEntry::NotBuilt) {
|
||||
*total_size += 1;
|
||||
}
|
||||
} else {
|
||||
if let WalkTreeEntry::Built(_p, pkg_size) = &entry {
|
||||
*total_size += pkg_size;
|
||||
if matches!(tree_opt, TreeOptions::Push) {
|
||||
if let WalkTreeEntry::Built(pkg_size) = &entry {
|
||||
data.total_size += pkg_size;
|
||||
}
|
||||
}
|
||||
*total_count += 1;
|
||||
}
|
||||
let pkg_meta: Package;
|
||||
|
||||
let mut all_deps_set: HashSet<&PackageName> = HashSet::new();
|
||||
if is_build_tree {
|
||||
all_deps_set.extend(cook_recipe.recipe.build.dependencies.iter());
|
||||
all_deps_set.extend(cook_recipe.recipe.package.dependencies.iter());
|
||||
} else {
|
||||
if let Ok(pkg_toml_str) = fs::read_to_string(&pkg_toml) {
|
||||
// more accurate with auto deps
|
||||
pkg_meta = Package::from_toml(&pkg_toml_str)?;
|
||||
all_deps_set.extend(pkg_meta.depends.iter());
|
||||
if matches!(entry, WalkTreeEntry::NotBuilt) {
|
||||
data.total_notbuilt += 1;
|
||||
}
|
||||
data.total_count += 1;
|
||||
}
|
||||
|
||||
if all_deps_set.is_empty() {
|
||||
let dependencies = dependencies.unwrap();
|
||||
if dependencies.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let sorted_deps: Vec<&PackageName> = all_deps_set.into_iter().collect();
|
||||
let deps_count = sorted_deps.len();
|
||||
let deps_count = dependencies.len();
|
||||
let child_prefix = if is_last { " " } else { "│ " };
|
||||
for (i, dep_name) in sorted_deps.iter().enumerate() {
|
||||
for (i, dep_name) in dependencies.iter().enumerate() {
|
||||
data.dependents
|
||||
.entry((*dep_name).clone())
|
||||
.or_insert_with(|| HashSet::new())
|
||||
.insert(package_name.clone());
|
||||
walk_tree_entry(
|
||||
dep_name,
|
||||
recipe_map,
|
||||
dependents_map,
|
||||
&format!("{}{}", prefix, child_prefix),
|
||||
i == deps_count - 1,
|
||||
is_build_tree,
|
||||
visited,
|
||||
total_size,
|
||||
total_count,
|
||||
tree_opt,
|
||||
data,
|
||||
op,
|
||||
)?;
|
||||
}
|
||||
@ -128,24 +304,68 @@ pub fn walk_tree_entry(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn display_pkg_fn(
|
||||
package_name: &PackageName,
|
||||
prefix: &str,
|
||||
is_last: bool,
|
||||
entry: &WalkTreeEntry,
|
||||
) -> Result<bool> {
|
||||
let size_str = match entry {
|
||||
WalkTreeEntry::Built(_path_buf, size) => format!("[{}]", format_size(*size)),
|
||||
fn display_tree_fn(item: TreeItem) -> Result<bool> {
|
||||
let size_str = match item.entry {
|
||||
WalkTreeEntry::Built(size) => format!("[{}]", format_size(size)),
|
||||
WalkTreeEntry::NotBuilt => "(not built)".to_string(),
|
||||
WalkTreeEntry::Deduped => "".to_string(),
|
||||
WalkTreeEntry::Missing => "(omitted)".to_string(),
|
||||
};
|
||||
let is_last = item.is_last;
|
||||
let line_prefix = if is_last { "└── " } else { "├── " };
|
||||
println!("{}{}{} {}", prefix, line_prefix, package_name, size_str);
|
||||
println!(
|
||||
"{}{}{} {}",
|
||||
item.prefix, line_prefix, item.recipe.name, size_str
|
||||
);
|
||||
// TODO: check dirty build by checking source ident
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
fn display_name_fn(item: TreeItem) -> Result<bool> {
|
||||
if item.entry.is_valid() {
|
||||
println!("{}", item.recipe.name.as_str());
|
||||
}
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
fn display_path_fn(item: TreeItem) -> Result<bool> {
|
||||
if item.entry.is_valid() {
|
||||
println!("{}", item.recipe.dir.display());
|
||||
}
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
fn display_csv_fn(item: TreeItem) -> Result<bool> {
|
||||
// name, path, status, dependencies, dependents
|
||||
if item.entry.is_valid() {
|
||||
let mut deps = String::new();
|
||||
let mut depz = String::new();
|
||||
for dep in item.dependencies.unwrap() {
|
||||
if !deps.is_empty() {
|
||||
let _ = deps.write_char(';');
|
||||
}
|
||||
let _ = deps.write_str(dep.as_str());
|
||||
}
|
||||
if let Some(dependents) = item.dependents {
|
||||
for dep in dependents {
|
||||
if !depz.is_empty() {
|
||||
let _ = depz.write_char(';');
|
||||
}
|
||||
let _ = depz.write_str(dep.as_str());
|
||||
}
|
||||
}
|
||||
println!(
|
||||
"{},{},{:?},{},{}",
|
||||
item.recipe.name.as_str(),
|
||||
item.recipe.dir.display(),
|
||||
item.entry,
|
||||
deps,
|
||||
depz,
|
||||
);
|
||||
}
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
pub fn walk_file_tree(
|
||||
dir: &PathBuf,
|
||||
prefix: &str,
|
||||
@ -204,11 +424,5 @@ pub fn walk_file_tree(
|
||||
}
|
||||
|
||||
pub fn format_size(bytes: u64) -> String {
|
||||
if bytes == 0 {
|
||||
return "0 B".to_string();
|
||||
}
|
||||
const UNITS: [&str; 5] = ["B", "KiB", "MiB", "GiB", "TiB"];
|
||||
let i = (bytes as f64).log(1024.0).floor() as usize;
|
||||
let size = bytes as f64 / 1024.0_f64.powi(i as i32);
|
||||
format!("{:.2} {}", size, UNITS[i])
|
||||
redox_installer::format_bytes(bytes)
|
||||
}
|
||||
|
||||
@ -276,6 +276,18 @@ impl CookRecipe {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn dummy(name: &PackageName) -> Self {
|
||||
Self {
|
||||
dir: PathBuf::new(),
|
||||
is_deps: false,
|
||||
name: name.clone(),
|
||||
recipe: Recipe::default(),
|
||||
target: redoxer::target(),
|
||||
pinned: false,
|
||||
rule: "".into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_name(name: PackageName) -> Result<Self, PackageError> {
|
||||
let dir = staged_pkg::find(name.name())
|
||||
.ok_or_else(|| PackageError::PackageNotFound(name.clone()))?;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user