feat: add nix support

merged #25, thank you so much @conroy-cheers!
this will likely fix #16
This commit is contained in:
João Dias
2025-11-09 10:16:15 -03:00
committed by GitHub
9 changed files with 442 additions and 6 deletions
+1
View File
@@ -0,0 +1 @@
use flake
+4 -2
View File
@@ -1,6 +1,8 @@
node_modules/ node_modules
@types/ @types/
build/ build/
pnpm-lock.yaml
*.log *.log
result
.direnv/
Generated
+106
View File
@@ -0,0 +1,106 @@
{
"nodes": {
"ags": {
"inputs": {
"astal": [
"astal"
],
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1762046771,
"narHash": "sha256-baVZvZZN0t9F3fvVhxmQA1/oNykXGd/YhlF19JqCLc8=",
"owner": "aylur",
"repo": "ags",
"rev": "fe13af2daec716226ccdb3158606a8577853e0ff",
"type": "github"
},
"original": {
"owner": "aylur",
"repo": "ags",
"type": "github"
}
},
"astal": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1762012522,
"narHash": "sha256-ncEN4OVFM5M9VFc4oR3gOI5K8r99GcYxtU+Cf4Z8pbs=",
"owner": "aylur",
"repo": "astal",
"rev": "671d4229c798834190a50fb8b8d8addd19b529e9",
"type": "github"
},
"original": {
"owner": "aylur",
"repo": "astal",
"type": "github"
}
},
"flake-parts": {
"inputs": {
"nixpkgs-lib": "nixpkgs-lib"
},
"locked": {
"lastModified": 1762040540,
"narHash": "sha256-z5PlZ47j50VNF3R+IMS9LmzI5fYRGY/Z5O5tol1c9I4=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "0010412d62a25d959151790968765a70c436598b",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1761907660,
"narHash": "sha256-kJ8lIZsiPOmbkJypG+B5sReDXSD1KGu2VEPNqhRa/ew=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "2fb006b87f04c4d3bdf08cfdbc7fab9c13d94a15",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-lib": {
"locked": {
"lastModified": 1761765539,
"narHash": "sha256-b0yj6kfvO8ApcSE+QmA6mUfu8IYG6/uU28OFn4PaC8M=",
"owner": "nix-community",
"repo": "nixpkgs.lib",
"rev": "719359f4562934ae99f5443f20aa06c2ffff91fc",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixpkgs.lib",
"type": "github"
}
},
"root": {
"inputs": {
"ags": "ags",
"astal": "astal",
"flake-parts": "flake-parts",
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}
+60
View File
@@ -0,0 +1,60 @@
{
description = "Super cool desktop shell for Hyprland!";
inputs = {
flake-parts.url = "github:hercules-ci/flake-parts";
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
astal = {
url = "github:aylur/astal";
inputs.nixpkgs.follows = "nixpkgs";
};
ags = {
url = "github:aylur/ags";
inputs.nixpkgs.follows = "nixpkgs";
inputs.astal.follows = "astal";
};
};
outputs =
inputs@{ flake-parts, ... }:
flake-parts.lib.mkFlake { inherit inputs; } {
imports = [
# To import an internal flake module: ./other.nix
# To import an external flake module:
# 1. Add foo to inputs
# 2. Add foo as a parameter to the outputs function
# 3. Add here: foo.flakeModule
];
systems = [
"x86_64-linux"
"aarch64-linux"
];
perSystem =
{
config,
self',
inputs',
pkgs,
system,
...
}:
let
colorshell = pkgs.callPackage ./nix/package.nix { inherit inputs'; };
in
{
packages = {
inherit colorshell;
default = colorshell;
};
devShells = import ./nix/devshell.nix { inherit self' pkgs; };
};
flake = {
passthru = {
inherit inputs;
};
};
};
}
+52
View File
@@ -0,0 +1,52 @@
{
self',
pkgs,
}:
let
colorshell = self'.packages.colorshell;
packages = [
];
devPackages = with pkgs; [
nodePackages.nodejs
pnpm
# dev scripts
jq
# pywal16
pywal16
imagemagick
];
colorshellDeps = pkgs.stdenvNoCC.mkDerivation {
inherit (colorshell.pnpmDeps) name src;
inherit (colorshell) pnpmDeps sourceRoot;
buildInputs = [ colorshell.npmConfigHook ];
installPhase = ''
mkdir -p $out/lib
cp -rp node_modules $out/lib/node_modules
'';
};
in
{
default = pkgs.mkShell {
inputsFrom = [ colorshell ];
packages = devPackages ++ packages;
shellHook = ''
NODE_MODULES_PATH="${colorshellDeps}/lib/node_modules"
if [ -L ./node_modules ] || [ -e ./node_modules ]; then
rm -rf ./node_modules
fi
echo "Linking $NODE_MODULES_PATH" to $PWD/node_modules...
ln -s $NODE_MODULES_PATH .
'';
passthru = {
inherit colorshellDeps;
};
};
}
+159
View File
@@ -0,0 +1,159 @@
{
inputs',
lib,
stdenv,
stdenvNoCC,
pnpm_10,
buildNpmPackage,
wrapGAppsHook4,
gobject-introspection,
glib,
gjs,
libadwaita,
}:
let
packageJSON = lib.importJSON ../package.json;
pname = packageJSON.name;
version = packageJSON.version;
# Cleaned sources from this repository
src = lib.fileset.toSource {
root = ../.;
fileset = lib.fileset.difference ../. (
lib.fileset.unions [
../flake.nix
../flake.lock
./.
]
);
};
# Derivation building just the gresources file
colorshellResources = stdenv.mkDerivation {
pname = "${pname}-resources.gresource";
inherit version;
inherit src;
buildInputs = [
glib
];
buildPhase = ''
runHook preBuild
glib-compile-resources resources.gresource.xml \
--sourcedir ./resources \
--target resources.gresource
runHook postBuild
'';
installPhase = ''
runHook preInstall
cp resources.gresource $out
runHook postInstall
'';
};
# Cleaned sources, with FHS paths patched out.
colorshellSrc = stdenvNoCC.mkDerivation {
pname = "${pname}-src";
inherit version;
inherit src;
# Replace reference to ags FHS install path
postPatch = ''
substituteInPlace package.json pnpm-lock.yaml \
--replace-fail "/usr/share/ags/js" "${inputs'.ags.packages.ags.jsPackage}"
'';
installPhase = ''
mkdir $out
cp -rp * $out
'';
};
in
buildNpmPackage (finalAttrs: {
inherit pname version;
src = colorshellSrc;
sourceRoot = "${finalAttrs.src.name}";
npmConfigHook = pnpm_10.configHook;
npmDeps = finalAttrs.pnpmDeps;
pnpmDeps = pnpm_10.fetchDeps {
inherit (finalAttrs)
pname
version
src
sourceRoot
;
fetcherVersion = 2;
hash = "sha256-m/aPNvv26r0DUvRUR4TL2GwwAHKvEIkc8Nvlm/jpnPc=";
# fetcher version 2 fails if there are no *-exec files in the output
preFixup = ''
touch $out/.dummy-exec
'';
};
nativeBuildInputs = [
wrapGAppsHook4
gobject-introspection
inputs'.ags.packages.default
];
buildInputs = [
glib
gjs
libadwaita
inputs'.astal.packages.astal4
inputs'.astal.packages.apps
inputs'.astal.packages.auth
inputs'.astal.packages.battery
inputs'.astal.packages.bluetooth
inputs'.astal.packages.hyprland
inputs'.astal.packages.io
inputs'.astal.packages.mpris
inputs'.astal.packages.network
inputs'.astal.packages.notifd
inputs'.astal.packages.tray
inputs'.astal.packages.wireplumber
];
buildPhase = ''
runHook preBuild
mkdir -p $out/bin
ags bundle ./src/app.ts $out/bin/${packageJSON.name} \
--gtk 4 \
--root ./src \
--define "DEVEL=false" \
--define "COLORSHELL_VERSION='${finalAttrs.version}'" \
--define "GRESOURCES_FILE='${colorshellResources}'"
runHook postBuild
'';
# the above buildPhase installs for us
dontInstall = true;
preFixup = ''
gappsWrapperArgs+=(
--prefix PATH : ${
lib.makeBinPath [
# runtime executables
]
}
)
'';
passthru = {
resources = colorshellResources;
};
})
+1 -1
View File
@@ -13,7 +13,7 @@
"sync-config": "sh ./scripts/sync-config.sh" "sync-config": "sh ./scripts/sync-config.sh"
}, },
"devDependencies": { "devDependencies": {
"ags": "link:/usr/share/ags/js", "ags": "file:/usr/share/ags/js",
"gnim-utils": "github:retrozinndev/gnim-utils#1.0.0", "gnim-utils": "github:retrozinndev/gnim-utils#1.0.0",
"fuse.js": "^7.1.0" "fuse.js": "^7.1.0"
} }
+56
View File
@@ -0,0 +1,56 @@
lockfileVersion: '9.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
importers:
.:
devDependencies:
ags:
specifier: file:/usr/share/ags/js
version: file:../../../../usr/share/ags/js(gnim@1.8.2)
fuse.js:
specifier: ^7.1.0
version: 7.1.0
gnim-utils:
specifier: github:retrozinndev/gnim-utils#1.0.0
version: https://codeload.github.com/retrozinndev/gnim-utils/tar.gz/8bfb7d21817ac91a639c3cc90f1b4f66eb990b1e(gnim@1.8.2)
packages:
ags@file:../../../../usr/share/ags/js:
resolution: {directory: ../../../../usr/share/ags/js, type: directory}
engines: {gjs: '>=1.79.0'}
os: [linux]
peerDependencies:
gnim: ^1.8.2
fuse.js@7.1.0:
resolution: {integrity: sha512-trLf4SzuuUxfusZADLINj+dE8clK1frKdmqiJNb1Es75fmI5oY6X2mxLVUciLLjxqw/xr72Dhy+lER6dGd02FQ==}
engines: {node: '>=10'}
gnim-utils@https://codeload.github.com/retrozinndev/gnim-utils/tar.gz/8bfb7d21817ac91a639c3cc90f1b4f66eb990b1e:
resolution: {tarball: https://codeload.github.com/retrozinndev/gnim-utils/tar.gz/8bfb7d21817ac91a639c3cc90f1b4f66eb990b1e}
version: 1.0.0
peerDependencies:
gnim: ^1.8.2
gnim@1.8.2:
resolution: {integrity: sha512-VwvTLclraJPAhS//SzdlWNOdaA7xKqC7KkJpIq5jq9DKDTXPis5SCrExFxrcjtcujK+I2l4drNvoXp6s1G78NA==}
engines: {gjs: '>=1.79.0'}
snapshots:
ags@file:../../../../usr/share/ags/js(gnim@1.8.2):
dependencies:
gnim: 1.8.2
fuse.js@7.1.0: {}
gnim-utils@https://codeload.github.com/retrozinndev/gnim-utils/tar.gz/8bfb7d21817ac91a639c3cc90f1b4f66eb990b1e(gnim@1.8.2):
dependencies:
gnim: 1.8.2
gnim@1.8.2: {}
+3 -3
View File
@@ -1,5 +1,5 @@
// thanks Aylur!! // thanks Aylur!!
import "/usr/share/ags/js/lib/overrides"; import "ags/overrides";
import "./config"; import "./config";
import { import {
PluginApps, PluginApps,
@@ -168,7 +168,7 @@ you should use the socket in the XDG_RUNTIME_DIR/colorshell.sock for a faster re
private init(): void { private init(): void {
// load gresource from build-defined path // load gresource from build-defined path
try { try {
this.#gresource = Gio.Resource.load(GRESOURCES_FILE.split('/').filter(s => const gresourcesPath: string = GRESOURCES_FILE.startsWith('/') ? GRESOURCES_FILE : (GRESOURCES_FILE.split('/').filter(s =>
s !== "" s !== ""
).map(path => { ).map(path => {
// support environment variables at runtime // support environment variables at runtime
@@ -179,9 +179,9 @@ you should use the socket in the XDG_RUNTIME_DIR/colorshell.sock for a faster re
return env; return env;
} }
return path; return path;
}).join('/')); }).join('/'));
this.#gresource = Gio.Resource.load(gresourcesPath);
Gio.resources_register(this.#gresource); Gio.resources_register(this.#gresource);
// add icons // add icons