Created
December 1, 2018 23:56
-
-
Save ottidmes/213af6c5f26c5d75c59bd42d67b43405 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
nix-path() { | |
if (( $# < 1 )) || [[ $1 == --help ]]; then | |
echo "Usage: nix-path <pkg_name>..." >&2 | |
return 1 | |
fi | |
if [[ -z $NIX_PATH ]]; then return 1; fi | |
local ret=0 needle found name nix_path | |
for needle in "$@"; do | |
found=false | |
while IFS= read -r -d ':' nix_path; do | |
IFS='=' read -r name nix_path <<< "$nix_path" | |
if [[ $name == "$needle" ]]; then | |
found=true | |
echo "$nix_path" | |
break | |
fi | |
done <<< "$NIX_PATH:" | |
! $found && ret=1 | |
done | |
return $ret | |
} | |
nixos-config() { | |
local nixos_config | |
if [[ -n $NIXOS_CONFIG ]]; then | |
nixos_config=$NIXOS_CONFIG | |
elif ! nixos_config=$(nix-path nixos-config); then | |
nixos_config=/etc/nixos/configuration.nix | |
fi | |
echo "$nixos_config" | |
} | |
grep-nix-store() { | |
find /nix/store -maxdepth 1 | grep "$@" | |
} | |
nix-store-path() { | |
if (( $# < 1 )) || [[ $1 == --help ]]; then | |
echo "Usage: nix-store-path <store_path_like>..." >&2 | |
return 1 | |
fi | |
local ret=0 store_path real_store_path | |
for store_path in "$@"; do | |
if [[ $store_path =~ ^[a-z0-9]{32} ]]; then | |
(( ${#store_path} == 32 )) && store_path=$(bash -c "echo /nix/store/'$store_path'-*") || store_path=/nix/store/$store_path | |
elif ! [[ $store_path == /nix/store/* ]]; then | |
if real_store_path=$(readlink --canonicalize-existing "$store_path") && [[ $real_store_path == /nix/store/* ]]; then | |
echo "$real_store_path" | |
continue | |
elif ! store_path=$(nix-out "$store_path"); then | |
ret=1 | |
continue | |
fi | |
fi | |
[[ -e $store_path ]] && echo "$store_path" || ret=1 | |
done | |
return $ret | |
} | |
nix-outs() { | |
if (( $# != 1 )) || [[ -z $1 || $1 == --help ]]; then | |
echo "Usage: nix-outs <pkg_name>" >&2 | |
return 1 | |
fi | |
local pkg_name=$1 pkg_drv | |
pkg_drv=$(nix-instantiate --quiet '<nixpkgs>' --attr "$pkg_name") && | |
nix-store --query --outputs "$pkg_drv" | |
} | |
nix-out() { | |
if (( $# < 1 )) || [[ $1 == --help ]]; then | |
echo "Usage: nix-out <pkg_name>..." >&2 | |
return 1 | |
fi | |
local ret=0 pkg_name | |
for pkg_name in "$@"; do | |
[[ -n $pkg_name ]] && nix-outs "$pkg_name" > >(tail -1) || ret=1 | |
done | |
return $ret | |
} | |
nix-drv-name() { | |
local arg | |
for arg in "$@"; do | |
arg=${arg%$'\n'} | |
echo -n "$arg" | sed 's/^\.*//' | tr -cs '+-._?=[:alnum:]' - | |
done | |
} | |
nix-drv() { | |
if (( $# < 1 )); then | |
echo "Usage: nix-drv <store_path>..." >&2 | |
return 1 | |
fi | |
local ret=0 store_path pkg_drv | |
for store_path in "$@"; do | |
store_path=$(nix-store-path "$store_path") && | |
pkg_drv=$(nix-store --query --deriver "$store_path") && | |
[[ $pkg_drv != unknown-deriver ]] && echo "$pkg_drv" || ret=1 | |
done | |
return $ret | |
} | |
whichpkg() { | |
local store_path | |
while IFS= read -r store_path; do | |
pkgname "$store_path" | |
done < <(which "$@") | |
} | |
pkgname() { | |
if (( $# != 1 )) || [[ -z $1 ]]; then | |
echo "Usage: pkgname <name>" >&2 | |
return 1 | |
fi | |
search_name=$1 | |
# /nix/store/k033y37bvx5npnrbg14b4rd5vrc0p7gr-rsync-3.1.3/bin/rsync ~> rsync-3.1.3 | |
if [[ $search_name =~ ^/nix/store/ ]]; then | |
search_name=$(echo "$search_name" | sed 's|/nix/store/.\{32\}-\([^/]*\).*|\1|') | |
fi | |
# rsync-3.1.3 ~> rsync | |
grep_name=$(echo "$search_name" | sed 's/[-_]\?[0-9].*//') | |
# Remove characters that would worsen the results of grep's matching. | |
grep_name="${grep_name//[^a-zA-Z_-]/}" | |
# If word boundaries are defined, check all common formats, e.g. inotify-tools ~> (inotify-tools, inotify_tools, inotifytools) | |
if [[ $grep_name =~ [-_] ]]; then | |
grep_names=( "${grep_name//[-_]/-}" "${grep_name//[-_]/_}" "${grep_name//[-_]/}" ) | |
else | |
grep_names=( "$grep_name" ) | |
fi | |
# Find all package names that partially match the name package name being searched for. | |
tab=$'\t' | |
grep_regexp="[^ ${tab}]*($(echo "${grep_names[@]}" | tr ' ' '|'))[^ ]* = callPackage" | |
nixpkgs=$(nix-path nixpkgs) | |
if ! pkg_names=$(grep -E --ignore-case --only-matching "$grep_regexp" "$nixpkgs/pkgs/top-level/all-packages.nix"); then | |
echo "no matches found for '$*'" >&2 | |
return 1 | |
fi | |
pkg_names=${pkg_names// = callPackage/} | |
# Optimize the search name for regular expression matching. | |
# By removing all non-letters and non-digits and lowercasing the letters, | |
# we unify most naming conventions found in all-packages.nix. | |
re_search_name=$(tr 'A-Z' 'a-z' <<< "${search_name//[^a-zA-Z0-9]/}") | |
likely_matches=() | |
while IFS= read -r pkg_name; do | |
# Same optimizations as `re_search_name`. | |
re_pkg_name=$(tr 'A-Z' 'a-z' <<< "${pkg_name//[^a-zA-Z0-9]/}") | |
# We found an exact match, no need to continue searching. | |
if [[ $re_pkg_name == "$re_search_name" ]]; then | |
echo "exact match: $pkg_name" | |
return 0 | |
# We already know the name matches, otherwise it would not have matched the grep's regexp. | |
elif [[ $re_search_name =~ [0-9] ]]; then | |
# Find a package name that exactly matches the name of the package being searched for | |
# and that has a version in the name that comes the closest to the version we are looking for. | |
if [[ $re_search_name =~ ^${re_pkg_name} ]]; then | |
if (( ${#re_pkg_name} > ${#re_best_match} )); then | |
best_match=$pkg_name | |
re_best_match=$re_pkg_name | |
fi | |
# A partial match of both name and version, so a likely candidate. | |
elif [[ $re_pkg_name =~ $re_search_name ]]; then | |
likely_matches+=( "$pkg_name" ) | |
fi | |
fi | |
done <<< "$pkg_names" | |
if [[ -n $best_match ]]; then | |
echo "best match: $best_match" | |
elif (( ${#likely_matches[@]} > 0 )); then | |
echo 'likely matches:' "${likely_matches[@]}" | |
else | |
echo -n 'potential matches:' | |
while IFS= read -r pkg_name; do | |
echo -n " ${pkg_name}" | |
done <<< "$pkg_names" | |
echo | |
fi | |
} | |
pkgfile() { | |
if (( $# != 1 )) || [[ -z $1 ]]; then | |
echo "Usage: pkgfile <pkg_name>" >&2 | |
return 1 | |
fi | |
local grep_name=$1 | |
local tab=$'\t' | |
local nixpkgs=$(nix-path nixpkgs) | |
local call_pkg | |
if ! call_pkg=$(grep -E --ignore-case --max-count=1 --only-matching "[ ${tab}]$grep_name = callPackage [^ ]*" "$nixpkgs/pkgs/top-level/all-packages.nix"); then | |
echo "No matches found for '$grep_name'" >&2 | |
return 1 | |
fi | |
local pkg_path | |
! pkg_path=$(realpath "$nixpkgs/pkgs/top-level/$(echo "$call_pkg" | sed 's/.*callPackage \(.*\)/\1/')") && return 1 | |
if [[ -d $pkg_path ]]; then | |
echo "$pkg_path"/default.nix | |
else | |
echo "$pkg_path" | |
fi | |
} | |
nix-prefetch-src() { | |
if (( $# != 1 )) || [[ -z $1 ]]; then | |
echo "Usage: nix-prefetch-src <pkg_name>" >&2 | |
return 1 | |
fi | |
local pkg_name=$1 | |
nix-prefetch-url '<nixpkgs>' --attr "${pkg_name}.src" | |
} | |
for call in build shell; do | |
source /dev/stdin <<EOF | |
nix-$call-call() { | |
local pkg_path | |
if (( \$# == 0 )); then | |
pkg_path=./. | |
else | |
pkg_path=\$1 | |
if [[ ! -e \$pkg_path ]]; then | |
echo "derivation file or directory '\$pkg_path' does not exist" >&2 | |
exit 1 | |
fi | |
if [[ \$pkg_path != */* ]]; then | |
pkg_path=./\$pkg_path | |
fi | |
fi | |
nix-$call --expr "with import <nixpkgs> { }; callPackage \$pkg_path { }" | |
} | |
EOF | |
done | |
unset -v call | |
nixpkgs-update() { | |
local nixpkgs nixpkgs_unstable | |
nixpkgs=$(nix-path nixpkgs) && | |
git -C "$nixpkgs" remote update channels && | |
git -C "$nixpkgs" rebase channels/nixos-"$(< "$nixpkgs"/.version)" && | |
nixpkgs_unstable=$(nix-path nixpkgs-unstable) && | |
git -C "$nixpkgs_unstable" rebase channels/nixos-unstable | |
} | |
nixos-upgrade() { | |
command nix-env --uninstall '.*' && | |
command sudo nix-env --uninstall '.*' && | |
nixpkgs-update && | |
sudo nixos-rebuild boot | |
} | |
nano-nix() { | |
nano-readonly /etc/nix/nix.conf && | |
systemctl restart nix-daemon | |
} | |
lspkgs() { | |
local user_name | |
user_name=$(id --user --name) && | |
nix-instantiate --eval --strict --json --expr \ | |
'map (pkg: pkg.name) (let config = (import <nixpkgs/nixos> { }).config; in config.environment.systemPackages ++ config.users.users."'"$user_name"'".packages)' | | |
jq --raw-output 'unique | sort_by(ascii_downcase) | .[]' | |
} | |
nixos-system-diff() { | |
local old_drv new_drv | |
old_drv=$(nix-store --query --deriver "$(readlink --canonicalize-existing /nix/var/nix/profiles/system)") && | |
new_drv=$(nix-instantiate --quiet '<nixpkgs/nixos>' --attr system) && | |
nix-diff "$old_drv" "$new_drv" | |
} | |
nix-du() { | |
if (( $# < 1 )); then | |
echo "Usage: nix-du /nix/store/..." >&2 | |
return 1 | |
fi | |
du --human-readable --total --max=0 $(nix-store --query --requisites "$1") | sort --human-numeric-sort | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment