From 3678d107b74d4cd2f367cf33b29b0980a3aaf066 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=B7=F0=90=91=91=F0=90=91=B4=F0=90=91=95=F0=90=91=91?= =?UTF-8?q?=F0=90=91=A9=F0=90=91=A4?= Date: Thu, 21 May 2026 21:50:01 +0700 Subject: [PATCH 1/7] factor: add hello-world test --- .../factor-lang/test/hello-world/default.nix | 56 +++++++++++++++++++ .../test/hello-world/extra/hello/author.txt | 1 + .../hello-world/extra/hello/cli/author.txt | 1 + .../hello-world/extra/hello/cli/cli.factor | 13 +++++ .../test/hello-world/extra/hello/hello.factor | 7 +++ .../compilers/factor-lang/wrapper.nix | 13 +++++ 6 files changed, 91 insertions(+) create mode 100644 pkgs/development/compilers/factor-lang/test/hello-world/default.nix create mode 100644 pkgs/development/compilers/factor-lang/test/hello-world/extra/hello/author.txt create mode 100644 pkgs/development/compilers/factor-lang/test/hello-world/extra/hello/cli/author.txt create mode 100644 pkgs/development/compilers/factor-lang/test/hello-world/extra/hello/cli/cli.factor create mode 100644 pkgs/development/compilers/factor-lang/test/hello-world/extra/hello/hello.factor diff --git a/pkgs/development/compilers/factor-lang/test/hello-world/default.nix b/pkgs/development/compilers/factor-lang/test/hello-world/default.nix new file mode 100644 index 000000000000..a84260381291 --- /dev/null +++ b/pkgs/development/compilers/factor-lang/test/hello-world/default.nix @@ -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" + '' diff --git a/pkgs/development/compilers/factor-lang/test/hello-world/extra/hello/author.txt b/pkgs/development/compilers/factor-lang/test/hello-world/extra/hello/author.txt new file mode 100644 index 000000000000..95fc5a77b470 --- /dev/null +++ b/pkgs/development/compilers/factor-lang/test/hello-world/extra/hello/author.txt @@ -0,0 +1 @@ +toastal diff --git a/pkgs/development/compilers/factor-lang/test/hello-world/extra/hello/cli/author.txt b/pkgs/development/compilers/factor-lang/test/hello-world/extra/hello/cli/author.txt new file mode 100644 index 000000000000..95fc5a77b470 --- /dev/null +++ b/pkgs/development/compilers/factor-lang/test/hello-world/extra/hello/cli/author.txt @@ -0,0 +1 @@ +toastal diff --git a/pkgs/development/compilers/factor-lang/test/hello-world/extra/hello/cli/cli.factor b/pkgs/development/compilers/factor-lang/test/hello-world/extra/hello/cli/cli.factor new file mode 100644 index 000000000000..027ddd7bc9f0 --- /dev/null +++ b/pkgs/development/compilers/factor-lang/test/hello-world/extra/hello/cli/cli.factor @@ -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 diff --git a/pkgs/development/compilers/factor-lang/test/hello-world/extra/hello/hello.factor b/pkgs/development/compilers/factor-lang/test/hello-world/extra/hello/hello.factor new file mode 100644 index 000000000000..bf256300c641 --- /dev/null +++ b/pkgs/development/compilers/factor-lang/test/hello-world/extra/hello/hello.factor @@ -0,0 +1,7 @@ +! SPDX-License-Identifier: 0BSD +USING: io namespaces sequences ; + +IN: hello + +: greet ( name -- ) + "Hello, " prepend print ; diff --git a/pkgs/development/compilers/factor-lang/wrapper.nix b/pkgs/development/compilers/factor-lang/wrapper.nix index 5f8e4ff37020..80d3def2df04 100644 --- a/pkgs/development/compilers/factor-lang/wrapper.nix +++ b/pkgs/development/compilers/factor-lang/wrapper.nix @@ -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 // { From 59d0bc1cf90c3ba767e3c4b533e0f7cb3c046f99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=B7=F0=90=91=91=F0=90=91=B4=F0=90=91=95=F0=90=91=91?= =?UTF-8?q?=F0=90=91=A9=F0=90=91=A4?= Date: Thu, 4 Jun 2026 11:08:42 +0700 Subject: [PATCH 2/7] =?UTF-8?q?factor:=20capitalize=20=E2=80=9CUsage?= =?UTF-8?q?=E2=80=9D=20as=20is=20customary?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../development/compilers/factor-lang/mk-factor-application.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/development/compilers/factor-lang/mk-factor-application.nix b/pkgs/development/compilers/factor-lang/mk-factor-application.nix index 2b694d68ecdd..fd05e241e9e5 100644 --- a/pkgs/development/compilers/factor-lang/mk-factor-application.nix +++ b/pkgs/development/compilers/factor-lang/mk-factor-application.nix @@ -54,7 +54,7 @@ in first2 deploy-vocab ] [ drop - "usage: deploy-me " print + "Usage: deploy-me " print nl ] if ; From 58eddaf709739b3a6d95b835350e7801eb5399f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=B7=F0=90=91=91=F0=90=91=B4=F0=90=91=95=F0=90=91=91?= =?UTF-8?q?=F0=90=91=A9=F0=90=91=A4?= Date: Thu, 4 Jun 2026 11:34:19 +0700 Subject: [PATCH 3/7] factor: add language string annotations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit tree-sitter can highlight these (& more depending on editor setup), & for the rest of users, it’s still an annotation that helps keep track of what language we are working in. --- .../factor-lang/mk-factor-application.nix | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pkgs/development/compilers/factor-lang/mk-factor-application.nix b/pkgs/development/compilers/factor-lang/mk-factor-application.nix index fd05e241e9e5..ff3b457a3623 100644 --- a/pkgs/development/compilers/factor-lang/mk-factor-application.nix +++ b/pkgs/development/compilers/factor-lang/mk-factor-application.nix @@ -31,7 +31,7 @@ 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 ; @@ -91,7 +91,7 @@ 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" @@ -105,11 +105,11 @@ in __structuredAttrs = true; installPhase = - attrs.installPhase or ( - '' + attrs.installPhase or + /* bash */ '' runHook preInstall '' - + (lib.optionalString finalAttrs.enableUI '' + + (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 @@ -117,10 +117,10 @@ in 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}" '' - + '' + + /* bash */ '' mkdir -p "$out/bin" makeWrapper "$out/lib/factor/$vocabBaseName/$vocabBaseName" \ "$out/bin/$binName" \ From 5d13d05d5e28f38d6798d6524f74990d259d3a56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=B7=F0=90=91=91=F0=90=91=B4=F0=90=91=95=F0=90=91=91?= =?UTF-8?q?=F0=90=91=A9=F0=90=91=A4?= Date: Thu, 4 Jun 2026 11:37:52 +0700 Subject: [PATCH 4/7] factor: use indent strings for install phase --- .../factor-lang/mk-factor-application.nix | 30 ++++++++----------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/pkgs/development/compilers/factor-lang/mk-factor-application.nix b/pkgs/development/compilers/factor-lang/mk-factor-application.nix index ff3b457a3623..67fb03d130c6 100644 --- a/pkgs/development/compilers/factor-lang/mk-factor-application.nix +++ b/pkgs/development/compilers/factor-lang/mk-factor-application.nix @@ -105,30 +105,26 @@ in __structuredAttrs = true; installPhase = - attrs.installPhase or - /* bash */ '' - runHook preInstall - '' - + (lib.optionalString finalAttrs.enableUI /* bash */ '' + 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 != [ ])) /* bash */ '' + ''} + ${lib.optionalString (wrapped-factor.runtimeLibs != [ ]) /* bash */ '' appendToVar makeWrapperArgs --prefix LD_LIBRARY_PATH : "${lib.makeLibraryPath wrapped-factor.runtimeLibs}" - '' - + /* bash */ '' - 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 "$out/lib/factor/$vocabBaseName/$vocabBaseName" \ + "$out/bin/$binName" \ + --prefix PATH : "${lib.makeBinPath runtimePaths}" \ + "''${makeWrapperArgs[@]}" + runHook postInstall + ''; passthru = { vocab = finalAttrs.src; From 7aaa9694b89a3027bb716fa2f6e339d08aadc231 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=B7=F0=90=91=91=F0=90=91=B4=F0=90=91=95=F0=90=91=91?= =?UTF-8?q?=F0=90=91=A9=F0=90=91=A4?= Date: Thu, 4 Jun 2026 18:44:22 +0700 Subject: [PATCH 5/7] factor: deploy script prints its path handling version differences In 0.101 & on non-macOS builds, Factor added a .out extension to deployments. The current Nix derivation is built with path assumptions in mind. Rather than running switch-cases on versions+OS or relying on globbing in the shell scripts, the deploy script has been modified to print its resolved deploy path to a file so that the build can continue knowing exactly where the files are / should go. This handles both with & without .out extension as the tests pass on 0.99, 0.100, & 0.101. --- .../factor-lang/mk-factor-application.nix | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/pkgs/development/compilers/factor-lang/mk-factor-application.nix b/pkgs/development/compilers/factor-lang/mk-factor-application.nix index 67fb03d130c6..0537f74ddda8 100644 --- a/pkgs/development/compilers/factor-lang/mk-factor-application.nix +++ b/pkgs/development/compilers/factor-lang/mk-factor-application.nix @@ -44,10 +44,15 @@ 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 = [ @@ -97,8 +102,15 @@ in 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 ''; @@ -119,7 +131,7 @@ in appendToVar makeWrapperArgs --prefix LD_LIBRARY_PATH : "${lib.makeLibraryPath wrapped-factor.runtimeLibs}" ''} mkdir -p "$out/bin" - makeWrapper "$out/lib/factor/$vocabBaseName/$vocabBaseName" \ + makeWrapper "$deploy_path" \ "$out/bin/$binName" \ --prefix PATH : "${lib.makeBinPath runtimePaths}" \ "''${makeWrapperArgs[@]}" From dde6eefd58cca2ff6c5e1237863cc7a3ca033657 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=B7=F0=90=91=91=F0=90=91=B4=F0=90=91=95=F0=90=91=91?= =?UTF-8?q?=F0=90=91=A9=F0=90=91=A4?= Date: Fri, 5 Jun 2026 18:17:51 +0700 Subject: [PATCH 6/7] factor: override deployment copy-file to skip setting file permissions Assisted-by: DeepSeek V4 Flash --- .../factor-lang/mk-factor-application.nix | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/pkgs/development/compilers/factor-lang/mk-factor-application.nix b/pkgs/development/compilers/factor-lang/mk-factor-application.nix index 0537f74ddda8..bbd039ba3615 100644 --- a/pkgs/development/compilers/factor-lang/mk-factor-application.nix +++ b/pkgs/development/compilers/factor-lang/mk-factor-application.nix @@ -33,10 +33,22 @@ in extraVocabs ? [ ], 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 sandbox’s seccomp filter blocks chmod(2). Factor’s + ! copy-file calls set-file-permissions which chmod’s the target + ! to the source’s 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 From 401cab2cb7ff3014bccde58ef86de8d3f9a3f73b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=B7=F0=90=91=91=F0=90=91=B4=F0=90=91=95=F0=90=91=91?= =?UTF-8?q?=F0=90=91=A9=F0=90=91=A4?= Date: Wed, 20 May 2026 15:12:40 +0700 Subject: [PATCH 7/7] =?UTF-8?q?factorPackages:=200.100=20=E2=86=92=200.101?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I think this was an oversight. If the default factor-lang is 0.101 the packages should match. --- pkgs/top-level/all-packages.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 8944205f1b1f..6af7a2024028 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -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;