factor: deploy script reports its path (fixes 0.101 compat) + setting 0.101 as the default (#527945)

This commit is contained in:
Audrey Dutcher
2026-06-12 20:56:41 +00:00
committed by GitHub
8 changed files with 135 additions and 24 deletions
@@ -31,12 +31,24 @@ in
extraPaths ? [ ],
# Extra vocabularies needed by this application
extraVocabs ? [ ],
deployScriptText ? ''
deployScriptText ? /* factor */ ''
USING: command-line io io.backend io.pathnames kernel namespaces sequences
tools.deploy tools.deploy.config tools.deploy.backend vocabs.loader ;
tools.deploy tools.deploy.config tools.deploy.backend vocabs.loader
io.directories.unix ;
IN: deploy-me
! The Nix sandboxs seccomp filter blocks chmod(2). Factors
! copy-file calls set-file-permissions which chmods the target
! to the sources mode, 0o444. The blocked syscall returns
! EACCES, crashing the deploys. The method override skips the
! set-file-permissions call (Nix will manage its output
! permissions).
!
! Surfaced with Factor 0.101 which added icon PNG resources to
! the definitions.icons vocab to copy-vocab-resources.
M: unix copy-file call-next-method ;
: load-and-deploy ( path/vocab -- )
normalize-path [
parent-directory add-vocab-root
@@ -44,17 +56,22 @@ in
file-name dup reload deploy
] bi ;
! Factor 0.101 added a .out extension on not macOS. Rather than
! having shell scripts dealing path name changes per-OS &
! per-version, the deploy script prints its deploy path to a file.
: deploy-vocab ( path/vocab path/target -- )
normalize-path deploy-directory set
f open-directory-after-deploy? set
load-and-deploy ;
dup file-name
[ load-and-deploy ] dip
deploy-path "deploy-path.txt" utf8 set-file-contents ;
: deploy-me ( -- )
command-line get dup length 2 = [
first2 deploy-vocab
] [
drop
"usage: deploy-me <PATH-TO-VOCAB> <TARGET-DIR>" print
"Usage: deploy-me <PATH-TO-VOCAB> <TARGET-DIR>" print
nl
] if ;
@@ -91,44 +108,47 @@ in
buildInputs = (lib.optional enableUI gdk-pixbuf) ++ attrs.buildInputs or [ ];
buildPhase =
attrs.buildPhase or ''
attrs.buildPhase or /* bash */ ''
runHook preBuild
vocabBaseName=$(basename "$vocabName")
mkdir -p "$out/lib/factor" "$TMPDIR/.cache"
export XDG_CACHE_HOME="$TMPDIR/.cache"
# Deploy script writes the deploy path to to $PWD/deploy-path.txt
factor "${deployScript}" "./$vocabName" "$out/lib/factor"
cp "$TMPDIR/factor-temp"/*.image "$out/lib/factor/$vocabBaseName"
deploy_path=$(cat "$PWD/deploy-path.txt")
if [ ! -x "$deploy_path" ]; then
echo "Not a valid deploy path for Factor: $deploy_path"
exit 1
fi
cp "$TMPDIR/factor-temp"/*.image "$(dirname "$deploy_path")/$(basename "$deploy_path").image"
runHook postBuild
'';
__structuredAttrs = true;
installPhase =
attrs.installPhase or (
''
runHook preInstall
''
+ (lib.optionalString finalAttrs.enableUI ''
attrs.installPhase or /* bash */ ''
runHook preInstall
${lib.optionalString finalAttrs.enableUI /* bash */ ''
# Set Gdk pixbuf loaders file to the one from the build dependencies here
unset GDK_PIXBUF_MODULE_FILE
# Defined in gdk-pixbuf setup hook
findGdkPixbufLoaders "${librsvg}"
appendToVar makeWrapperArgs --set GDK_PIXBUF_MODULE_FILE "$GDK_PIXBUF_MODULE_FILE"
appendToVar makeWrapperArgs --prefix LD_LIBRARY_PATH : /run/opengl-driver/lib
'')
+ (lib.optionalString (wrapped-factor.runtimeLibs != [ ])) ''
''}
${lib.optionalString (wrapped-factor.runtimeLibs != [ ]) /* bash */ ''
appendToVar makeWrapperArgs --prefix LD_LIBRARY_PATH : "${lib.makeLibraryPath wrapped-factor.runtimeLibs}"
''
+ ''
mkdir -p "$out/bin"
makeWrapper "$out/lib/factor/$vocabBaseName/$vocabBaseName" \
"$out/bin/$binName" \
--prefix PATH : "${lib.makeBinPath runtimePaths}" \
"''${makeWrapperArgs[@]}"
runHook postInstall
''
);
''}
mkdir -p "$out/bin"
makeWrapper "$deploy_path" \
"$out/bin/$binName" \
--prefix PATH : "${lib.makeBinPath runtimePaths}" \
"''${makeWrapperArgs[@]}"
runHook postInstall
'';
passthru = {
vocab = finalAttrs.src;
@@ -0,0 +1,56 @@
# Builds hello-world Factor application using buildFactorApplication & verifies
# source-to-binary that the resulting app prints "Hello, $NAME" depending on
# `--name` flag.
{
lib,
runCommandLocal,
buildFactorApplication,
buildFactorVocab,
}:
let
fs = lib.fileset;
factorFilter =
file:
lib.lists.any file.hasExt [
"factor"
"txt"
];
version = "0-test";
vocab = buildFactorVocab {
inherit version;
pname = "hello";
src = fs.toSource {
root = ./extra;
fileset = fs.difference (fs.fileFilter factorFilter ./extra/hello) ./extra/hello/cli;
};
vocabName = "hello";
};
app = buildFactorApplication {
inherit version;
pname = "hello-cli";
src = fs.toSource {
root = ./extra;
fileset = fs.fileFilter factorFilter ./extra/hello/cli;
};
vocabName = "hello.cli";
binName = "hello";
extraVocabs = [ vocab ];
};
in
runCommandLocal "assert-factor-hello-world"
{
env.expected = "Hello, Nixpkgs";
}
''
output="$(${lib.getExe app} --name "Nixpkgs")"
if [ "$output" != "$expected" ]; then
echo "FAIL: expected $expected; got $output" >&2
exit 1
fi
touch "$out"
''
@@ -0,0 +1,13 @@
! SPDX-License-Identifier: 0BSD
USING: command-line combinators io kernel namespaces sequences hello ;
IN: hello.cli
: main ( -- )
command-line get {
{ [ dup empty? ] [ drop "world" ] }
{ [ dup first "--name" = not ] [ drop "world" ] }
[ second ]
} cond greet ;
MAIN: main
@@ -0,0 +1,7 @@
! SPDX-License-Identifier: 0BSD
USING: io namespaces sequences ;
IN: hello
: greet ( name -- )
"Hello, " prepend print ;
@@ -2,6 +2,9 @@
lib,
stdenv,
makeWrapper,
runCommandLocal,
buildFactorApplication,
buildFactorVocab,
buildEnv,
copyDesktopItems,
makeDesktopItem,
@@ -220,6 +223,16 @@ stdenv.mkDerivation (finalAttrs: {
extraVocabs
vocabTree
;
tests = {
hello-world = import ./test/hello-world {
inherit
lib
runCommandLocal
buildFactorApplication
buildFactorVocab
;
};
};
};
meta = factor-unwrapped.meta // {
+1 -1
View File
@@ -5851,7 +5851,7 @@ with pkgs;
stdenv = clangStdenv;
};
};
factorPackages = factorPackages-0_100;
factorPackages = factorPackages-0_101;
factor-lang-0_99 = factorPackages-0_99.factor-lang;
factor-lang-0_100 = factorPackages-0_100.factor-lang;