Skip to content

Commit

Permalink
feat: add nix-cleanup script and nixfied package
Browse files Browse the repository at this point in the history
  • Loading branch information
willyrgf committed Jun 10, 2024
1 parent d043fdb commit 88886b1
Show file tree
Hide file tree
Showing 5 changed files with 254 additions and 1 deletion.
35 changes: 35 additions & 0 deletions .github/workflows/nix-checks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Nix Checks

on:
push:
paths:
- 'flake.nix'
- 'flake.lock'
- 'nix-cleanup.sh'
- '.github/workflows/nix-checks.yml'

jobs:
nix_checks:
runs-on: ubuntu-latest
strategy:
fail-fast: false
permissions:
id-token: write
contents: read
pull-requests: read

steps:
- name: Checkout repository
uses: actions/checkout@cd7d8d697e10461458bc61a30d094dc601a8b017 #v4

- uses: cachix/install-nix-action@8887e596b4ee1134dae06b98d573bd674693f47c #v26
with:
nix_path: nixpkgs=channel:nixos-unstable
extra_nix_config: |
sandbox = true # force sandbox for all OS (normally disabled for macOS)
- name: Run app
run: nix run --print-build-logs --show-trace '.#nix-cleanup' -- --help

- name: Run app with --system
run: nix run --print-build-logs --show-trace '.#nix-cleanup' -- --system
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
# nix-cleanup
# nix-cleanup
nix-cleanup is a script that cleans up the nix environment

## Run
`nix run 'github:willyrgf/nix-cleanup'`

60 changes: 60 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 40 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
description = "nix-cleanup is a script that cleans up the nix environment.";

inputs.nixpkgs.url = "github:NixOS/nixpkgs";
inputs.flake-utils.url = "github:numtide/flake-utils";

outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs { inherit system; };
in
{
packages.nix-cleanup = pkgs.stdenv.mkDerivation rec {
pname = "nix-cleanup";
version = "0.0.1";
src = ./.;

buildInputs = [ pkgs.bash pkgs.nix pkgs.sudo ];

installPhase = ''
mkdir -p $out/bin
substitute ${pname}.sh $out/bin/${pname} \
--replace "/usr/bin/env bash" "${pkgs.bash}/bin/bash"
chmod +x $out/bin/${pname}
'';

shellHook = ''
export PATH=${pkgs.bash}/bin:${pkgs.nix}/bin:${pkgs.sudo}/bin:$PATH
'';
};

defaultPackage = self.packages.${system}.nix-cleanup;

defaultApp = {
type = "app";
program = "${self.packages.${system}.nix-cleanup}/bin/nix-cleanup";
};
});
}

113 changes: 113 additions & 0 deletions nix-cleanup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#!/usr/bin/env bash

_exit_error(){
echo "ERROR: $@"
exit 1
}

_arg0(){
echo -n $0 | grep -Eo '([a-z]+[-.]?){1,}$'
}

_help(){
printf "
Usage: $(_arg0) [--system] [flake-pkg-name] [nix-store-path]
\t--system\t\tcleans up the whole nix-store (nix state)
\tflake-pkg-name\t\tcleans up everything related to this package on the nix-store
\tnix-store-path\t\tcleans up everything related to a nix-store path
"
}

_delete_from_store_path(){
STORE_PATH=$1

# Get all referrers
REFERRERS=$(nix-store --query --referrers-closure "$STORE_PATH")

# Combine the store path and its referrers
ALL_PATHS="$STORE_PATH $REFERRERS"

echo "The following paths will be deleted (${#ALL_PATHS}):"
echo "$ALL_PATHS"

# Confirm before deletion
if [ ${CLEANUP_SYSTEM} -ne 1 ]; then
read -p "Are you sure you want to delete these paths? (y/N): " -r
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo "Aborting."
exit 1
fi
fi

# Delete the store path and its referrers
sudo nix-store --delete $ALL_PATHS

echo "Deleted the following paths:"
echo "$ALL_PATHS"
}

_nix_cleanup_system() {
echo "Indexing and deleting all nix-store paths..."
ls -1 -f -q /nix/store/ | grep -v '^\.' |
xargs -I {} -P 4 $0 /nix/store/{}

# Perform garbage collection to clean up everything
sudo nix-collect-garbage -d
}

_cleanup_package() {
PACKAGE_NAME=$1

# Get the store path of the package

STORE_PATH=$(nix path-info .#$PACKAGE_NAME 2> >(grep -Eo '/nix/store/([a-z0-9]+[_.-]?)+'))
if [ -z "$STORE_PATH" ]; then
echo "Package $PACKAGE_NAME not found."
exit 1
fi
echo "Found store path: ${STORE_PATH[@]}"
_delete_from_store_path ${STORE_PATH[@]}
# Perform garbage collection to clean up everything
sudo nix-collect-garbage -d
echo "Garbage collection complete. Nix store is cleaned up."
}
export CLEANUP_SYSTEM=0
# Ensure required packages is available
required_packages=("nix" "nix-store" "nix-collect-garbage")
for req in "${required_packages[@]}"; do
if ! type ${req} > /dev/null 2>&1; then
_exit_error "package required: ${req}"
fi
done
# Ensure a arg is provided
if [ -z "$1" ]; then
_help
exit 1
fi
if [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]]; then
_help
exit 0
fi
if [ "$1" == "--system" ]; then
CLEANUP_SYSTEM=1
_nix_cleanup_system
exit $?
fi
if [[ "$1" =~ "/nix/store" ]]; then
CLEANUP_SYSTEM=1
_delete_from_store_path $1
exit $?
fi
_cleanup_package $@

0 comments on commit 88886b1

Please sign in to comment.