log4brains: init at 1.1.0
Patches the generation process, as upstream requires writeable node_modules at runtime. Co-authored-by: Ross Smyth <18294397+RossSmyth@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,40 @@
|
|||||||
|
From 6a8571098024d1eb69efaae1f1622b3a91417b5f Mon Sep 17 00:00:00 2001
|
||||||
|
From: tropf <tropf@users.noreply.github.com>
|
||||||
|
Date: Tue, 26 Aug 2025 15:08:07 +0200
|
||||||
|
Subject: [PATCH 1/2] replace version check using package.json
|
||||||
|
|
||||||
|
In the distributed (nix) version, package.json is not available under
|
||||||
|
the expected path. As nix can inject the version during build time, this
|
||||||
|
patch removes the reference to package.json, and injects a marker for
|
||||||
|
the version to be replaced during the patchPhase.
|
||||||
|
---
|
||||||
|
packages/web/nextjs/next.config.js | 6 +-----
|
||||||
|
1 file changed, 1 insertion(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/packages/web/nextjs/next.config.js b/packages/web/nextjs/next.config.js
|
||||||
|
index 9b2b364..db9d680 100644
|
||||||
|
--- a/packages/web/nextjs/next.config.js
|
||||||
|
+++ b/packages/web/nextjs/next.config.js
|
||||||
|
@@ -5,10 +5,6 @@ const withBundleAnalyzer = require("@next/bundle-analyzer")({
|
||||||
|
enabled: process.env.ANALYZE === "true"
|
||||||
|
});
|
||||||
|
|
||||||
|
-const packageJson = require(`${
|
||||||
|
- fs.existsSync(path.join(__dirname, "package.json")) ? "./" : "../"
|
||||||
|
-}package.json`);
|
||||||
|
-
|
||||||
|
module.exports = withBundleAnalyzer({
|
||||||
|
reactStrictMode: true,
|
||||||
|
target: "serverless",
|
||||||
|
@@ -16,7 +12,7 @@ module.exports = withBundleAnalyzer({
|
||||||
|
trailingSlash: true,
|
||||||
|
serverRuntimeConfig: {
|
||||||
|
PROJECT_ROOT: __dirname, // https://github.com/vercel/next.js/issues/8251
|
||||||
|
- VERSION: packageJson.version
|
||||||
|
+ VERSION: "@NIX_LOG4BRAINS_VERSION@",
|
||||||
|
},
|
||||||
|
webpack(config, { webpack, buildId }) {
|
||||||
|
// For cache invalidation purpose (thanks https://github.com/vercel/next.js/discussions/14743)
|
||||||
|
--
|
||||||
|
2.50.1
|
||||||
|
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
From 8c7af30fe7377235037c1a385f484f201ecfe063 Mon Sep 17 00:00:00 2001
|
||||||
|
From: tropf <tropf@users.noreply.github.com>
|
||||||
|
Date: Tue, 26 Aug 2025 15:15:19 +0200
|
||||||
|
Subject: [PATCH 2/2] move nextjs build into temporary directory
|
||||||
|
|
||||||
|
For the build command, upstream invokes a nextjs-base build inside
|
||||||
|
node_modules. As this is read-only in nix, the corresponding directory
|
||||||
|
is copied into a newly-created directory in the temporary directory
|
||||||
|
(e.g. /tmp), from where the build can successfully run.
|
||||||
|
---
|
||||||
|
packages/web/cli/commands/build.ts | 38 +++++++++++++++++++++++++++++-
|
||||||
|
1 file changed, 37 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/packages/web/cli/commands/build.ts b/packages/web/cli/commands/build.ts
|
||||||
|
index b611cd9..213e82f 100644
|
||||||
|
--- a/packages/web/cli/commands/build.ts
|
||||||
|
+++ b/packages/web/cli/commands/build.ts
|
||||||
|
@@ -16,6 +16,36 @@ type Deps = {
|
||||||
|
appConsole: AppConsole;
|
||||||
|
};
|
||||||
|
|
||||||
|
+const fs = require('fs');
|
||||||
|
+const os = require('os');
|
||||||
|
+
|
||||||
|
+// Helper: Recursively copy directory
|
||||||
|
+function copyDirSync(src: any, dest: any) {
|
||||||
|
+ if (!fs.existsSync(dest)) fs.mkdirSync(dest, { recursive: true });
|
||||||
|
+ for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
||||||
|
+ const srcPath = path.join(src, entry.name);
|
||||||
|
+ const destPath = path.join(dest, entry.name);
|
||||||
|
+ if (entry.isDirectory()) {
|
||||||
|
+ copyDirSync(srcPath, destPath);
|
||||||
|
+ } else {
|
||||||
|
+ fs.copyFileSync(srcPath, destPath);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+// Helper: Recursively set writeable flag
|
||||||
|
+function setWriteableSync(target: any) {
|
||||||
|
+ const stat = fs.statSync(target);
|
||||||
|
+ if (stat.isDirectory()) {
|
||||||
|
+ fs.chmodSync(target, 0o755);
|
||||||
|
+ for (const entry of fs.readdirSync(target)) {
|
||||||
|
+ setWriteableSync(path.join(target, entry));
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ fs.chmodSync(target, 0o644);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
export async function buildCommand(
|
||||||
|
{ appConsole }: Deps,
|
||||||
|
outPath: string,
|
||||||
|
@@ -24,7 +54,13 @@ export async function buildCommand(
|
||||||
|
process.env.NEXT_TELEMETRY_DISABLED = "1";
|
||||||
|
appConsole.println("Building Log4brains...");
|
||||||
|
|
||||||
|
- const nextDir = getNextJsDir();
|
||||||
|
+ const oldNextDir = getNextJsDir();
|
||||||
|
+
|
||||||
|
+ const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'log4brains-nextjs-'));
|
||||||
|
+ copyDirSync(oldNextDir, tmpDir);
|
||||||
|
+ setWriteableSync(tmpDir);
|
||||||
|
+ const nextDir = tmpDir;
|
||||||
|
+
|
||||||
|
// eslint-disable-next-line global-require,import/no-dynamic-require,@typescript-eslint/no-var-requires
|
||||||
|
const nextConfig = require(path.join(nextDir, "next.config.js")) as Record<
|
||||||
|
string,
|
||||||
|
--
|
||||||
|
2.50.1
|
||||||
|
|
||||||
118
pkgs/by-name/lo/log4brains/package.nix
Normal file
118
pkgs/by-name/lo/log4brains/package.nix
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
{
|
||||||
|
lib,
|
||||||
|
stdenv,
|
||||||
|
callPackage,
|
||||||
|
fetchFromGitHub,
|
||||||
|
fetchYarnDeps,
|
||||||
|
yarnConfigHook,
|
||||||
|
yarnBuildHook,
|
||||||
|
yarnInstallHook,
|
||||||
|
nodejs,
|
||||||
|
yarn,
|
||||||
|
moreutils,
|
||||||
|
jq,
|
||||||
|
makeBinaryWrapper,
|
||||||
|
fetchpatch2,
|
||||||
|
replaceVars,
|
||||||
|
}:
|
||||||
|
stdenv.mkDerivation (finalAttrs: {
|
||||||
|
pname = "log4brains";
|
||||||
|
version = "1.1.0";
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "thomvaill";
|
||||||
|
repo = "log4brains";
|
||||||
|
tag = "v${finalAttrs.version}";
|
||||||
|
hash = "sha256-2EAETbICK3XSjAEoLV0KP2xeOYlw8qgctit+shMp5Qs=";
|
||||||
|
};
|
||||||
|
|
||||||
|
yarnOfflineCache = fetchYarnDeps {
|
||||||
|
yarnLock = finalAttrs.src + "/yarn.lock";
|
||||||
|
hash = "sha256-HHiWlOYwR+PhfpQlUfuTXUiQ+6w1HATGlmflQvqdNlg=";
|
||||||
|
};
|
||||||
|
|
||||||
|
# generated from https://codeberg.org/tropf/log4brains
|
||||||
|
patches = [
|
||||||
|
# This replaces a version check by accessing package.json, which
|
||||||
|
# in the nix packaging is not at the expected path
|
||||||
|
(replaceVars ./0001-replace-version-check-using-package.json.patch {
|
||||||
|
NIX_LOG4BRAINS_VERSION = finalAttrs.version;
|
||||||
|
})
|
||||||
|
|
||||||
|
./0002-move-nextjs-build-into-temporary-directory.patch
|
||||||
|
];
|
||||||
|
|
||||||
|
postPatch = ''
|
||||||
|
# Top-level is just a workspace (actual packages reside in packages/
|
||||||
|
# subdir), but w/o `version` the yarn hooks refuse to run.
|
||||||
|
jq '.version = "${finalAttrs.version}"' < package.json | sponge package.json
|
||||||
|
'';
|
||||||
|
|
||||||
|
# = Notes =
|
||||||
|
#
|
||||||
|
# Not copying the full node_modules yields:
|
||||||
|
# Error: Cannot find module 'chalk'
|
||||||
|
#
|
||||||
|
# The log4brains version in src/ and the default install differ,
|
||||||
|
# hence remove the copied version and let installPhase handle it.
|
||||||
|
#
|
||||||
|
# An alternative approach is to bundle log4brains binary using (tested only in devshell):
|
||||||
|
# npx pkg --target 'node*-linux-x64' .
|
||||||
|
preInstall = ''
|
||||||
|
mkdir -p $out/lib
|
||||||
|
cp -aLrt $out/lib node_modules
|
||||||
|
|
||||||
|
# will get installed by the installPhase, so avoid conflicts
|
||||||
|
rm -r $out/lib/node_modules/log4brains
|
||||||
|
|
||||||
|
# the desired final package is inside of a subdir; switch there
|
||||||
|
pushd packages/global-cli
|
||||||
|
'';
|
||||||
|
|
||||||
|
# w/o yarn it just generated cryptic errors ENOENT
|
||||||
|
#
|
||||||
|
# There are some builds at runtime (marked as "hack" in the src),
|
||||||
|
# hence we need node_modules set
|
||||||
|
postInstall = ''
|
||||||
|
popd
|
||||||
|
|
||||||
|
wrapProgram $out/bin/log4brains \
|
||||||
|
--suffix PATH : ${
|
||||||
|
lib.makeBinPath [
|
||||||
|
nodejs
|
||||||
|
yarn
|
||||||
|
]
|
||||||
|
} \
|
||||||
|
--set NODE_PATH $out/lib/node_modules
|
||||||
|
'';
|
||||||
|
|
||||||
|
nativeBuildInputs = [
|
||||||
|
yarnConfigHook
|
||||||
|
yarnBuildHook
|
||||||
|
yarnInstallHook
|
||||||
|
# Needed for executing package.json scripts
|
||||||
|
nodejs
|
||||||
|
|
||||||
|
makeBinaryWrapper
|
||||||
|
|
||||||
|
moreutils # sponge
|
||||||
|
jq
|
||||||
|
];
|
||||||
|
|
||||||
|
passthru.tests.basic-scenario = callPackage ./test-basic-scenario.nix {
|
||||||
|
log4brains = finalAttrs.finalPackage;
|
||||||
|
};
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
description = "Architecture Decision Records (ADR) management and publication tool";
|
||||||
|
longDescription = ''
|
||||||
|
Log4brains is a docs-as-code knowledge base for your development and infrastructure projects.
|
||||||
|
It enables you to log Architecture Decision Records (ADR) right from your IDE and to publish them automatically as a static website.
|
||||||
|
'';
|
||||||
|
homepage = "https://github.com/thomvaill/log4brains";
|
||||||
|
license = lib.licenses.asl20;
|
||||||
|
mainProgram = "log4brains";
|
||||||
|
maintainers = with lib.maintainers; [ tropf ];
|
||||||
|
platforms = lib.platforms.all;
|
||||||
|
};
|
||||||
|
})
|
||||||
33
pkgs/by-name/lo/log4brains/test-basic-scenario.nix
Normal file
33
pkgs/by-name/lo/log4brains/test-basic-scenario.nix
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
testers,
|
||||||
|
log4brains,
|
||||||
|
}:
|
||||||
|
testers.runCommand {
|
||||||
|
name = "log4brains-test-basic-scenario";
|
||||||
|
# the build runs for *quite* a while
|
||||||
|
meta.timeout = 90;
|
||||||
|
nativeBuildInputs = [ log4brains ];
|
||||||
|
|
||||||
|
script = ''
|
||||||
|
log4brains | grep 'Log4brains CLI'
|
||||||
|
|
||||||
|
mkdir project && cd project
|
||||||
|
|
||||||
|
log4brains init --defaults
|
||||||
|
test -f docs/adr/index.md
|
||||||
|
|
||||||
|
log4brains adr new --quiet 'Test ADR'
|
||||||
|
grep -r 'Test ADR' docs/adr/ >/dev/null
|
||||||
|
|
||||||
|
# Note: Preview is difficult to check (and hence not checked):
|
||||||
|
# (1) It requires some timeout for the page to become ready.
|
||||||
|
# (2) The signal & process handling is screwed; on kill the
|
||||||
|
# process serving in the background stays alive.
|
||||||
|
|
||||||
|
log4brains build --out www
|
||||||
|
test -f www/index.html
|
||||||
|
grep -r 'Test ADR' www >/dev/null
|
||||||
|
|
||||||
|
touch $out
|
||||||
|
'';
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user