Compare commits
No commits in common. "master" and "before-nix" have entirely different histories.
master
...
before-nix
715 changed files with 5828 additions and 67900 deletions
.forgejo/workflows
.gitattributes.gitignoreKvantum
LICENSE.mdREADME.mdTODO.mdVSCodium/User
_outputs.nixalacritty
apps
README.mdbuildApp.nix
config
default.nixextract-subs
gen-docs
list2series
mc-mods
packages.nixpin-inputs
update-sources
configurations
|
@ -1,19 +0,0 @@
|
|||
name: Discord
|
||||
|
||||
on:
|
||||
- workflow_dispatch
|
||||
- push
|
||||
|
||||
jobs:
|
||||
discord_commits:
|
||||
runs-on: ubuntu-latest
|
||||
name: discord commits
|
||||
if: contains(github.event.head_commit.message, '(servers)')
|
||||
|
||||
steps:
|
||||
- name: Discommit
|
||||
uses: https://github.com/matt1432/discommit@v0.0.2
|
||||
with:
|
||||
discord_webhook: ${{ secrets.DISCORD_WEBHOOK }}
|
||||
api_url: 'https://git.nelim.org/api/v1/repos/$OWNER/$REPO/git/commits/$REF'
|
||||
title: 'New commit containing changes to server configs:'
|
5
.gitattributes
vendored
5
.gitattributes
vendored
|
@ -1,5 +0,0 @@
|
|||
flake.lock -diff
|
||||
flake.nix -diff
|
||||
**/non-declarative-conf -diff
|
||||
**/package-lock.json -diff
|
||||
**/HomeAssistantGenerated -diff
|
99
.gitignore
vendored
99
.gitignore
vendored
|
@ -1,23 +1,76 @@
|
|||
# Python
|
||||
*.egg-info
|
||||
|
||||
# NPM
|
||||
*node_modules
|
||||
*build/
|
||||
|
||||
# Direnv
|
||||
*.direnv/
|
||||
|
||||
# Generated by nix
|
||||
result*
|
||||
!results/
|
||||
.nixd.json
|
||||
|
||||
## AGS
|
||||
**/vars.ts
|
||||
**/config.js
|
||||
*icons
|
||||
**/types
|
||||
|
||||
# Other
|
||||
*.temp
|
||||
okularrc
|
||||
user-dirs.dirs
|
||||
.gsd-keyboard.settings-ported
|
||||
arkrc
|
||||
evolution/
|
||||
fontconfig/
|
||||
gnome-initial-setup-done
|
||||
kcharselectrc
|
||||
user-dirs.locale
|
||||
GalaxyBudsClient/
|
||||
baloofilerc
|
||||
Zeal/
|
||||
environment.d/
|
||||
gtk-3.0/bookmarks
|
||||
Kvantum/**/
|
||||
chromium/
|
||||
Electron/
|
||||
GIMP/
|
||||
Nextcloud/
|
||||
PhotoQt/
|
||||
QtProject.conf
|
||||
VSCodium/Cache/
|
||||
VSCodium/CachedData/
|
||||
VSCodium/CachedExtensionVSIXs/
|
||||
VSCodium/CachedProfilesData/
|
||||
VSCodium/Code Cache/
|
||||
VSCodium/Cookies
|
||||
VSCodium/Cookies-journal
|
||||
VSCodium/Crashpad/
|
||||
VSCodium/DawnCache/
|
||||
VSCodium/Dictionaries/
|
||||
VSCodium/GPUCache/
|
||||
VSCodium/Local Storage/
|
||||
VSCodium/Network Persistent State
|
||||
VSCodium/Preferences
|
||||
VSCodium/Service Worker/
|
||||
VSCodium/Session Storage/
|
||||
VSCodium/TransportSecurity
|
||||
VSCodium/User/History/
|
||||
VSCodium/User/globalStorage/
|
||||
VSCodium/User/workspaceStorage/
|
||||
VSCodium/WebStorage/
|
||||
VSCodium/code.lock
|
||||
VSCodium/databases/
|
||||
VSCodium/languagepacks.json
|
||||
VSCodium/logs/
|
||||
VSCodium/machineid
|
||||
akregatorrc
|
||||
autostart/
|
||||
baloofileinformationrc
|
||||
dconf/
|
||||
discord/
|
||||
gtk-4.0/
|
||||
htop/
|
||||
kconf_updaterc
|
||||
kde.org/
|
||||
kdeglobals
|
||||
kiorc
|
||||
libreoffice/
|
||||
mimeapps.list
|
||||
pavucontrol.ini
|
||||
pulse/
|
||||
replugged/
|
||||
session/
|
||||
spicetify/
|
||||
spotify/
|
||||
systemd/
|
||||
trashrc
|
||||
tuta_integration/
|
||||
tutanota-desktop/
|
||||
unity3d/
|
||||
unityhub/
|
||||
vlc/
|
||||
wireguard/
|
||||
xsettingsd/
|
||||
waybar/scripts/.heart
|
||||
|
|
2
Kvantum/kvantum.kvconfig
Normal file
2
Kvantum/kvantum.kvconfig
Normal file
|
@ -0,0 +1,2 @@
|
|||
[General]
|
||||
theme=LavandaDark
|
16
LICENSE.md
16
LICENSE.md
|
@ -1,16 +0,0 @@
|
|||
MIT No Attribution
|
||||
|
||||
Copyright 2024 Mathis H.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
software and associated documentation files (the "Software"), to deal in the Software
|
||||
without restriction, including without limitation the rights to use, copy, modify,
|
||||
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
101
README.md
101
README.md
|
@ -1,100 +1,3 @@
|
|||
# My NixOS configs
|
||||
Kvantum, qt5ct and my environment are for theming QT apps the same way I do with GTK apps with lxappearance (i have to run it with the X11 backend)
|
||||
|
||||
## AGS
|
||||
|
||||
You might find it weird that most of my config is written in TypeScript.
|
||||
That's because all my desktops run
|
||||
[AGS](https://github.com/Aylur/ags)
|
||||
for UI. Click on
|
||||
[this](https://git.nelim.org/matt1432/nixos-configs/src/branch/master/modules/ags)
|
||||
to see my configuration.
|
||||
|
||||
I'm also a victim of Stockholm syndrome at this point and make my scripts
|
||||
in TypeScript because it's the scripting language I am most comfortable with.
|
||||
|
||||
## About
|
||||
|
||||
### General
|
||||
|
||||
This repo is the complete configuration of machines I own running NixOS or Nix
|
||||
and any other related smaller projects exposed by a Nix Flake.
|
||||
|
||||
Its main directory structure is based on a flake's
|
||||
[outputs](https://wiki.nixos.org/wiki/Flakes#Output_schema).
|
||||
|
||||
I try to follow a few rules to better organise my Nix code:
|
||||
|
||||
- Every main subdirectory only has an optional `default.nix` and subfolders for each
|
||||
of its attributes.
|
||||
- Inside a subdirectory, if there is non nix code, it will be in a `config` folder.
|
||||
- Every module should not do anything if imported. An enable option should be toggled
|
||||
for it to have any effect.
|
||||
- Any nix file that represents a module should be named `default.nix` (a nix file
|
||||
which is imported directly can be called anything else alongside `default.nix`)
|
||||
|
||||
### Flake Location
|
||||
|
||||
This git repo will always be located at `$FLAKE` (`config.environment.variables.FLAKE`)
|
||||
and symlinked to `/etc/nixos` to have everything where NixOS tools
|
||||
expect things to be.
|
||||
|
||||
ie.
|
||||
|
||||
```bash
|
||||
sudo rm -r /etc/nixos
|
||||
|
||||
echo "$FLAKE" # /home/matt/.nix
|
||||
|
||||
sudo ln -sf /home/matt/.nix /etc/nixos
|
||||
```
|
||||
|
||||
### Subdirectories
|
||||
|
||||
| Output / Directory | Description |
|
||||
| -------------------- | ----------- |
|
||||
| `apps` | [Misc scripts ran from the flake](./apps) |
|
||||
| `configurations` | [device, ISO and nix-on-droid configurations](./configurations) |
|
||||
| `devShells` | [Development shells for a bunch of projects and languages](./devShells) |
|
||||
| `homeManagerModules` | [Modules made for home-manager](./homeManagerModules) |
|
||||
| `inputs` | [Pre-evaluated flake inputs](./inputs) |
|
||||
| `lib` | [Custom Nix functions made easily available](./lib) |
|
||||
| `modules` | [Modules made for NixOS systems](./modules) |
|
||||
| `nixFastChecks` | [Attribute set of derivations exposed by this flake](./nixFastChecks) |
|
||||
| `overlays` | [Nixpkgs overlays](./overlays) |
|
||||
| `packages` | [Some custom packages not available in nixpkgs or modified from it](./packages) |
|
||||
| `results` | Directory where I neatly keep my result symlinks from `nixFastChecks` |
|
||||
| `scopedPackages` | [Some custom package scopes not available in nixpkgs or modified from it](./scopedPackages) |
|
||||
|
||||
### Secrets
|
||||
|
||||
All my secrets are in a private git repo that makes use of
|
||||
[sops-nix](https://github.com/Mic92/sops-nix).
|
||||
I generate `.sops.yaml` from `.sops.nix`:
|
||||
|
||||
```nix
|
||||
let
|
||||
wim = "somekey";
|
||||
binto = "somekey2";
|
||||
in {
|
||||
creation_rules = [
|
||||
{
|
||||
path_regex = "secrets/[^/]+\\.(yaml|json|env|ini)$";
|
||||
key_groups = [
|
||||
{
|
||||
age = [wim binto];
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
which is then converted to `.sops.yaml` using
|
||||
[remarshal](https://github.com/remarshal-project/remarshal)
|
||||
and this shell command:
|
||||
|
||||
```bash
|
||||
nix eval --json --file ./.sops.nix | remarshal --if json --of yaml > .sops.yaml
|
||||
```
|
||||
|
||||
TLDR: I **[hate](https://ruudvanasseldonk.com/2023/01/11/the-yaml-document-from-hell)** YAML
|
||||
I use some scripts to make my own tablet mode since my laptop's switch is not yet in the kernel
|
||||
|
|
3
TODO.md
Normal file
3
TODO.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
change tray icons
|
||||
decide on layers for eww and waybar
|
||||
double tap to right click
|
12
VSCodium/User/settings.json
Normal file
12
VSCodium/User/settings.json
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"editor.fontSize": 16,
|
||||
"editor.wordWrap": "on",
|
||||
"omnisharp.useGlobalMono": "always",
|
||||
"workbench.startupEditor": "none",
|
||||
"workbench.colorTheme": "Cherry Midnight",
|
||||
"git.openRepositoryInParentFolders": "always",
|
||||
"git.autofetch": true,
|
||||
"clangd.path": "/home/matt/.config/VSCodium/User/globalStorage/llvm-vs-code-extensions.vscode-clangd/install/16.0.2/clangd_16.0.2/bin/clangd",
|
||||
"git.enableSmartCommit": true,
|
||||
"git.confirmSync": false
|
||||
}
|
110
_outputs.nix
110
_outputs.nix
|
@ -1,110 +0,0 @@
|
|||
{
|
||||
inputs = import ./inputs;
|
||||
|
||||
outputs = inputs @ {
|
||||
self,
|
||||
systems,
|
||||
nixpkgs,
|
||||
secrets,
|
||||
...
|
||||
}: let
|
||||
inherit (self.lib) mkNixOS mkNixOnDroid mkPkgs;
|
||||
|
||||
perSystem = attrs:
|
||||
nixpkgs.lib.genAttrs (import systems) (system:
|
||||
attrs (mkPkgs {inherit system nixpkgs;}));
|
||||
in {
|
||||
lib = import ./lib {inherit inputs perSystem;};
|
||||
|
||||
nixOnDroidConfigurations.default =
|
||||
mkNixOnDroid [./configurations/android];
|
||||
|
||||
nixosConfigurations = {
|
||||
# Desktops
|
||||
wim = mkNixOS {
|
||||
extraModules = [
|
||||
./configurations/wim
|
||||
secrets.nixosModules.default
|
||||
];
|
||||
};
|
||||
binto = mkNixOS {
|
||||
cudaSupport = true;
|
||||
extraModules = [./configurations/binto];
|
||||
};
|
||||
|
||||
bbsteamie = mkNixOS {
|
||||
mainUser = "mariah";
|
||||
extraModules = [./configurations/bbsteamie];
|
||||
};
|
||||
|
||||
# NAS
|
||||
nos = mkNixOS {
|
||||
cudaSupport = true;
|
||||
extraModules = [
|
||||
./configurations/nos
|
||||
secrets.nixosModules.nos
|
||||
];
|
||||
};
|
||||
|
||||
# Build / test server
|
||||
servivi = mkNixOS {
|
||||
extraModules = [
|
||||
./configurations/servivi
|
||||
secrets.nixosModules.servivi
|
||||
];
|
||||
};
|
||||
|
||||
# Home-assistant
|
||||
homie = mkNixOS {
|
||||
extraModules = [
|
||||
./configurations/homie
|
||||
secrets.nixosModules.homie
|
||||
];
|
||||
};
|
||||
|
||||
# Cluster
|
||||
thingone = mkNixOS {
|
||||
extraModules = [
|
||||
(import ./configurations/cluster "thingone")
|
||||
secrets.nixosModules.thingy
|
||||
];
|
||||
};
|
||||
thingtwo = mkNixOS {
|
||||
extraModules = [
|
||||
(import ./configurations/cluster "thingtwo")
|
||||
secrets.nixosModules.thingy
|
||||
];
|
||||
};
|
||||
|
||||
live-image = mkNixOS {
|
||||
mainUser = "nixos";
|
||||
extraModules = [./configurations/live-image];
|
||||
};
|
||||
};
|
||||
|
||||
# For nix-fast-build. I use a custom output to alleviate eval time of this flake. ie. when doing nix flake show
|
||||
nixFastChecks = import ./nixFastChecks {inherit perSystem self;};
|
||||
|
||||
homeManagerModules = import ./homeManagerModules {inherit self;};
|
||||
|
||||
nixosModules = import ./modules {inherit self;};
|
||||
|
||||
overlays = import ./overlays {inherit self;};
|
||||
|
||||
apps =
|
||||
perSystem (pkgs:
|
||||
import ./apps {inherit pkgs self;});
|
||||
|
||||
appsPackages = perSystem (pkgs: pkgs.appsPackages);
|
||||
|
||||
devShells =
|
||||
perSystem (pkgs:
|
||||
import ./devShells {inherit pkgs self;});
|
||||
|
||||
packages = perSystem (pkgs: pkgs.selfPackages);
|
||||
|
||||
scopedPackages = perSystem (pkgs: pkgs.scopedPackages);
|
||||
|
||||
formatter = perSystem (pkgs: pkgs.alejandra);
|
||||
};
|
||||
}
|
920
alacritty/alacritty.yml
Normal file
920
alacritty/alacritty.yml
Normal file
|
@ -0,0 +1,920 @@
|
|||
# Configuration for Alacritty, the GPU enhanced terminal emulator.
|
||||
|
||||
# Import additional configuration files
|
||||
#
|
||||
# Imports are loaded in order, skipping all missing files, with the importing
|
||||
# file being loaded last. If a field is already present in a previous import, it
|
||||
# will be replaced.
|
||||
#
|
||||
# All imports must either be absolute paths starting with `/`, or paths relative
|
||||
# to the user's home directory starting with `~/`.
|
||||
#import:
|
||||
# - /path/to/alacritty.yml
|
||||
|
||||
# Any items in the `env` entry below will be added as
|
||||
# environment variables. Some entries may override variables
|
||||
# set by alacritty itself.
|
||||
env:
|
||||
# TERM variable
|
||||
#
|
||||
# This value is used to set the `$TERM` environment variable for
|
||||
# each instance of Alacritty. If it is not present, alacritty will
|
||||
# check the local terminfo database and use `alacritty` if it is
|
||||
# available, otherwise `xterm-256color` is used.
|
||||
#TERM: alacritty
|
||||
POKE: "true"
|
||||
|
||||
window:
|
||||
# Window dimensions (changes require restart)
|
||||
#
|
||||
# Number of lines/columns (not pixels) in the terminal. Both lines and columns
|
||||
# must be non-zero for this to take effect. The number of columns must be at
|
||||
# least `2`, while using a value of `0` for columns and lines will fall back
|
||||
# to the window manager's recommended size
|
||||
#dimensions:
|
||||
# columns: 0
|
||||
# lines: 0
|
||||
|
||||
# Window position (changes require restart)
|
||||
#
|
||||
# Specified in number of pixels.
|
||||
# If the position is not set, the window manager will handle the placement.
|
||||
#position:
|
||||
# x: 0
|
||||
# y: 0
|
||||
|
||||
# Window padding (changes require restart)
|
||||
#
|
||||
# Blank space added around the window in pixels. This padding is scaled
|
||||
# by DPI and the specified value is always added at both opposing sides.
|
||||
padding:
|
||||
x: 0
|
||||
y: 10
|
||||
|
||||
# Spread additional padding evenly around the terminal content.
|
||||
#dynamic_padding: false
|
||||
|
||||
# Window decorations
|
||||
#
|
||||
# Values for `decorations`:
|
||||
# - full: Borders and title bar
|
||||
# - none: Neither borders nor title bar
|
||||
#
|
||||
# Values for `decorations` (macOS only):
|
||||
# - transparent: Title bar, transparent background and title bar buttons
|
||||
# - buttonless: Title bar, transparent background and no title bar buttons
|
||||
#decorations: full
|
||||
|
||||
# Background opacity
|
||||
#
|
||||
# Window opacity as a floating point number from `0.0` to `1.0`.
|
||||
# The value `0.0` is completely transparent and `1.0` is opaque.
|
||||
opacity: 0.8
|
||||
|
||||
# Startup Mode (changes require restart)
|
||||
#
|
||||
# Values for `startup_mode`:
|
||||
# - Windowed
|
||||
# - Maximized
|
||||
# - Fullscreen
|
||||
#
|
||||
# Values for `startup_mode` (macOS only):
|
||||
# - SimpleFullscreen
|
||||
#startup_mode: Windowed
|
||||
|
||||
# Window title
|
||||
#title: Alacritty
|
||||
|
||||
# Allow terminal applications to change Alacritty's window title.
|
||||
#dynamic_title: true
|
||||
|
||||
# Window class (Linux/BSD only):
|
||||
#class:
|
||||
# Application instance name
|
||||
#instance: Alacritty
|
||||
# General application class
|
||||
#general: Alacritty
|
||||
|
||||
# Decorations theme variant
|
||||
#
|
||||
# Override the variant of the System theme/GTK theme/Wayland client side
|
||||
# decorations. Commonly supported values are `Dark`, `Light`, and `None` for
|
||||
# auto pick-up. Set this to `None` to use the default theme variant.
|
||||
#decorations_theme_variant: None
|
||||
|
||||
# Resize increments
|
||||
#
|
||||
# Prefer resizing window by discrete steps equal to cell dimensions.
|
||||
#resize_increments: false
|
||||
|
||||
# Make `Option` key behave as `Alt` (macOS only):
|
||||
# - OnlyLeft
|
||||
# - OnlyRight
|
||||
# - Both
|
||||
# - None (default)
|
||||
#option_as_alt: None
|
||||
|
||||
#scrolling:
|
||||
# Maximum number of lines in the scrollback buffer.
|
||||
# Specifying '0' will disable scrolling.
|
||||
#history: 10000
|
||||
|
||||
# Scrolling distance multiplier.
|
||||
#multiplier: 3
|
||||
|
||||
# Font configuration
|
||||
#font:
|
||||
# Normal (roman) font face
|
||||
#normal:
|
||||
# Font family
|
||||
#
|
||||
# Default:
|
||||
# - (macOS) Menlo
|
||||
# - (Linux/BSD) monospace
|
||||
# - (Windows) Consolas
|
||||
#family: monospace
|
||||
|
||||
# The `style` can be specified to pick a specific face.
|
||||
#style: Regular
|
||||
|
||||
# Bold font face
|
||||
#bold:
|
||||
# Font family
|
||||
#
|
||||
# If the bold family is not specified, it will fall back to the
|
||||
# value specified for the normal font.
|
||||
#family: monospace
|
||||
|
||||
# The `style` can be specified to pick a specific face.
|
||||
#style: Bold
|
||||
|
||||
# Italic font face
|
||||
#italic:
|
||||
# Font family
|
||||
#
|
||||
# If the italic family is not specified, it will fall back to the
|
||||
# value specified for the normal font.
|
||||
#family: monospace
|
||||
|
||||
# The `style` can be specified to pick a specific face.
|
||||
#style: Italic
|
||||
|
||||
# Bold italic font face
|
||||
#bold_italic:
|
||||
# Font family
|
||||
#
|
||||
# If the bold italic family is not specified, it will fall back to the
|
||||
# value specified for the normal font.
|
||||
#family: monospace
|
||||
|
||||
# The `style` can be specified to pick a specific face.
|
||||
#style: Bold Italic
|
||||
|
||||
# Point size
|
||||
#size: 11.0
|
||||
|
||||
# Offset is the extra space around each character. `offset.y` can be thought
|
||||
# of as modifying the line spacing, and `offset.x` as modifying the letter
|
||||
# spacing.
|
||||
#offset:
|
||||
# x: 0
|
||||
# y: 0
|
||||
|
||||
# Glyph offset determines the locations of the glyphs within their cells with
|
||||
# the default being at the bottom. Increasing `x` moves the glyph to the
|
||||
# right, increasing `y` moves the glyph upward.
|
||||
#glyph_offset:
|
||||
# x: 0
|
||||
# y: 0
|
||||
|
||||
# Use built-in font for box drawing characters.
|
||||
#
|
||||
# If `true`, Alacritty will use a custom built-in font for box drawing
|
||||
# characters (Unicode points 2500 - 259f).
|
||||
#
|
||||
#builtin_box_drawing: true
|
||||
|
||||
# If `true`, bold text is drawn using the bright color variants.
|
||||
#draw_bold_text_with_bright_colors: false
|
||||
|
||||
# Colors (Tomorrow Night)
|
||||
colors:
|
||||
# Default colors
|
||||
primary:
|
||||
# background: '#1d1f21'
|
||||
background: '#0c0c0c'
|
||||
# foreground: '#c5c8c6'
|
||||
|
||||
# Bright and dim foreground colors
|
||||
#
|
||||
# The dimmed foreground color is calculated automatically if it is not
|
||||
# present. If the bright foreground color is not set, or
|
||||
# `draw_bold_text_with_bright_colors` is `false`, the normal foreground
|
||||
# color will be used.
|
||||
#dim_foreground: '#828482'
|
||||
#bright_foreground: '#eaeaea'
|
||||
|
||||
# Cursor colors
|
||||
#
|
||||
# Colors which should be used to draw the terminal cursor.
|
||||
#
|
||||
# Allowed values are CellForeground/CellBackground, which reference the
|
||||
# affected cell, or hexadecimal colors like #ff00ff.
|
||||
#cursor:
|
||||
# text: CellBackground
|
||||
# cursor: CellForeground
|
||||
|
||||
# Vi mode cursor colors
|
||||
#
|
||||
# Colors for the cursor when the vi mode is active.
|
||||
#
|
||||
# Allowed values are CellForeground/CellBackground, which reference the
|
||||
# affected cell, or hexadecimal colors like #ff00ff.
|
||||
#vi_mode_cursor:
|
||||
# text: CellBackground
|
||||
# cursor: CellForeground
|
||||
|
||||
# Search colors
|
||||
#
|
||||
# Colors used for the search bar and match highlighting.
|
||||
#search:
|
||||
# Allowed values are CellForeground/CellBackground, which reference the
|
||||
# affected cell, or hexadecimal colors like #ff00ff.
|
||||
#matches:
|
||||
# foreground: '#000000'
|
||||
# background: '#ffffff'
|
||||
#focused_match:
|
||||
# foreground: '#ffffff'
|
||||
# background: '#000000'
|
||||
|
||||
# Keyboard hints
|
||||
#hints:
|
||||
# First character in the hint label
|
||||
#
|
||||
# Allowed values are CellForeground/CellBackground, which reference the
|
||||
# affected cell, or hexadecimal colors like #ff00ff.
|
||||
#start:
|
||||
# foreground: '#1d1f21'
|
||||
# background: '#e9ff5e'
|
||||
|
||||
# All characters after the first one in the hint label
|
||||
#
|
||||
# Allowed values are CellForeground/CellBackground, which reference the
|
||||
# affected cell, or hexadecimal colors like #ff00ff.
|
||||
#end:
|
||||
# foreground: '#e9ff5e'
|
||||
# background: '#1d1f21'
|
||||
|
||||
# Line indicator
|
||||
#
|
||||
# Color used for the indicator displaying the position in history during
|
||||
# search and vi mode.
|
||||
#
|
||||
# By default, these will use the opposing primary color.
|
||||
#line_indicator:
|
||||
# foreground: None
|
||||
# background: None
|
||||
|
||||
# Footer bar
|
||||
#
|
||||
# Color used for the footer bar on the bottom, used by search regex input,
|
||||
# hyperlink URI preview, etc.
|
||||
#
|
||||
#footer_bar:
|
||||
# background: '#c5c8c6'
|
||||
# foreground: '#1d1f21'
|
||||
|
||||
# Selection colors
|
||||
#
|
||||
# Colors which should be used to draw the selection area.
|
||||
#
|
||||
# Allowed values are CellForeground/CellBackground, which reference the
|
||||
# affected cell, or hexadecimal colors like #ff00ff.
|
||||
#selection:
|
||||
# text: CellBackground
|
||||
# background: CellForeground
|
||||
|
||||
# Normal colors
|
||||
#normal:
|
||||
# black: '#1d1f21'
|
||||
# red: '#cc6666'
|
||||
# green: '#b5bd68'
|
||||
# yellow: '#f0c674'
|
||||
# blue: '#81a2be'
|
||||
# magenta: '#b294bb'
|
||||
# cyan: '#8abeb7'
|
||||
# white: '#c5c8c6'
|
||||
|
||||
# Bright colors
|
||||
#bright:
|
||||
# black: '#666666'
|
||||
# red: '#d54e53'
|
||||
# green: '#b9ca4a'
|
||||
# yellow: '#e7c547'
|
||||
# blue: '#7aa6da'
|
||||
# magenta: '#c397d8'
|
||||
# cyan: '#70c0b1'
|
||||
# white: '#eaeaea'
|
||||
|
||||
# Dim colors
|
||||
#
|
||||
# If the dim colors are not set, they will be calculated automatically based
|
||||
# on the `normal` colors.
|
||||
#dim:
|
||||
# black: '#131415'
|
||||
# red: '#864343'
|
||||
# green: '#777c44'
|
||||
# yellow: '#9e824c'
|
||||
# blue: '#556a7d'
|
||||
# magenta: '#75617b'
|
||||
# cyan: '#5b7d78'
|
||||
# white: '#828482'
|
||||
|
||||
# Indexed Colors
|
||||
#
|
||||
# The indexed colors include all colors from 16 to 256.
|
||||
# When these are not set, they're filled with sensible defaults.
|
||||
#
|
||||
# Example:
|
||||
# `- { index: 16, color: '#ff00ff' }`
|
||||
#
|
||||
#indexed_colors: []
|
||||
|
||||
# Transparent cell backgrounds
|
||||
#
|
||||
# Whether or not `window.opacity` applies to all cell backgrounds or only to
|
||||
# the default background. When set to `true` all cells will be transparent
|
||||
# regardless of their background color.
|
||||
#transparent_background_colors: false
|
||||
|
||||
# Bell
|
||||
#
|
||||
# The bell is rung every time the BEL control character is received.
|
||||
#bell:
|
||||
# Visual Bell Animation
|
||||
#
|
||||
# Animation effect for flashing the screen when the visual bell is rung.
|
||||
#
|
||||
# Values for `animation`:
|
||||
# - Ease
|
||||
# - EaseOut
|
||||
# - EaseOutSine
|
||||
# - EaseOutQuad
|
||||
# - EaseOutCubic
|
||||
# - EaseOutQuart
|
||||
# - EaseOutQuint
|
||||
# - EaseOutExpo
|
||||
# - EaseOutCirc
|
||||
# - Linear
|
||||
#animation: EaseOutExpo
|
||||
|
||||
# Duration of the visual bell flash in milliseconds. A `duration` of `0` will
|
||||
# disable the visual bell animation.
|
||||
#duration: 0
|
||||
|
||||
# Visual bell animation color.
|
||||
#color: '#ffffff'
|
||||
|
||||
# Bell Command
|
||||
#
|
||||
# This program is executed whenever the bell is rung.
|
||||
#
|
||||
# When set to `command: None`, no command will be executed.
|
||||
#
|
||||
# Example:
|
||||
# command:
|
||||
# program: notify-send
|
||||
# args: ["Hello, World!"]
|
||||
#
|
||||
#command: None
|
||||
|
||||
#selection:
|
||||
# This string contains all characters that are used as separators for
|
||||
# "semantic words" in Alacritty.
|
||||
#semantic_escape_chars: ",│`|:\"' ()[]{}<>\t"
|
||||
|
||||
# When set to `true`, selected text will be copied to the primary clipboard.
|
||||
#save_to_clipboard: false
|
||||
|
||||
#cursor:
|
||||
# Cursor style
|
||||
#style:
|
||||
# Cursor shape
|
||||
#
|
||||
# Values for `shape`:
|
||||
# - ▇ Block
|
||||
# - _ Underline
|
||||
# - | Beam
|
||||
#shape: Block
|
||||
|
||||
# Cursor blinking state
|
||||
#
|
||||
# Values for `blinking`:
|
||||
# - Never: Prevent the cursor from ever blinking
|
||||
# - Off: Disable blinking by default
|
||||
# - On: Enable blinking by default
|
||||
# - Always: Force the cursor to always blink
|
||||
#blinking: Off
|
||||
|
||||
# Vi mode cursor style
|
||||
#
|
||||
# If the vi mode cursor style is `None` or not specified, it will fall back to
|
||||
# the style of the active value of the normal cursor.
|
||||
#
|
||||
# See `cursor.style` for available options.
|
||||
#vi_mode_style: None
|
||||
|
||||
# Cursor blinking interval in milliseconds.
|
||||
#blink_interval: 750
|
||||
|
||||
# Time after which cursor stops blinking, in seconds.
|
||||
#
|
||||
# Specifying '0' will disable timeout for blinking.
|
||||
#blink_timeout: 5
|
||||
|
||||
# If this is `true`, the cursor will be rendered as a hollow box when the
|
||||
# window is not focused.
|
||||
#unfocused_hollow: true
|
||||
|
||||
# Thickness of the cursor relative to the cell width as floating point number
|
||||
# from `0.0` to `1.0`.
|
||||
#thickness: 0.15
|
||||
|
||||
# Live config reload (changes require restart)
|
||||
#live_config_reload: true
|
||||
|
||||
# Shell
|
||||
#
|
||||
# You can set `shell.program` to the path of your favorite shell, e.g.
|
||||
# `/bin/fish`. Entries in `shell.args` are passed unmodified as arguments to the
|
||||
# shell.
|
||||
#
|
||||
# Default:
|
||||
# - (Linux/BSD/macOS) `$SHELL` or the user's login shell, if `$SHELL` is unset
|
||||
# - (Windows) powershell
|
||||
#shell:
|
||||
# program: /bin/bash
|
||||
# args:
|
||||
# - --login
|
||||
|
||||
# Startup directory
|
||||
#
|
||||
# Directory the shell is started in. If this is unset, or `None`, the working
|
||||
# directory of the parent process will be used.
|
||||
#working_directory: None
|
||||
|
||||
# Offer IPC using `alacritty msg` (unix only)
|
||||
#ipc_socket: true
|
||||
|
||||
#mouse:
|
||||
# Click settings
|
||||
#
|
||||
# The `double_click` and `triple_click` settings control the time
|
||||
# alacritty should wait for accepting multiple clicks as one double
|
||||
# or triple click.
|
||||
#double_click: { threshold: 300 }
|
||||
#triple_click: { threshold: 300 }
|
||||
|
||||
# If this is `true`, the cursor is temporarily hidden when typing.
|
||||
#hide_when_typing: false
|
||||
|
||||
# Hints
|
||||
#
|
||||
# Terminal hints can be used to find text or hyperlink in the visible part of
|
||||
# the terminal and pipe it to other applications.
|
||||
#hints:
|
||||
# Keys used for the hint labels.
|
||||
#alphabet: "jfkdls;ahgurieowpq"
|
||||
|
||||
# List with all available hints
|
||||
#
|
||||
# Each hint must have any of `regex` or `hyperlinks` field and either an
|
||||
# `action` or a `command` field. The fields `mouse`, `binding` and
|
||||
# `post_processing` are optional.
|
||||
#
|
||||
# The `hyperlinks` option will cause OSC 8 escape sequence hyperlinks to be
|
||||
# highlighted.
|
||||
#
|
||||
# The fields `command`, `binding.key`, `binding.mods`, `binding.mode` and
|
||||
# `mouse.mods` accept the same values as they do in the `key_bindings` section.
|
||||
#
|
||||
# The `mouse.enabled` field controls if the hint should be underlined while
|
||||
# the mouse with all `mouse.mods` keys held or the vi mode cursor is above it.
|
||||
#
|
||||
# If the `post_processing` field is set to `true`, heuristics will be used to
|
||||
# shorten the match if there are characters likely not to be part of the hint
|
||||
# (e.g. a trailing `.`). This is most useful for URIs and applies only to
|
||||
# `regex` matches.
|
||||
#
|
||||
# Values for `action`:
|
||||
# - Copy
|
||||
# Copy the hint's text to the clipboard.
|
||||
# - Paste
|
||||
# Paste the hint's text to the terminal or search.
|
||||
# - Select
|
||||
# Select the hint's text.
|
||||
# - MoveViModeCursor
|
||||
# Move the vi mode cursor to the beginning of the hint.
|
||||
#enabled:
|
||||
# - regex: "(ipfs:|ipns:|magnet:|mailto:|gemini:|gopher:|https:|http:|news:|file:|git:|ssh:|ftp:)\
|
||||
# [^\u0000-\u001F\u007F-\u009F<>\"\\s{-}\\^⟨⟩`]+"
|
||||
# hyperlinks: true
|
||||
# command: xdg-open
|
||||
# post_processing: true
|
||||
# mouse:
|
||||
# enabled: true
|
||||
# mods: None
|
||||
# binding:
|
||||
# key: U
|
||||
# mods: Control|Shift
|
||||
|
||||
# Mouse bindings
|
||||
#
|
||||
# Mouse bindings are specified as a list of objects, much like the key
|
||||
# bindings further below.
|
||||
#
|
||||
# To trigger mouse bindings when an application running within Alacritty
|
||||
# captures the mouse, the `Shift` modifier is automatically added as a
|
||||
# requirement.
|
||||
#
|
||||
# Each mouse binding will specify a:
|
||||
#
|
||||
# - `mouse`:
|
||||
#
|
||||
# - Middle
|
||||
# - Left
|
||||
# - Right
|
||||
# - Numeric identifier such as `5`
|
||||
#
|
||||
# - `action` (see key bindings for actions not exclusive to mouse mode)
|
||||
#
|
||||
# - Mouse exclusive actions:
|
||||
#
|
||||
# - ExpandSelection
|
||||
# Expand the selection to the current mouse cursor location.
|
||||
#
|
||||
# And optionally:
|
||||
#
|
||||
# - `mods` (see key bindings)
|
||||
#mouse_bindings:
|
||||
# - { mouse: Right, action: ExpandSelection }
|
||||
# - { mouse: Right, mods: Control, action: ExpandSelection }
|
||||
# - { mouse: Middle, mode: ~Vi, action: PasteSelection }
|
||||
|
||||
# Key bindings
|
||||
#
|
||||
# Key bindings are specified as a list of objects. For example, this is the
|
||||
# default paste binding:
|
||||
#
|
||||
# `- { key: V, mods: Control|Shift, action: Paste }`
|
||||
#
|
||||
# Each key binding will specify a:
|
||||
#
|
||||
# - `key`: Identifier of the key pressed
|
||||
#
|
||||
# - A-Z
|
||||
# - F1-F24
|
||||
# - Key0-Key9
|
||||
#
|
||||
# A full list with available key codes can be found here:
|
||||
# https://docs.rs/winit/*/winit/event/enum.VirtualKeyCode.html#variants
|
||||
#
|
||||
# Instead of using the name of the keys, the `key` field also supports using
|
||||
# the scancode of the desired key. Scancodes have to be specified as a
|
||||
# decimal number. This command will allow you to display the hex scancodes
|
||||
# for certain keys:
|
||||
#
|
||||
# `showkey --scancodes`.
|
||||
#
|
||||
# Then exactly one of:
|
||||
#
|
||||
# - `chars`: Send a byte sequence to the running application
|
||||
#
|
||||
# The `chars` field writes the specified string to the terminal. This makes
|
||||
# it possible to pass escape sequences. To find escape codes for bindings
|
||||
# like `PageUp` (`"\x1b[5~"`), you can run the command `showkey -a` outside
|
||||
# of tmux. Note that applications use terminfo to map escape sequences back
|
||||
# to keys. It is therefore required to update the terminfo when changing an
|
||||
# escape sequence.
|
||||
#
|
||||
# - `action`: Execute a predefined action
|
||||
#
|
||||
# - ToggleViMode
|
||||
# - SearchForward
|
||||
# Start searching toward the right of the search origin.
|
||||
# - SearchBackward
|
||||
# Start searching toward the left of the search origin.
|
||||
# - Copy
|
||||
# - Paste
|
||||
# - IncreaseFontSize
|
||||
# - DecreaseFontSize
|
||||
# - ResetFontSize
|
||||
# - ScrollPageUp
|
||||
# - ScrollPageDown
|
||||
# - ScrollHalfPageUp
|
||||
# - ScrollHalfPageDown
|
||||
# - ScrollLineUp
|
||||
# - ScrollLineDown
|
||||
# - ScrollToTop
|
||||
# - ScrollToBottom
|
||||
# - ClearHistory
|
||||
# Remove the terminal's scrollback history.
|
||||
# - Hide
|
||||
# Hide the Alacritty window.
|
||||
# - Minimize
|
||||
# Minimize the Alacritty window.
|
||||
# - Quit
|
||||
# Quit Alacritty.
|
||||
# - ToggleFullscreen
|
||||
# - ToggleMaximized
|
||||
# - SpawnNewInstance
|
||||
# Spawn a new instance of Alacritty.
|
||||
# - CreateNewWindow
|
||||
# Create a new Alacritty window from the current process.
|
||||
# - ClearLogNotice
|
||||
# Clear Alacritty's UI warning and error notice.
|
||||
# - ClearSelection
|
||||
# Remove the active selection.
|
||||
# - ReceiveChar
|
||||
# - None
|
||||
#
|
||||
# - Vi mode exclusive actions:
|
||||
#
|
||||
# - Open
|
||||
# Perform the action of the first matching hint under the vi mode cursor
|
||||
# with `mouse.enabled` set to `true`.
|
||||
# - ToggleNormalSelection
|
||||
# - ToggleLineSelection
|
||||
# - ToggleBlockSelection
|
||||
# - ToggleSemanticSelection
|
||||
# Toggle semantic selection based on `selection.semantic_escape_chars`.
|
||||
# - CenterAroundViCursor
|
||||
# Center view around vi mode cursor
|
||||
#
|
||||
# - Vi mode exclusive cursor motion actions:
|
||||
#
|
||||
# - Up
|
||||
# One line up.
|
||||
# - Down
|
||||
# One line down.
|
||||
# - Left
|
||||
# One character left.
|
||||
# - Right
|
||||
# One character right.
|
||||
# - First
|
||||
# First column, or beginning of the line when already at the first column.
|
||||
# - Last
|
||||
# Last column, or beginning of the line when already at the last column.
|
||||
# - FirstOccupied
|
||||
# First non-empty cell in this terminal row, or first non-empty cell of
|
||||
# the line when already at the first cell of the row.
|
||||
# - High
|
||||
# Top of the screen.
|
||||
# - Middle
|
||||
# Center of the screen.
|
||||
# - Low
|
||||
# Bottom of the screen.
|
||||
# - SemanticLeft
|
||||
# Start of the previous semantically separated word.
|
||||
# - SemanticRight
|
||||
# Start of the next semantically separated word.
|
||||
# - SemanticLeftEnd
|
||||
# End of the previous semantically separated word.
|
||||
# - SemanticRightEnd
|
||||
# End of the next semantically separated word.
|
||||
# - WordLeft
|
||||
# Start of the previous whitespace separated word.
|
||||
# - WordRight
|
||||
# Start of the next whitespace separated word.
|
||||
# - WordLeftEnd
|
||||
# End of the previous whitespace separated word.
|
||||
# - WordRightEnd
|
||||
# End of the next whitespace separated word.
|
||||
# - Bracket
|
||||
# Character matching the bracket at the cursor's location.
|
||||
# - SearchNext
|
||||
# Beginning of the next match.
|
||||
# - SearchPrevious
|
||||
# Beginning of the previous match.
|
||||
# - SearchStart
|
||||
# Start of the match to the left of the vi mode cursor.
|
||||
# - SearchEnd
|
||||
# End of the match to the right of the vi mode cursor.
|
||||
#
|
||||
# - Search mode exclusive actions:
|
||||
# - SearchFocusNext
|
||||
# Move the focus to the next search match.
|
||||
# - SearchFocusPrevious
|
||||
# Move the focus to the previous search match.
|
||||
# - SearchConfirm
|
||||
# - SearchCancel
|
||||
# - SearchClear
|
||||
# Reset the search regex.
|
||||
# - SearchDeleteWord
|
||||
# Delete the last word in the search regex.
|
||||
# - SearchHistoryPrevious
|
||||
# Go to the previous regex in the search history.
|
||||
# - SearchHistoryNext
|
||||
# Go to the next regex in the search history.
|
||||
#
|
||||
# - macOS exclusive actions:
|
||||
# - ToggleSimpleFullscreen
|
||||
# Enter fullscreen without occupying another space.
|
||||
#
|
||||
# - Linux/BSD exclusive actions:
|
||||
#
|
||||
# - CopySelection
|
||||
# Copy from the selection buffer.
|
||||
# - PasteSelection
|
||||
# Paste from the selection buffer.
|
||||
#
|
||||
# - `command`: Fork and execute a specified command plus arguments
|
||||
#
|
||||
# The `command` field must be a map containing a `program` string and an
|
||||
# `args` array of command line parameter strings. For example:
|
||||
# `{ program: "alacritty", args: ["-e", "vttest"] }`
|
||||
#
|
||||
# And optionally:
|
||||
#
|
||||
# - `mods`: Key modifiers to filter binding actions
|
||||
#
|
||||
# - Command
|
||||
# - Control
|
||||
# - Option
|
||||
# - Super
|
||||
# - Shift
|
||||
# - Alt
|
||||
#
|
||||
# Multiple `mods` can be combined using `|` like this:
|
||||
# `mods: Control|Shift`.
|
||||
# Whitespace and capitalization are relevant and must match the example.
|
||||
#
|
||||
# - `mode`: Indicate a binding for only specific terminal reported modes
|
||||
#
|
||||
# This is mainly used to send applications the correct escape sequences
|
||||
# when in different modes.
|
||||
#
|
||||
# - AppCursor
|
||||
# - AppKeypad
|
||||
# - Search
|
||||
# - Alt
|
||||
# - Vi
|
||||
#
|
||||
# A `~` operator can be used before a mode to apply the binding whenever
|
||||
# the mode is *not* active, e.g. `~Alt`.
|
||||
#
|
||||
# Bindings are always filled by default, but will be replaced when a new
|
||||
# binding with the same triggers is defined. To unset a default binding, it can
|
||||
# be mapped to the `ReceiveChar` action. Alternatively, you can use `None` for
|
||||
# a no-op if you do not wish to receive input characters for that binding.
|
||||
#
|
||||
# If the same trigger is assigned to multiple actions, all of them are executed
|
||||
# in the order they were defined in.
|
||||
#key_bindings:
|
||||
#- { key: Paste, action: Paste }
|
||||
#- { key: Copy, action: Copy }
|
||||
#- { key: L, mods: Control, action: ClearLogNotice }
|
||||
#- { key: L, mods: Control, mode: ~Vi|~Search, chars: "\x0c" }
|
||||
#- { key: PageUp, mods: Shift, mode: ~Alt, action: ScrollPageUp }
|
||||
#- { key: PageDown, mods: Shift, mode: ~Alt, action: ScrollPageDown }
|
||||
#- { key: Home, mods: Shift, mode: ~Alt, action: ScrollToTop }
|
||||
#- { key: End, mods: Shift, mode: ~Alt, action: ScrollToBottom }
|
||||
|
||||
# Vi Mode
|
||||
#- { key: Space, mods: Shift|Control, mode: ~Search, action: ToggleViMode }
|
||||
#- { key: Space, mods: Shift|Control, mode: Vi|~Search, action: ScrollToBottom }
|
||||
#- { key: Escape, mode: Vi|~Search, action: ClearSelection }
|
||||
#- { key: I, mode: Vi|~Search, action: ToggleViMode }
|
||||
#- { key: I, mode: Vi|~Search, action: ScrollToBottom }
|
||||
#- { key: C, mods: Control, mode: Vi|~Search, action: ToggleViMode }
|
||||
#- { key: Y, mods: Control, mode: Vi|~Search, action: ScrollLineUp }
|
||||
#- { key: E, mods: Control, mode: Vi|~Search, action: ScrollLineDown }
|
||||
#- { key: G, mode: Vi|~Search, action: ScrollToTop }
|
||||
#- { key: G, mods: Shift, mode: Vi|~Search, action: ScrollToBottom }
|
||||
#- { key: B, mods: Control, mode: Vi|~Search, action: ScrollPageUp }
|
||||
#- { key: F, mods: Control, mode: Vi|~Search, action: ScrollPageDown }
|
||||
#- { key: U, mods: Control, mode: Vi|~Search, action: ScrollHalfPageUp }
|
||||
#- { key: D, mods: Control, mode: Vi|~Search, action: ScrollHalfPageDown }
|
||||
#- { key: Y, mode: Vi|~Search, action: Copy }
|
||||
#- { key: Y, mode: Vi|~Search, action: ClearSelection }
|
||||
#- { key: Copy, mode: Vi|~Search, action: ClearSelection }
|
||||
#- { key: V, mode: Vi|~Search, action: ToggleNormalSelection }
|
||||
#- { key: V, mods: Shift, mode: Vi|~Search, action: ToggleLineSelection }
|
||||
#- { key: V, mods: Control, mode: Vi|~Search, action: ToggleBlockSelection }
|
||||
#- { key: V, mods: Alt, mode: Vi|~Search, action: ToggleSemanticSelection }
|
||||
#- { key: Return, mode: Vi|~Search, action: Open }
|
||||
#- { key: Z, mode: Vi|~Search, action: CenterAroundViCursor }
|
||||
#- { key: K, mode: Vi|~Search, action: Up }
|
||||
#- { key: J, mode: Vi|~Search, action: Down }
|
||||
#- { key: H, mode: Vi|~Search, action: Left }
|
||||
#- { key: L, mode: Vi|~Search, action: Right }
|
||||
#- { key: Up, mode: Vi|~Search, action: Up }
|
||||
#- { key: Down, mode: Vi|~Search, action: Down }
|
||||
#- { key: Left, mode: Vi|~Search, action: Left }
|
||||
#- { key: Right, mode: Vi|~Search, action: Right }
|
||||
#- { key: Key0, mode: Vi|~Search, action: First }
|
||||
#- { key: Key4, mods: Shift, mode: Vi|~Search, action: Last }
|
||||
#- { key: Key6, mods: Shift, mode: Vi|~Search, action: FirstOccupied }
|
||||
#- { key: H, mods: Shift, mode: Vi|~Search, action: High }
|
||||
#- { key: M, mods: Shift, mode: Vi|~Search, action: Middle }
|
||||
#- { key: L, mods: Shift, mode: Vi|~Search, action: Low }
|
||||
#- { key: B, mode: Vi|~Search, action: SemanticLeft }
|
||||
#- { key: W, mode: Vi|~Search, action: SemanticRight }
|
||||
#- { key: E, mode: Vi|~Search, action: SemanticRightEnd }
|
||||
#- { key: B, mods: Shift, mode: Vi|~Search, action: WordLeft }
|
||||
#- { key: W, mods: Shift, mode: Vi|~Search, action: WordRight }
|
||||
#- { key: E, mods: Shift, mode: Vi|~Search, action: WordRightEnd }
|
||||
#- { key: Key5, mods: Shift, mode: Vi|~Search, action: Bracket }
|
||||
#- { key: Slash, mode: Vi|~Search, action: SearchForward }
|
||||
#- { key: Slash, mods: Shift, mode: Vi|~Search, action: SearchBackward }
|
||||
#- { key: N, mode: Vi|~Search, action: SearchNext }
|
||||
#- { key: N, mods: Shift, mode: Vi|~Search, action: SearchPrevious }
|
||||
|
||||
# Search Mode
|
||||
#- { key: Return, mode: Search|Vi, action: SearchConfirm }
|
||||
#- { key: Escape, mode: Search, action: SearchCancel }
|
||||
#- { key: C, mods: Control, mode: Search, action: SearchCancel }
|
||||
#- { key: U, mods: Control, mode: Search, action: SearchClear }
|
||||
#- { key: W, mods: Control, mode: Search, action: SearchDeleteWord }
|
||||
#- { key: P, mods: Control, mode: Search, action: SearchHistoryPrevious }
|
||||
#- { key: N, mods: Control, mode: Search, action: SearchHistoryNext }
|
||||
#- { key: Up, mode: Search, action: SearchHistoryPrevious }
|
||||
#- { key: Down, mode: Search, action: SearchHistoryNext }
|
||||
#- { key: Return, mode: Search|~Vi, action: SearchFocusNext }
|
||||
#- { key: Return, mods: Shift, mode: Search|~Vi, action: SearchFocusPrevious }
|
||||
|
||||
# (Windows, Linux, and BSD only)
|
||||
#- { key: V, mods: Control|Shift, mode: ~Vi, action: Paste }
|
||||
#- { key: C, mods: Control|Shift, action: Copy }
|
||||
#- { key: F, mods: Control|Shift, mode: ~Search, action: SearchForward }
|
||||
#- { key: B, mods: Control|Shift, mode: ~Search, action: SearchBackward }
|
||||
#- { key: C, mods: Control|Shift, mode: Vi|~Search, action: ClearSelection }
|
||||
#- { key: Insert, mods: Shift, action: PasteSelection }
|
||||
#- { key: Key0, mods: Control, action: ResetFontSize }
|
||||
#- { key: Equals, mods: Control, action: IncreaseFontSize }
|
||||
#- { key: Plus, mods: Control, action: IncreaseFontSize }
|
||||
#- { key: NumpadAdd, mods: Control, action: IncreaseFontSize }
|
||||
#- { key: Minus, mods: Control, action: DecreaseFontSize }
|
||||
#- { key: NumpadSubtract, mods: Control, action: DecreaseFontSize }
|
||||
|
||||
# (Windows only)
|
||||
#- { key: Return, mods: Alt, action: ToggleFullscreen }
|
||||
|
||||
# (macOS only)
|
||||
#- { key: K, mods: Command, mode: ~Vi|~Search, chars: "\x0c" }
|
||||
#- { key: K, mods: Command, mode: ~Vi|~Search, action: ClearHistory }
|
||||
#- { key: Key0, mods: Command, action: ResetFontSize }
|
||||
#- { key: Equals, mods: Command, action: IncreaseFontSize }
|
||||
#- { key: Plus, mods: Command, action: IncreaseFontSize }
|
||||
#- { key: NumpadAdd, mods: Command, action: IncreaseFontSize }
|
||||
#- { key: Minus, mods: Command, action: DecreaseFontSize }
|
||||
#- { key: NumpadSubtract, mods: Command, action: DecreaseFontSize }
|
||||
#- { key: V, mods: Command, action: Paste }
|
||||
#- { key: C, mods: Command, action: Copy }
|
||||
#- { key: C, mods: Command, mode: Vi|~Search, action: ClearSelection }
|
||||
#- { key: H, mods: Command, action: Hide }
|
||||
#- { key: H, mods: Command|Alt, action: HideOtherApplications }
|
||||
#- { key: M, mods: Command, action: Minimize }
|
||||
#- { key: Q, mods: Command, action: Quit }
|
||||
#- { key: W, mods: Command, action: Quit }
|
||||
#- { key: N, mods: Command, action: CreateNewWindow }
|
||||
#- { key: F, mods: Command|Control, action: ToggleFullscreen }
|
||||
#- { key: F, mods: Command, mode: ~Search, action: SearchForward }
|
||||
#- { key: B, mods: Command, mode: ~Search, action: SearchBackward }
|
||||
|
||||
#debug:
|
||||
# Display the time it takes to redraw each frame.
|
||||
#render_timer: false
|
||||
|
||||
# Keep the log file after quitting Alacritty.
|
||||
#persistent_logging: false
|
||||
|
||||
# Log level
|
||||
#
|
||||
# Values for `log_level`:
|
||||
# - Off
|
||||
# - Error
|
||||
# - Warn
|
||||
# - Info
|
||||
# - Debug
|
||||
# - Trace
|
||||
#log_level: Warn
|
||||
|
||||
# Renderer override.
|
||||
# - glsl3
|
||||
# - gles2
|
||||
# - gles2_pure
|
||||
#renderer: None
|
||||
|
||||
# Print all received window events.
|
||||
#print_events: false
|
||||
|
||||
# Highlight window damage information.
|
||||
#highlight_damage: false
|
||||
|
||||
import:
|
||||
# uncomment the flavour you want below:
|
||||
- ~/.config/alacritty/catppuccin/catppuccin-mocha.yml
|
||||
# - ~/.config/alacritty/catppuccin/catppuccin-macchiato.yml
|
||||
# - ~/.config/alacritty/catppuccin/catppuccin-frappe.yml
|
||||
# - ~/.config/alacritty/catppuccin/catppuccin-latte.yml
|
1
alacritty/catppuccin
Submodule
1
alacritty/catppuccin
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 3c808cbb4f9c87be43ba5241bc57373c793d2f17
|
|
@ -1,14 +0,0 @@
|
|||
# Apps
|
||||
|
||||
This directory contains every derivations for apps exposed by this flake.
|
||||
|
||||
## List of my apps found in `self.apps`
|
||||
|
||||
| Name | Description |
|
||||
| ---- | ----------- |
|
||||
| `extract-subs` | Extract all `srt` subtitle files from a `mkv` video with the appropriate name. |
|
||||
| `gen-docs` | Generates the READMEs in this repository from nix attributes. |
|
||||
| `list2series` | Converts a Komga read list into a comics series for reading with mihon. |
|
||||
| `mc-mods` | Checks if a list of mods have a version available for a specific Minecraft version and a specific loader. |
|
||||
| `pin-inputs` | Takes a list of inputs to pin to their current rev in `flake.lock`. |
|
||||
| `update-sources` | Updates all derivation sources in this repository and generates a commit message for the changes made. |
|
|
@ -1,61 +0,0 @@
|
|||
{
|
||||
lib,
|
||||
src,
|
||||
npmDepsHash,
|
||||
runtimeInputs,
|
||||
buildNpmPackage,
|
||||
meta,
|
||||
makeWrapper,
|
||||
nodejs_latest,
|
||||
jq,
|
||||
...
|
||||
}: let
|
||||
inherit (lib) boolToString concatMapStringsSep concatStringsSep mapAttrsToList;
|
||||
inherit (builtins) fromJSON isBool readFile;
|
||||
|
||||
packageJSON = fromJSON (readFile "${src}/package.json");
|
||||
tsconfig = fromJSON (readFile ./config/tsconfig.base.json);
|
||||
|
||||
pname = packageJSON.name;
|
||||
inherit (packageJSON) version;
|
||||
in
|
||||
buildNpmPackage {
|
||||
inherit pname version src runtimeInputs npmDepsHash;
|
||||
|
||||
prePatch = ''
|
||||
# Patch tsconfig
|
||||
mv ./tsconfig.json ./project.json
|
||||
sed 's/^ *\/\/.*//' ${./config/tsconfig.base.json} > ./base.json
|
||||
${jq}/bin/jq -sr '.[0] * .[1] | del(.extends)' ./project.json ./base.json > ./tsconfig.json
|
||||
rm base.json project.json
|
||||
'';
|
||||
|
||||
nativeBuildInputs = [makeWrapper];
|
||||
|
||||
postInstall = ''
|
||||
wrapProgram $out/bin/${pname} \
|
||||
--prefix PATH : ${concatMapStringsSep ":" (p: p + "/bin") runtimeInputs}
|
||||
'';
|
||||
|
||||
doCheck = true;
|
||||
|
||||
checkPhase = ''
|
||||
runHook preCheck
|
||||
|
||||
npx tsc ${concatStringsSep " " (mapAttrsToList (n: v:
|
||||
if n == "lib"
|
||||
then concatMapStringsSep " " (x: "--lib ${x}") v
|
||||
else "--${n} ${
|
||||
if isBool v
|
||||
then boolToString v
|
||||
else toString v
|
||||
}")
|
||||
tsconfig.compilerOptions)} src/app.ts
|
||||
|
||||
runHook postCheck
|
||||
'';
|
||||
|
||||
nodejs = nodejs_latest;
|
||||
|
||||
meta = {mainProgram = pname;} // meta;
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
use flake $FLAKE#node
|
||||
npm ci
|
|
@ -1,451 +0,0 @@
|
|||
import eslint from '@eslint/js';
|
||||
import jsdoc from 'eslint-plugin-jsdoc';
|
||||
import stylistic from '@stylistic/eslint-plugin';
|
||||
import tseslint from 'typescript-eslint';
|
||||
|
||||
|
||||
export default tseslint.config({
|
||||
files: ['**/*.js', '**/*.ts'],
|
||||
ignores: ['node_modules/**', 'types/**'],
|
||||
|
||||
extends: [
|
||||
eslint.configs.recommended,
|
||||
jsdoc.configs['flat/recommended-typescript'],
|
||||
stylistic.configs['recommended-flat'],
|
||||
...tseslint.configs.recommended,
|
||||
...tseslint.configs.stylistic,
|
||||
],
|
||||
|
||||
rules: {
|
||||
// JSDoc settings
|
||||
'jsdoc/tag-lines': ['warn', 'any', { startLines: 1 }],
|
||||
'jsdoc/check-line-alignment': ['warn', 'always', {
|
||||
tags: ['param', 'arg', 'argument', 'property', 'prop'],
|
||||
}],
|
||||
'jsdoc/no-types': 'off',
|
||||
|
||||
// Newer settings
|
||||
'@typescript-eslint/no-extraneous-class': ['off'],
|
||||
'@typescript-eslint/no-implied-eval': ['off'],
|
||||
'class-methods-use-this': 'off',
|
||||
'@stylistic/no-multiple-empty-lines': 'off',
|
||||
|
||||
// Pre-flat config
|
||||
'@typescript-eslint/no-unused-vars': [
|
||||
'error',
|
||||
{
|
||||
args: 'all',
|
||||
argsIgnorePattern: '^_',
|
||||
caughtErrors: 'all',
|
||||
caughtErrorsIgnorePattern: '^_',
|
||||
destructuredArrayIgnorePattern: '^_',
|
||||
varsIgnorePattern: '^_',
|
||||
ignoreRestSiblings: true,
|
||||
},
|
||||
],
|
||||
|
||||
'array-callback-return': [
|
||||
'error',
|
||||
{
|
||||
allowImplicit: true,
|
||||
checkForEach: true,
|
||||
},
|
||||
],
|
||||
'no-constructor-return': [
|
||||
'error',
|
||||
],
|
||||
'no-unreachable-loop': [
|
||||
'error',
|
||||
{
|
||||
ignore: [
|
||||
'ForInStatement',
|
||||
'ForOfStatement',
|
||||
],
|
||||
},
|
||||
],
|
||||
'no-use-before-define': [
|
||||
'error',
|
||||
{
|
||||
functions: false,
|
||||
},
|
||||
],
|
||||
'block-scoped-var': [
|
||||
'error',
|
||||
],
|
||||
'curly': [
|
||||
'warn',
|
||||
],
|
||||
'default-case-last': [
|
||||
'warn',
|
||||
],
|
||||
'default-param-last': [
|
||||
'error',
|
||||
],
|
||||
'eqeqeq': [
|
||||
'error',
|
||||
'smart',
|
||||
],
|
||||
'func-names': [
|
||||
'warn',
|
||||
'never',
|
||||
],
|
||||
'func-style': [
|
||||
'warn',
|
||||
'expression',
|
||||
],
|
||||
'logical-assignment-operators': [
|
||||
'warn',
|
||||
'always',
|
||||
],
|
||||
'no-array-constructor': [
|
||||
'error',
|
||||
],
|
||||
'no-empty-function': [
|
||||
'warn',
|
||||
],
|
||||
'no-empty-static-block': [
|
||||
'warn',
|
||||
],
|
||||
'no-extend-native': [
|
||||
'error',
|
||||
],
|
||||
'no-extra-bind': [
|
||||
'warn',
|
||||
],
|
||||
'no-implicit-coercion': [
|
||||
'warn',
|
||||
],
|
||||
'no-iterator': [
|
||||
'error',
|
||||
],
|
||||
'no-labels': [
|
||||
'error',
|
||||
],
|
||||
'no-lone-blocks': [
|
||||
'error',
|
||||
],
|
||||
'no-lonely-if': [
|
||||
'error',
|
||||
],
|
||||
'no-loop-func': [
|
||||
'error',
|
||||
],
|
||||
'no-magic-numbers': [
|
||||
'error',
|
||||
{
|
||||
ignore: [
|
||||
-1,
|
||||
0.1,
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
10,
|
||||
12,
|
||||
33,
|
||||
66,
|
||||
100,
|
||||
255,
|
||||
360,
|
||||
450,
|
||||
500,
|
||||
1000,
|
||||
],
|
||||
ignoreDefaultValues: true,
|
||||
ignoreClassFieldInitialValues: true,
|
||||
},
|
||||
],
|
||||
'no-multi-assign': [
|
||||
'error',
|
||||
],
|
||||
'no-new-wrappers': [
|
||||
'error',
|
||||
],
|
||||
'no-object-constructor': [
|
||||
'error',
|
||||
],
|
||||
'no-proto': [
|
||||
'error',
|
||||
],
|
||||
'no-return-assign': [
|
||||
'error',
|
||||
],
|
||||
'no-sequences': [
|
||||
'error',
|
||||
],
|
||||
'no-shadow': [
|
||||
'error',
|
||||
{
|
||||
builtinGlobals: true,
|
||||
allow: [
|
||||
'Window',
|
||||
],
|
||||
},
|
||||
],
|
||||
'no-undef-init': [
|
||||
'warn',
|
||||
],
|
||||
'no-undefined': [
|
||||
'error',
|
||||
],
|
||||
'no-useless-constructor': [
|
||||
'warn',
|
||||
],
|
||||
'no-useless-escape': [
|
||||
'off',
|
||||
],
|
||||
'no-useless-return': [
|
||||
'error',
|
||||
],
|
||||
'no-var': [
|
||||
'error',
|
||||
],
|
||||
'no-void': [
|
||||
'off',
|
||||
],
|
||||
'no-with': [
|
||||
'error',
|
||||
],
|
||||
'object-shorthand': [
|
||||
'error',
|
||||
'always',
|
||||
],
|
||||
'one-var': [
|
||||
'error',
|
||||
'never',
|
||||
],
|
||||
'operator-assignment': [
|
||||
'warn',
|
||||
'always',
|
||||
],
|
||||
'prefer-arrow-callback': [
|
||||
'error',
|
||||
],
|
||||
'prefer-const': [
|
||||
'error',
|
||||
],
|
||||
'prefer-object-has-own': [
|
||||
'error',
|
||||
],
|
||||
'prefer-regex-literals': [
|
||||
'error',
|
||||
],
|
||||
'prefer-template': [
|
||||
'warn',
|
||||
],
|
||||
'no-prototype-builtins': 'off',
|
||||
'@typescript-eslint/no-var-requires': [
|
||||
'off',
|
||||
],
|
||||
'@stylistic/array-bracket-newline': [
|
||||
'warn',
|
||||
'consistent',
|
||||
],
|
||||
'@stylistic/array-bracket-spacing': [
|
||||
'warn',
|
||||
'never',
|
||||
],
|
||||
'@stylistic/arrow-parens': [
|
||||
'warn',
|
||||
'always',
|
||||
],
|
||||
'@stylistic/brace-style': [
|
||||
'warn',
|
||||
'stroustrup',
|
||||
],
|
||||
'@stylistic/comma-dangle': [
|
||||
'warn',
|
||||
'always-multiline',
|
||||
],
|
||||
'@stylistic/comma-spacing': [
|
||||
'warn',
|
||||
{
|
||||
before: false,
|
||||
after: true,
|
||||
},
|
||||
],
|
||||
'@stylistic/comma-style': [
|
||||
'error',
|
||||
'last',
|
||||
],
|
||||
'@stylistic/dot-location': [
|
||||
'error',
|
||||
'property',
|
||||
],
|
||||
'@stylistic/function-call-argument-newline': [
|
||||
'warn',
|
||||
'consistent',
|
||||
],
|
||||
'@stylistic/function-paren-newline': [
|
||||
'warn',
|
||||
'consistent',
|
||||
],
|
||||
'@stylistic/indent': [
|
||||
'warn',
|
||||
4,
|
||||
{
|
||||
SwitchCase: 1,
|
||||
ignoreComments: true,
|
||||
ignoredNodes: ['TemplateLiteral > *'],
|
||||
},
|
||||
],
|
||||
'@stylistic/key-spacing': [
|
||||
'warn',
|
||||
{
|
||||
beforeColon: false,
|
||||
afterColon: true,
|
||||
},
|
||||
],
|
||||
'@stylistic/keyword-spacing': [
|
||||
'warn',
|
||||
{
|
||||
before: true,
|
||||
},
|
||||
],
|
||||
'@stylistic/linebreak-style': [
|
||||
'error',
|
||||
'unix',
|
||||
],
|
||||
'@stylistic/lines-between-class-members': [
|
||||
'warn',
|
||||
'always',
|
||||
{
|
||||
exceptAfterSingleLine: true,
|
||||
},
|
||||
],
|
||||
'@stylistic/max-len': [
|
||||
'warn',
|
||||
{
|
||||
code: 105,
|
||||
ignoreComments: true,
|
||||
ignoreTrailingComments: true,
|
||||
ignoreUrls: true,
|
||||
},
|
||||
],
|
||||
'@stylistic/multiline-ternary': [
|
||||
'warn',
|
||||
'always-multiline',
|
||||
],
|
||||
'@stylistic/new-parens': [
|
||||
'error',
|
||||
],
|
||||
'@stylistic/no-mixed-operators': [
|
||||
'warn',
|
||||
],
|
||||
'@stylistic/no-mixed-spaces-and-tabs': [
|
||||
'error',
|
||||
],
|
||||
'@stylistic/no-multi-spaces': [
|
||||
'error',
|
||||
],
|
||||
'@stylistic/no-tabs': [
|
||||
'error',
|
||||
],
|
||||
'@stylistic/no-trailing-spaces': [
|
||||
'error',
|
||||
],
|
||||
'@stylistic/no-whitespace-before-property': [
|
||||
'warn',
|
||||
],
|
||||
'@stylistic/nonblock-statement-body-position': [
|
||||
'error',
|
||||
'below',
|
||||
],
|
||||
'@stylistic/object-curly-newline': [
|
||||
'warn',
|
||||
{
|
||||
consistent: true,
|
||||
},
|
||||
],
|
||||
'@stylistic/object-curly-spacing': [
|
||||
'warn',
|
||||
'always',
|
||||
],
|
||||
'@stylistic/operator-linebreak': [
|
||||
'warn',
|
||||
'after',
|
||||
],
|
||||
'@stylistic/padded-blocks': [
|
||||
'error',
|
||||
'never',
|
||||
],
|
||||
'@stylistic/padding-line-between-statements': [
|
||||
'warn',
|
||||
{
|
||||
blankLine: 'always',
|
||||
prev: '*',
|
||||
next: 'return',
|
||||
},
|
||||
{
|
||||
blankLine: 'always',
|
||||
prev: [
|
||||
'const',
|
||||
'let',
|
||||
'var',
|
||||
],
|
||||
next: '*',
|
||||
},
|
||||
{
|
||||
blankLine: 'any',
|
||||
prev: [
|
||||
'const',
|
||||
'let',
|
||||
'var',
|
||||
],
|
||||
next: [
|
||||
'const',
|
||||
'let',
|
||||
'var',
|
||||
],
|
||||
},
|
||||
{
|
||||
blankLine: 'always',
|
||||
prev: [
|
||||
'case',
|
||||
'default',
|
||||
],
|
||||
next: '*',
|
||||
},
|
||||
],
|
||||
'@stylistic/quote-props': [
|
||||
'error',
|
||||
'consistent-as-needed',
|
||||
],
|
||||
'@stylistic/quotes': [
|
||||
'error',
|
||||
'single',
|
||||
{
|
||||
avoidEscape: true,
|
||||
},
|
||||
],
|
||||
'@stylistic/semi': [
|
||||
'error',
|
||||
'always',
|
||||
],
|
||||
'@stylistic/semi-spacing': [
|
||||
'warn',
|
||||
],
|
||||
'@stylistic/space-before-blocks': [
|
||||
'warn',
|
||||
],
|
||||
'@stylistic/space-before-function-paren': [
|
||||
'warn',
|
||||
'never',
|
||||
],
|
||||
'@stylistic/space-infix-ops': [
|
||||
'warn',
|
||||
],
|
||||
'@stylistic/spaced-comment': [
|
||||
'warn',
|
||||
'always',
|
||||
],
|
||||
'@stylistic/switch-colon-spacing': [
|
||||
'warn',
|
||||
],
|
||||
'@stylistic/wrap-regex': [
|
||||
'warn',
|
||||
],
|
||||
},
|
||||
});
|
|
@ -1,3 +0,0 @@
|
|||
import eslintConf from './eslint.config';
|
||||
|
||||
export default eslintConf;
|
1729
apps/config/package-lock.json
generated
1729
apps/config/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -1,16 +0,0 @@
|
|||
{
|
||||
"name": "eslint-conf",
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"exports": "./index.ts",
|
||||
"dependencies": {
|
||||
"@eslint/js": "9.23.0",
|
||||
"@stylistic/eslint-plugin": "4.2.0",
|
||||
"eslint": "9.23.0",
|
||||
"eslint-plugin-jsdoc": "50.6.9",
|
||||
"jiti": "2.4.2",
|
||||
"pkg-types": "2.1.0",
|
||||
"typescript": "5.8.2",
|
||||
"typescript-eslint": "8.28.0"
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"compilerOptions": {
|
||||
"target": "ESNext",
|
||||
"lib": [
|
||||
"ESNext"
|
||||
],
|
||||
"module": "preserve",
|
||||
"moduleResolution": "bundler",
|
||||
"baseUrl": ".",
|
||||
"noEmit": true,
|
||||
"newLine": "LF",
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"isolatedModules": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"noImplicitAny": false
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"extends": "./tsconfig.base.json",
|
||||
"includes": [
|
||||
"*.ts",
|
||||
"**/*.ts",
|
||||
"*.js",
|
||||
"**/*.js"
|
||||
]
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
{pkgs, ...}: let
|
||||
inherit (pkgs.lib) getExe mapAttrs;
|
||||
|
||||
mkApp = pkg: {
|
||||
program = getExe pkg;
|
||||
type = "app";
|
||||
};
|
||||
in
|
||||
mapAttrs (n: v: mkApp v) pkgs.appsPackages
|
|
@ -1,3 +0,0 @@
|
|||
use flake $FLAKE#subtitles-dev
|
||||
(cd ../config; npm ci)
|
||||
npm ci
|
|
@ -1,17 +0,0 @@
|
|||
{
|
||||
buildApp,
|
||||
ffmpeg-full,
|
||||
...
|
||||
}:
|
||||
buildApp {
|
||||
src = ./.;
|
||||
npmDepsHash = "sha256-laq+WevDxgcuK/8r0alI186SCeKswPx9VRzrCjXRHXU=";
|
||||
|
||||
runtimeInputs = [
|
||||
ffmpeg-full
|
||||
];
|
||||
|
||||
meta.description = ''
|
||||
Extract all `srt` subtitle files from a `mkv` video with the appropriate name.
|
||||
'';
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
import eslintConf from 'eslint-conf';
|
||||
|
||||
export default eslintConf;
|
1544
apps/extract-subs/package-lock.json
generated
1544
apps/extract-subs/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -1,21 +0,0 @@
|
|||
{
|
||||
"name": "extract-subs",
|
||||
"version": "0.0.0",
|
||||
"bin": "out/bin/app.cjs",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "node_ver=$(node -v); esbuild src/app.ts --bundle --platform=node --target=\"node${node_ver:1:2}\" --outfile=out/bin/app.cjs"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/fluent-ffmpeg": "2.1.27",
|
||||
"fluent-ffmpeg": "2.1.3",
|
||||
"@types/node": "22.13.14",
|
||||
"esbuild": "0.25.1",
|
||||
"eslint": "9.23.0",
|
||||
"jiti": "2.4.2",
|
||||
"typescript": "5.8.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint-conf": "file:../config"
|
||||
}
|
||||
}
|
|
@ -1,157 +0,0 @@
|
|||
import { spawnSync as spawn } from 'child_process';
|
||||
|
||||
import ffprobe from './ffprobe';
|
||||
import { ISO6393To1 } from './lang-codes';
|
||||
|
||||
/* Types */
|
||||
import { FfprobeStream } from 'fluent-ffmpeg';
|
||||
|
||||
|
||||
const SPAWN_OPTS = {
|
||||
stdio: [process.stdin, process.stdout, process.stderr],
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* These are the cli arguments
|
||||
*
|
||||
* @param videoPath the directory in which we want to sync the subtitles
|
||||
* @param languages a comma-separated list of languages (3 letters) to sync the subtitles
|
||||
*/
|
||||
const video = process.argv[2];
|
||||
const languages = process.argv[3]?.split(',');
|
||||
|
||||
|
||||
// Global Vars
|
||||
const subIndexes: number[] = [];
|
||||
let videoPath: string;
|
||||
let baseName: string;
|
||||
|
||||
|
||||
/**
|
||||
* Gets the relative path to the subtitle file of a ffmpeg stream.
|
||||
*
|
||||
* @param sub the stream of the subtitles to extract
|
||||
* @returns the path of the subtitle file
|
||||
*/
|
||||
const getSubPath = (sub: FfprobeStream): string => {
|
||||
const language = ISO6393To1.get(sub.tags.language);
|
||||
|
||||
const forced = sub.disposition?.forced === 0 ?
|
||||
'' :
|
||||
'.forced';
|
||||
|
||||
const hearingImpaired = sub.disposition?.hearing_impaired === 0 ?
|
||||
'' :
|
||||
'.sdh';
|
||||
|
||||
return `${baseName}${forced}.${language}${hearingImpaired}.srt`;
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes all subtitles streams from the video file.
|
||||
*/
|
||||
const removeContainerSubs = (): void => {
|
||||
spawn('mv', [
|
||||
videoPath,
|
||||
`${videoPath}.bak`,
|
||||
], SPAWN_OPTS);
|
||||
|
||||
spawn('ffmpeg', [
|
||||
'-i', `${videoPath}.bak`,
|
||||
'-map', '0',
|
||||
...subIndexes.map((i) => ['-map', `-0:${i}`]).flat(),
|
||||
'-c', 'copy', videoPath,
|
||||
], SPAWN_OPTS);
|
||||
|
||||
spawn('rm', [
|
||||
`${videoPath}.bak`,
|
||||
], SPAWN_OPTS);
|
||||
};
|
||||
|
||||
/**
|
||||
* Extracts a sub of a video file to a subtitle file.
|
||||
*
|
||||
* @param sub the stream of the subtitles to extract
|
||||
*/
|
||||
const extractSub = (sub: FfprobeStream): void => {
|
||||
const subFile = getSubPath(sub);
|
||||
|
||||
spawn('ffmpeg', [
|
||||
'-i', videoPath,
|
||||
'-map', `0:${sub.index}`, subFile,
|
||||
], SPAWN_OPTS);
|
||||
|
||||
subIndexes.push(sub.index);
|
||||
};
|
||||
|
||||
/**
|
||||
* Sorts the list of streams to only keep subtitles
|
||||
* that can be extracted.
|
||||
*
|
||||
* @param lang the language of the subtitles
|
||||
* @param streams the streams
|
||||
* @returns the streams that represent subtitles
|
||||
*/
|
||||
const findSubs = (
|
||||
lang: string,
|
||||
streams: FfprobeStream[],
|
||||
): FfprobeStream[] => {
|
||||
const subs = streams.filter((s) => s.tags?.language &&
|
||||
s.tags.language === lang &&
|
||||
s.codec_type === 'subtitle');
|
||||
|
||||
const pgs = subs.filter((s) => s.codec_name === 'hdmv_pgs_subtitle');
|
||||
|
||||
// If we only have PGS subs, warn user
|
||||
if (pgs.length === subs.length) {
|
||||
console.warn(`No SRT subtitle tracks were found for ${lang}`);
|
||||
}
|
||||
|
||||
// Remove PGS streams from subs
|
||||
return subs.filter((s) => s.codec_name !== 'hdmv_pgs_subtitle');
|
||||
};
|
||||
|
||||
/**
|
||||
* Where the magic happens.
|
||||
*/
|
||||
const main = async(): Promise<void> => {
|
||||
// Get rid of video extension
|
||||
baseName = videoPath.split('/').at(-1)!.replace(/\.[^.]*$/, '');
|
||||
|
||||
// ffprobe the video file to see available sub tracks
|
||||
const data = await ffprobe(videoPath);
|
||||
|
||||
if (!data?.streams) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for languages wanted
|
||||
languages.forEach((lang) => {
|
||||
const subs = findSubs(lang, data.streams);
|
||||
|
||||
if (subs.length === 0) {
|
||||
console.warn(`No subtitle tracks were found for ${lang}`);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Extract all subs
|
||||
subs.forEach((sub) => {
|
||||
extractSub(sub);
|
||||
});
|
||||
});
|
||||
|
||||
removeContainerSubs();
|
||||
};
|
||||
|
||||
|
||||
// Check if there are 2 params
|
||||
if (video && languages) {
|
||||
videoPath = video;
|
||||
main();
|
||||
}
|
||||
else {
|
||||
console.error('Error: no argument passed');
|
||||
process.exit(1);
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
import Ffmpeg from 'fluent-ffmpeg';
|
||||
|
||||
|
||||
export default (videoPath: string) => new Promise<Ffmpeg.FfprobeData>((resolve) => {
|
||||
Ffmpeg.ffprobe(videoPath, (_e, data) => {
|
||||
resolve(data);
|
||||
});
|
||||
});
|
|
@ -1,373 +0,0 @@
|
|||
export const ISO6391To3 = new Map([
|
||||
['aa', 'aar'],
|
||||
['ab', 'abk'],
|
||||
['af', 'afr'],
|
||||
['ak', 'aka'],
|
||||
['am', 'amh'],
|
||||
['ar', 'ara'],
|
||||
['an', 'arg'],
|
||||
['as', 'asm'],
|
||||
['av', 'ava'],
|
||||
['ae', 'ave'],
|
||||
['ay', 'aym'],
|
||||
['az', 'aze'],
|
||||
['ba', 'bak'],
|
||||
['bm', 'bam'],
|
||||
['be', 'bel'],
|
||||
['bn', 'ben'],
|
||||
['bi', 'bis'],
|
||||
['bo', 'bod'],
|
||||
['bs', 'bos'],
|
||||
['br', 'bre'],
|
||||
['bg', 'bul'],
|
||||
['ca', 'cat'],
|
||||
['cs', 'ces'],
|
||||
['ch', 'cha'],
|
||||
['ce', 'che'],
|
||||
['cu', 'chu'],
|
||||
['cv', 'chv'],
|
||||
['kw', 'cor'],
|
||||
['co', 'cos'],
|
||||
['cr', 'cre'],
|
||||
['cy', 'cym'],
|
||||
['da', 'dan'],
|
||||
['de', 'deu'],
|
||||
['dv', 'div'],
|
||||
['dz', 'dzo'],
|
||||
['el', 'ell'],
|
||||
['en', 'eng'],
|
||||
['eo', 'epo'],
|
||||
['et', 'est'],
|
||||
['eu', 'eus'],
|
||||
['ee', 'ewe'],
|
||||
['fo', 'fao'],
|
||||
['fa', 'fas'],
|
||||
['fj', 'fij'],
|
||||
['fi', 'fin'],
|
||||
['fr', 'fre'],
|
||||
['fy', 'fry'],
|
||||
['ff', 'ful'],
|
||||
['gd', 'gla'],
|
||||
['ga', 'gle'],
|
||||
['gl', 'glg'],
|
||||
['gv', 'glv'],
|
||||
['gn', 'grn'],
|
||||
['gu', 'guj'],
|
||||
['ht', 'hat'],
|
||||
['ha', 'hau'],
|
||||
['sh', 'hbs'],
|
||||
['he', 'heb'],
|
||||
['hz', 'her'],
|
||||
['hi', 'hin'],
|
||||
['ho', 'hmo'],
|
||||
['hr', 'hrv'],
|
||||
['hu', 'hun'],
|
||||
['hy', 'hye'],
|
||||
['ig', 'ibo'],
|
||||
['io', 'ido'],
|
||||
['ii', 'iii'],
|
||||
['iu', 'iku'],
|
||||
['ie', 'ile'],
|
||||
['ia', 'ina'],
|
||||
['id', 'ind'],
|
||||
['ik', 'ipk'],
|
||||
['is', 'isl'],
|
||||
['it', 'ita'],
|
||||
['jv', 'jav'],
|
||||
['ja', 'jpn'],
|
||||
['kl', 'kal'],
|
||||
['kn', 'kan'],
|
||||
['ks', 'kas'],
|
||||
['ka', 'kat'],
|
||||
['kr', 'kau'],
|
||||
['kk', 'kaz'],
|
||||
['km', 'khm'],
|
||||
['ki', 'kik'],
|
||||
['rw', 'kin'],
|
||||
['ky', 'kir'],
|
||||
['kv', 'kom'],
|
||||
['kg', 'kon'],
|
||||
['ko', 'kor'],
|
||||
['kj', 'kua'],
|
||||
['ku', 'kur'],
|
||||
['lo', 'lao'],
|
||||
['la', 'lat'],
|
||||
['lv', 'lav'],
|
||||
['li', 'lim'],
|
||||
['ln', 'lin'],
|
||||
['lt', 'lit'],
|
||||
['lb', 'ltz'],
|
||||
['lu', 'lub'],
|
||||
['lg', 'lug'],
|
||||
['mh', 'mah'],
|
||||
['ml', 'mal'],
|
||||
['mr', 'mar'],
|
||||
['mk', 'mkd'],
|
||||
['mg', 'mlg'],
|
||||
['mt', 'mlt'],
|
||||
['mn', 'mon'],
|
||||
['mi', 'mri'],
|
||||
['ms', 'msa'],
|
||||
['my', 'mya'],
|
||||
['na', 'nau'],
|
||||
['nv', 'nav'],
|
||||
['nr', 'nbl'],
|
||||
['nd', 'nde'],
|
||||
['ng', 'ndo'],
|
||||
['ne', 'nep'],
|
||||
['nl', 'nld'],
|
||||
['nn', 'nno'],
|
||||
['nb', 'nob'],
|
||||
['no', 'nor'],
|
||||
['ny', 'nya'],
|
||||
['oc', 'oci'],
|
||||
['oj', 'oji'],
|
||||
['or', 'ori'],
|
||||
['om', 'orm'],
|
||||
['os', 'oss'],
|
||||
['pa', 'pan'],
|
||||
['pi', 'pli'],
|
||||
['pl', 'pol'],
|
||||
['pt', 'por'],
|
||||
['ps', 'pus'],
|
||||
['qu', 'que'],
|
||||
['rm', 'roh'],
|
||||
['ro', 'ron'],
|
||||
['rn', 'run'],
|
||||
['ru', 'rus'],
|
||||
['sg', 'sag'],
|
||||
['sa', 'san'],
|
||||
['si', 'sin'],
|
||||
['sk', 'slk'],
|
||||
['sl', 'slv'],
|
||||
['se', 'sme'],
|
||||
['sm', 'smo'],
|
||||
['sn', 'sna'],
|
||||
['sd', 'snd'],
|
||||
['so', 'som'],
|
||||
['st', 'sot'],
|
||||
['es', 'spa'],
|
||||
['sq', 'sqi'],
|
||||
['sc', 'srd'],
|
||||
['sr', 'srp'],
|
||||
['ss', 'ssw'],
|
||||
['su', 'sun'],
|
||||
['sw', 'swa'],
|
||||
['sv', 'swe'],
|
||||
['ty', 'tah'],
|
||||
['ta', 'tam'],
|
||||
['tt', 'tat'],
|
||||
['te', 'tel'],
|
||||
['tg', 'tgk'],
|
||||
['tl', 'tgl'],
|
||||
['th', 'tha'],
|
||||
['ti', 'tir'],
|
||||
['to', 'ton'],
|
||||
['tn', 'tsn'],
|
||||
['ts', 'tso'],
|
||||
['tk', 'tuk'],
|
||||
['tr', 'tur'],
|
||||
['tw', 'twi'],
|
||||
['ug', 'uig'],
|
||||
['uk', 'ukr'],
|
||||
['ur', 'urd'],
|
||||
['uz', 'uzb'],
|
||||
['ve', 'ven'],
|
||||
['vi', 'vie'],
|
||||
['vo', 'vol'],
|
||||
['wa', 'wln'],
|
||||
['wo', 'wol'],
|
||||
['xh', 'xho'],
|
||||
['yi', 'yid'],
|
||||
['yo', 'yor'],
|
||||
['za', 'zha'],
|
||||
['zh', 'zho'],
|
||||
['zu', 'zul'],
|
||||
]);
|
||||
|
||||
export const ISO6393To1 = new Map([
|
||||
['aar', 'aa'],
|
||||
['abk', 'ab'],
|
||||
['afr', 'af'],
|
||||
['aka', 'ak'],
|
||||
['amh', 'am'],
|
||||
['ara', 'ar'],
|
||||
['arg', 'an'],
|
||||
['asm', 'as'],
|
||||
['ava', 'av'],
|
||||
['ave', 'ae'],
|
||||
['aym', 'ay'],
|
||||
['aze', 'az'],
|
||||
['bak', 'ba'],
|
||||
['bam', 'bm'],
|
||||
['bel', 'be'],
|
||||
['ben', 'bn'],
|
||||
['bis', 'bi'],
|
||||
['bod', 'bo'],
|
||||
['bos', 'bs'],
|
||||
['bre', 'br'],
|
||||
['bul', 'bg'],
|
||||
['cat', 'ca'],
|
||||
['ces', 'cs'],
|
||||
['cha', 'ch'],
|
||||
['che', 'ce'],
|
||||
['chu', 'cu'],
|
||||
['chv', 'cv'],
|
||||
['cor', 'kw'],
|
||||
['cos', 'co'],
|
||||
['cre', 'cr'],
|
||||
['cym', 'cy'],
|
||||
['dan', 'da'],
|
||||
['deu', 'de'],
|
||||
['div', 'dv'],
|
||||
['dzo', 'dz'],
|
||||
['ell', 'el'],
|
||||
['eng', 'en'],
|
||||
['epo', 'eo'],
|
||||
['est', 'et'],
|
||||
['eus', 'eu'],
|
||||
['ewe', 'ee'],
|
||||
['fao', 'fo'],
|
||||
['fas', 'fa'],
|
||||
['fij', 'fj'],
|
||||
['fin', 'fi'],
|
||||
['fre', 'fr'],
|
||||
['fry', 'fy'],
|
||||
['ful', 'ff'],
|
||||
['gla', 'gd'],
|
||||
['gle', 'ga'],
|
||||
['glg', 'gl'],
|
||||
['glv', 'gv'],
|
||||
['grn', 'gn'],
|
||||
['guj', 'gu'],
|
||||
['hat', 'ht'],
|
||||
['hau', 'ha'],
|
||||
['hbs', 'sh'],
|
||||
['heb', 'he'],
|
||||
['her', 'hz'],
|
||||
['hin', 'hi'],
|
||||
['hmo', 'ho'],
|
||||
['hrv', 'hr'],
|
||||
['hun', 'hu'],
|
||||
['hye', 'hy'],
|
||||
['ibo', 'ig'],
|
||||
['ido', 'io'],
|
||||
['iii', 'ii'],
|
||||
['iku', 'iu'],
|
||||
['ile', 'ie'],
|
||||
['ina', 'ia'],
|
||||
['ind', 'id'],
|
||||
['ipk', 'ik'],
|
||||
['isl', 'is'],
|
||||
['ita', 'it'],
|
||||
['jav', 'jv'],
|
||||
['jpn', 'ja'],
|
||||
['kal', 'kl'],
|
||||
['kan', 'kn'],
|
||||
['kas', 'ks'],
|
||||
['kat', 'ka'],
|
||||
['kau', 'kr'],
|
||||
['kaz', 'kk'],
|
||||
['khm', 'km'],
|
||||
['kik', 'ki'],
|
||||
['kin', 'rw'],
|
||||
['kir', 'ky'],
|
||||
['kom', 'kv'],
|
||||
['kon', 'kg'],
|
||||
['kor', 'ko'],
|
||||
['kua', 'kj'],
|
||||
['kur', 'ku'],
|
||||
['lao', 'lo'],
|
||||
['lat', 'la'],
|
||||
['lav', 'lv'],
|
||||
['lim', 'li'],
|
||||
['lin', 'ln'],
|
||||
['lit', 'lt'],
|
||||
['ltz', 'lb'],
|
||||
['lub', 'lu'],
|
||||
['lug', 'lg'],
|
||||
['mah', 'mh'],
|
||||
['mal', 'ml'],
|
||||
['mar', 'mr'],
|
||||
['mkd', 'mk'],
|
||||
['mlg', 'mg'],
|
||||
['mlt', 'mt'],
|
||||
['mon', 'mn'],
|
||||
['mri', 'mi'],
|
||||
['msa', 'ms'],
|
||||
['mya', 'my'],
|
||||
['nau', 'na'],
|
||||
['nav', 'nv'],
|
||||
['nbl', 'nr'],
|
||||
['nde', 'nd'],
|
||||
['ndo', 'ng'],
|
||||
['nep', 'ne'],
|
||||
['nld', 'nl'],
|
||||
['nno', 'nn'],
|
||||
['nob', 'nb'],
|
||||
['nor', 'no'],
|
||||
['nya', 'ny'],
|
||||
['oci', 'oc'],
|
||||
['oji', 'oj'],
|
||||
['ori', 'or'],
|
||||
['orm', 'om'],
|
||||
['oss', 'os'],
|
||||
['pan', 'pa'],
|
||||
['pli', 'pi'],
|
||||
['pol', 'pl'],
|
||||
['por', 'pt'],
|
||||
['pus', 'ps'],
|
||||
['que', 'qu'],
|
||||
['roh', 'rm'],
|
||||
['ron', 'ro'],
|
||||
['run', 'rn'],
|
||||
['rus', 'ru'],
|
||||
['sag', 'sg'],
|
||||
['san', 'sa'],
|
||||
['sin', 'si'],
|
||||
['slk', 'sk'],
|
||||
['slv', 'sl'],
|
||||
['sme', 'se'],
|
||||
['smo', 'sm'],
|
||||
['sna', 'sn'],
|
||||
['snd', 'sd'],
|
||||
['som', 'so'],
|
||||
['sot', 'st'],
|
||||
['spa', 'es'],
|
||||
['sqi', 'sq'],
|
||||
['srd', 'sc'],
|
||||
['srp', 'sr'],
|
||||
['ssw', 'ss'],
|
||||
['sun', 'su'],
|
||||
['swa', 'sw'],
|
||||
['swe', 'sv'],
|
||||
['tah', 'ty'],
|
||||
['tam', 'ta'],
|
||||
['tat', 'tt'],
|
||||
['tel', 'te'],
|
||||
['tgk', 'tg'],
|
||||
['tgl', 'tl'],
|
||||
['tha', 'th'],
|
||||
['tir', 'ti'],
|
||||
['ton', 'to'],
|
||||
['tsn', 'tn'],
|
||||
['tso', 'ts'],
|
||||
['tuk', 'tk'],
|
||||
['tur', 'tr'],
|
||||
['twi', 'tw'],
|
||||
['uig', 'ug'],
|
||||
['ukr', 'uk'],
|
||||
['urd', 'ur'],
|
||||
['uzb', 'uz'],
|
||||
['ven', 've'],
|
||||
['vie', 'vi'],
|
||||
['vol', 'vo'],
|
||||
['wln', 'wa'],
|
||||
['wol', 'wo'],
|
||||
['xho', 'xh'],
|
||||
['yid', 'yi'],
|
||||
['yor', 'yo'],
|
||||
['zha', 'za'],
|
||||
['zho', 'zh'],
|
||||
['zul', 'zu'],
|
||||
]);
|
|
@ -1,10 +0,0 @@
|
|||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"extends": "../config/tsconfig.base.json",
|
||||
"includes": [
|
||||
"*.ts",
|
||||
"**/*.ts",
|
||||
"*.js",
|
||||
"**/*.js"
|
||||
]
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
{
|
||||
writeShellApplication,
|
||||
jq,
|
||||
pandoc,
|
||||
...
|
||||
}:
|
||||
writeShellApplication {
|
||||
name = "gen-docs";
|
||||
runtimeInputs = [jq pandoc];
|
||||
text = builtins.readFile ./script.sh;
|
||||
|
||||
meta.description = ''
|
||||
Generates the READMEs in this repository from nix attributes.
|
||||
'';
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
attr: selfPath: let
|
||||
inherit (builtins) mapAttrs replaceStrings;
|
||||
|
||||
modules = import "${selfPath}/${attr}" {description = true;};
|
||||
|
||||
trimNewlines = s: replaceStrings ["\n"] [" "] s;
|
||||
in {
|
||||
attrs =
|
||||
mapAttrs (_: v: {
|
||||
desc = trimNewlines v;
|
||||
})
|
||||
modules;
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
configs: let
|
||||
inherit (builtins) mapAttrs replaceStrings;
|
||||
|
||||
trimNewlines = s: replaceStrings ["\n"] [" "] s;
|
||||
in {
|
||||
attrs =
|
||||
mapAttrs (_: v: {
|
||||
roleDesc = trimNewlines (v.config.meta.roleDescription or "");
|
||||
hwDesc = trimNewlines (v.config.meta.hardwareDescription or "");
|
||||
})
|
||||
configs;
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
x: let
|
||||
inherit (builtins) currentSystem mapAttrs removeAttrs replaceStrings;
|
||||
|
||||
trimNewlines = s: replaceStrings ["\n"] [" "] s;
|
||||
packages = removeAttrs x.${currentSystem} ["default"];
|
||||
in {
|
||||
attrs =
|
||||
mapAttrs (_: v: {
|
||||
desc = trimNewlines (v.meta.description or "");
|
||||
homepage = v.meta.homepage or "";
|
||||
})
|
||||
packages;
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
attr: selfPath: let
|
||||
inherit (builtins) currentSystem getFlake mapAttrs removeAttrs replaceStrings;
|
||||
|
||||
self = getFlake selfPath;
|
||||
scopes = ((import "${selfPath}/${attr}" {description = true;}) {} {}).scopedPackages;
|
||||
|
||||
trimNewlines = s: replaceStrings ["\n"] [" "] s;
|
||||
in {
|
||||
attrs =
|
||||
mapAttrs (n: v: {
|
||||
desc = trimNewlines v;
|
||||
packages = let
|
||||
scopePkgs = removeAttrs self.${attr}.${currentSystem}.${n} [
|
||||
"buildFirefoxXpiAddon"
|
||||
"callPackage"
|
||||
"newScope"
|
||||
"override"
|
||||
"overrideDerivation"
|
||||
"overrideScope"
|
||||
"packages"
|
||||
"recurseForDerivations"
|
||||
];
|
||||
in
|
||||
mapAttrs (_: pkg: {
|
||||
desc = trimNewlines (pkg.meta.description or "");
|
||||
homepage = pkg.meta.homepage or "";
|
||||
})
|
||||
scopePkgs;
|
||||
})
|
||||
scopes;
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
substituteDerivs() {
|
||||
echo '' | pandoc --metadata-file <(
|
||||
nix eval \
|
||||
--impure \
|
||||
--json \
|
||||
"$FLAKE"#"$1" \
|
||||
--apply "import \"$FLAKE/apps/gen-docs/$3.nix\"" |
|
||||
jq -r
|
||||
) -t markdown --template "$FLAKE/apps/gen-docs/templates/$2.md" -o "$FLAKE/$2/README.md"
|
||||
}
|
||||
|
||||
substituteAttrs() {
|
||||
echo '' | pandoc --metadata-file <(
|
||||
nix eval \
|
||||
--impure \
|
||||
--json \
|
||||
--expr "\"$FLAKE\"" \
|
||||
--apply "(import \"$FLAKE/apps/gen-docs/getAttrsMeta.nix\") \"$1\"" |
|
||||
jq -r
|
||||
) -t markdown --template "$FLAKE/apps/gen-docs/templates/$1.md" -o "$FLAKE/$1/README.md"
|
||||
}
|
||||
|
||||
substituteScopes() {
|
||||
echo '' | pandoc --metadata-file <(
|
||||
nix eval \
|
||||
--impure \
|
||||
--json \
|
||||
--expr "\"$FLAKE\"" \
|
||||
--apply "(import \"$FLAKE/apps/gen-docs/getScopesMeta.nix\") \"$1\"" |
|
||||
jq -r
|
||||
) -t markdown --template "$FLAKE/apps/gen-docs/templates/$1.md" -o "$FLAKE/$1/README.md"
|
||||
}
|
||||
|
||||
substituteDerivs "appsPackages" "apps" "getPackageMeta"
|
||||
substituteDerivs "nixosConfigurations" "configurations" "getConfigMeta"
|
||||
substituteDerivs "devShells" "devShells" "getPackageMeta"
|
||||
substituteDerivs "packages" "packages" "getPackageMeta"
|
||||
|
||||
substituteAttrs "modules"
|
||||
substituteAttrs "homeManagerModules"
|
||||
substituteAttrs "overlays"
|
||||
|
||||
substituteScopes "scopedPackages"
|
|
@ -1,11 +0,0 @@
|
|||
# Apps
|
||||
|
||||
This directory contains every derivations for apps exposed by this flake.
|
||||
|
||||
## List of my apps found in `self.apps`
|
||||
|
||||
| Name | Description |
|
||||
| ---- | ----------- |
|
||||
$for(attrs/pairs)$
|
||||
| `$it.key$` | $it.value.desc/nowrap$ |
|
||||
$endfor$
|
|
@ -1,13 +0,0 @@
|
|||
# NixosConfigurations
|
||||
|
||||
This directory contains every device's main configuration file, their `hardware-configuration.nix` and some custom modules
|
||||
unique to them.
|
||||
|
||||
## List of my devices
|
||||
|
||||
| Name | Model / Specs | Description |
|
||||
| --------- | ------------- | ------------------------------------------------------------------------------------------------ |
|
||||
| `android` | OnePlus 9 Pro | [Nix-On-Droid](https://github.com/nix-community/nix-on-droid) configuration for my OnePlus 9 Pro |
|
||||
$for(attrs/pairs)$
|
||||
| `$it.key$` | $it.value.hwDesc/nowrap$ | $it.value.roleDesc/nowrap$ |
|
||||
$endfor$
|
|
@ -1,11 +0,0 @@
|
|||
# DevShells
|
||||
|
||||
This directory contains every derivations for devShells exposed by this flake.
|
||||
|
||||
## List of my devShells found in `self.devShells`
|
||||
|
||||
| Name | Description |
|
||||
| ---- | ----------- |
|
||||
$for(attrs/pairs)$
|
||||
| `$it.key$` | $it.value.desc/nowrap$ |
|
||||
$endfor$
|
|
@ -1,11 +0,0 @@
|
|||
# HomeManagerModules
|
||||
|
||||
This directory contains every home-manager modules exposed by this flake.
|
||||
|
||||
## List of my home-manager modules found in `self.homeManagerModules`
|
||||
|
||||
| Name | Description |
|
||||
| ---- | ----------- |
|
||||
$for(attrs/pairs)$
|
||||
| `$it.key$` | $it.value.desc/nowrap$ |
|
||||
$endfor$
|
|
@ -1,11 +0,0 @@
|
|||
# NixosModules
|
||||
|
||||
This directory contains every modules for NixOS exposed by this flake.
|
||||
|
||||
## List of my modules found in `self.nixosModules`
|
||||
|
||||
| Name | Description |
|
||||
| ---- | ----------- |
|
||||
$for(attrs/pairs)$
|
||||
| `$it.key$` | $it.value.desc/nowrap$ |
|
||||
$endfor$
|
|
@ -1,11 +0,0 @@
|
|||
# Overlays
|
||||
|
||||
This directory contains every overlay exposed by this flake.
|
||||
|
||||
## List of my overlays found in `self.overlays`
|
||||
|
||||
| Name | Description |
|
||||
| ---- | ----------- |
|
||||
$for(attrs/pairs)$
|
||||
| `$it.key$` | $it.value.desc/nowrap$ |
|
||||
$endfor$
|
|
@ -1,11 +0,0 @@
|
|||
# Packages
|
||||
|
||||
This directory contains every derivations for packages exposed by this flake.
|
||||
|
||||
## List of my packages found in `self.packages`
|
||||
|
||||
| Name | Description | Homepage |
|
||||
| ---- | ----------- | -------- |
|
||||
$for(attrs/pairs)$
|
||||
| `$it.key$` | $it.value.desc/nowrap$ | $it.value.homepage/nowrap$ |
|
||||
$endfor$
|
|
@ -1,18 +0,0 @@
|
|||
# ScopedPackages
|
||||
|
||||
This directory contains every package scopes exposed by this flake.
|
||||
|
||||
## List of my package scopes found in `self.scopedPackages`
|
||||
|
||||
$for(attrs/pairs)$
|
||||
### $it.key$
|
||||
|
||||
$it.value.desc/nowrap$
|
||||
|
||||
| Name | Description | Homepage |
|
||||
| ---- | ----------- | -------- |
|
||||
$for(it.value.packages/pairs)$
|
||||
| `$it.key$` | $it.value.desc/nowrap$ | $it.value.homepage/nowrap$ |
|
||||
$endfor$
|
||||
|
||||
$endfor$
|
|
@ -1,3 +0,0 @@
|
|||
use flake $FLAKE#node
|
||||
(cd ../config; npm ci)
|
||||
npm ci
|
1
apps/list2series/.gitignore
vendored
1
apps/list2series/.gitignore
vendored
|
@ -1 +0,0 @@
|
|||
.env
|
|
@ -1,11 +0,0 @@
|
|||
{buildApp, ...}:
|
||||
buildApp {
|
||||
src = ./.;
|
||||
npmDepsHash = "sha256-A5xtspKUPJaVtJYKNnGNXg1A+u0rg7J7HbDu+dE6sHs=";
|
||||
|
||||
runtimeInputs = [];
|
||||
|
||||
meta.description = ''
|
||||
Converts a Komga read list into a comics series for reading with mihon.
|
||||
'';
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
import eslintConf from 'eslint-conf';
|
||||
|
||||
export default eslintConf;
|
1812
apps/list2series/package-lock.json
generated
1812
apps/list2series/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -1,21 +0,0 @@
|
|||
{
|
||||
"name": "list2series",
|
||||
"version": "0.0.0",
|
||||
"bin": "out/bin/app.cjs",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "node_ver=$(node -v); esbuild src/app.ts --bundle --platform=node --target=\"node${node_ver:1:2}\" --outfile=out/bin/app.cjs"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/node": "22.13.14",
|
||||
"axios": "1.8.4",
|
||||
"esbuild": "0.25.1",
|
||||
"eslint": "9.23.0",
|
||||
"jiti": "2.4.2",
|
||||
"pkg-types": "2.1.0",
|
||||
"typescript": "5.8.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint-conf": "file:../config"
|
||||
}
|
||||
}
|
|
@ -1,214 +0,0 @@
|
|||
import axios from 'axios';
|
||||
import { linkSync, mkdirSync, readFileSync, rmSync } from 'fs';
|
||||
import { basename } from 'path';
|
||||
|
||||
import { type Book, type ReadList, type Series } from './types';
|
||||
|
||||
|
||||
// Examples of calling this script:
|
||||
// $ just l2s copy 0K65Q482KK7SD
|
||||
// $ just l2s meta 0K65Q482KK7SD
|
||||
const API = JSON.parse(
|
||||
readFileSync(`${process.env.FLAKE}/apps/list2series/.env`, { encoding: 'utf-8' }),
|
||||
).API;
|
||||
|
||||
const LIST_ID = process.argv[3];
|
||||
|
||||
const getListInfo = async(): Promise<ReadList> => {
|
||||
const res = await axios.request({
|
||||
method: 'get',
|
||||
maxBodyLength: Infinity,
|
||||
url: `https://komga.nelim.org/api/v1/readlists/${LIST_ID}`,
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'X-API-Key': API,
|
||||
},
|
||||
});
|
||||
|
||||
return res.data;
|
||||
};
|
||||
|
||||
const getSeries = async(seriesTitle: string, operator = true): Promise<Series[]> => {
|
||||
return (await axios.request({
|
||||
method: 'post',
|
||||
maxBodyLength: Infinity,
|
||||
url: 'https://komga.nelim.org/api/v1/series/list?unpaged=true',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
'X-API-Key': API,
|
||||
},
|
||||
data: JSON.stringify({
|
||||
condition: {
|
||||
title: {
|
||||
operator: operator ? 'is' : 'isNot',
|
||||
value: seriesTitle,
|
||||
},
|
||||
},
|
||||
}),
|
||||
})).data.content;
|
||||
};
|
||||
|
||||
const getSeriesBooks = async(listName: string, seriesPath: string): Promise<Book[]> => {
|
||||
const thisSeries = (await getSeries('', false)).find((s) => s.url === seriesPath);
|
||||
|
||||
if (!thisSeries) {
|
||||
throw new Error('Series could not be found');
|
||||
}
|
||||
|
||||
// Reset Series metadata
|
||||
axios.request({
|
||||
method: 'patch',
|
||||
maxBodyLength: Infinity,
|
||||
url: `https://komga.nelim.org/api/v1/series/${thisSeries.id}/metadata`,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-API-Key': API,
|
||||
},
|
||||
data: JSON.stringify({
|
||||
ageRating: null,
|
||||
ageRatingLock: true,
|
||||
alternateTitles: null,
|
||||
alternateTitlesLock: true,
|
||||
genres: null,
|
||||
genresLock: true,
|
||||
language: null,
|
||||
languageLock: true,
|
||||
links: null,
|
||||
linksLock: true,
|
||||
publisherLock: true,
|
||||
readingDirection: 'LEFT_TO_RIGHT',
|
||||
readingDirectionLock: true,
|
||||
sharingLabels: null,
|
||||
sharingLabelsLock: true,
|
||||
status: null,
|
||||
statusLock: true,
|
||||
summary: null,
|
||||
summaryLock: true,
|
||||
tags: null,
|
||||
tagsLock: true,
|
||||
title: listName,
|
||||
titleLock: true,
|
||||
titleSort: listName,
|
||||
titleSortLock: true,
|
||||
totalBookCountLock: true,
|
||||
}),
|
||||
});
|
||||
|
||||
const books = await axios.request({
|
||||
method: 'post',
|
||||
maxBodyLength: Infinity,
|
||||
url: 'https://komga.nelim.org/api/v1/books/list?unpaged=true',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
'X-API-Key': API,
|
||||
},
|
||||
data: JSON.stringify({
|
||||
condition: {
|
||||
seriesId: {
|
||||
operator: 'is',
|
||||
value: thisSeries.id,
|
||||
},
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
return books.data.content;
|
||||
};
|
||||
|
||||
const getBookInfo = async(id: string): Promise<Book> => {
|
||||
const res = await axios.request({
|
||||
method: 'get',
|
||||
maxBodyLength: Infinity,
|
||||
url: `https://komga.nelim.org/api/v1/books/${id}`,
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'X-API-Key': API,
|
||||
},
|
||||
});
|
||||
|
||||
return res.data;
|
||||
};
|
||||
|
||||
// There doesn't seem to be a way to wait for the scan to be done
|
||||
const scanLibrary = (): void => {
|
||||
axios.request({
|
||||
method: 'post',
|
||||
maxBodyLength: Infinity,
|
||||
url: 'https://komga.nelim.org/api/v1/libraries/0K4QG58XA29DZ/scan',
|
||||
headers: {
|
||||
'X-API-Key': API,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const setBookMetadata = async(i: number, source: Book, target: Book): Promise<void> => {
|
||||
const thisSeries = (await getSeries(source.seriesTitle))[0];
|
||||
|
||||
source.metadata.title = thisSeries.booksCount !== 1 ?
|
||||
`${source.seriesTitle} Issue #${source.metadata.number}` :
|
||||
source.metadata.title = source.seriesTitle;
|
||||
|
||||
source.metadata.number = i.toString();
|
||||
source.metadata.numberSort = i;
|
||||
|
||||
const metadata = JSON.stringify(source.metadata);
|
||||
|
||||
axios.request({
|
||||
method: 'patch',
|
||||
maxBodyLength: Infinity,
|
||||
url: `https://komga.nelim.org/api/v1/books/${target.id}/metadata`,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-API-Key': API,
|
||||
},
|
||||
data: metadata,
|
||||
});
|
||||
};
|
||||
|
||||
const main = async(): Promise<void> => {
|
||||
const list = await getListInfo();
|
||||
const ids = list.bookIds;
|
||||
const seriesPath = `/data/comics/[List] ${list.name}`;
|
||||
|
||||
const listBooks = [] as Book[];
|
||||
|
||||
for (let i = 0; i < ids.length; i++) {
|
||||
const book = await getBookInfo(ids[i]);
|
||||
|
||||
listBooks[i] = book;
|
||||
};
|
||||
|
||||
if (process.argv[2] === 'copy') {
|
||||
rmSync(seriesPath, { recursive: true, force: true });
|
||||
mkdirSync(seriesPath, { recursive: true });
|
||||
|
||||
for (const book of listBooks) {
|
||||
const bookPath = book.url;
|
||||
const inListPath = `${seriesPath}/${basename(bookPath)}`;
|
||||
|
||||
console.log(`hardlinking ${basename(bookPath)}`);
|
||||
linkSync(bookPath, inListPath);
|
||||
}
|
||||
|
||||
scanLibrary();
|
||||
}
|
||||
|
||||
else if (process.argv[2] === 'meta') {
|
||||
const seriesBooks = await getSeriesBooks(`[List] ${list.name}`, seriesPath);
|
||||
|
||||
for (const target of seriesBooks) {
|
||||
const source = listBooks.find((b) => basename(b.url) === basename(target.url));
|
||||
|
||||
if (source) {
|
||||
const i = listBooks.indexOf(source) + 1;
|
||||
|
||||
console.log(`Setting metadata for ${source.name}`);
|
||||
setBookMetadata(i, source, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
main();
|
|
@ -1,135 +0,0 @@
|
|||
export interface Media {
|
||||
status: string
|
||||
mediaType: string
|
||||
pagesCount: number
|
||||
comment: string
|
||||
epubDivinaCompatible: boolean
|
||||
epubIsKepub: boolean
|
||||
mediaProfile: string
|
||||
}
|
||||
|
||||
export interface Author {
|
||||
name: string
|
||||
role: string
|
||||
}
|
||||
|
||||
export interface Link {
|
||||
label: string
|
||||
url: string
|
||||
}
|
||||
|
||||
export interface ShortBookMetadata {
|
||||
authors: Author[]
|
||||
tags: unknown[]
|
||||
releaseDate: string
|
||||
summary: string
|
||||
summaryNumber: string
|
||||
created: string
|
||||
lastModified: string
|
||||
}
|
||||
|
||||
export interface BookMetadata {
|
||||
title: string
|
||||
titleLock: boolean
|
||||
summary: string
|
||||
summaryLock: boolean
|
||||
number: string
|
||||
numberLock: boolean
|
||||
numberSort: number
|
||||
numberSortLock: boolean
|
||||
releaseDate: string
|
||||
releaseDateLock: boolean
|
||||
authors: Author[]
|
||||
authorsLock: boolean
|
||||
tags: unknown[]
|
||||
tagsLock: boolean
|
||||
isbn: string
|
||||
isbnLock: boolean
|
||||
links: Link[]
|
||||
linksLock: boolean
|
||||
created: string
|
||||
lastModified: string
|
||||
}
|
||||
|
||||
export interface Book {
|
||||
id: string
|
||||
seriesId: string
|
||||
seriesTitle: string
|
||||
libraryId: string
|
||||
name: string
|
||||
url: string
|
||||
number: number
|
||||
created: string
|
||||
lastModified: string
|
||||
fileLastModified: string
|
||||
sizeBytes: number
|
||||
size: string
|
||||
media: Media
|
||||
metadata: BookMetadata
|
||||
readProgress: null | unknown
|
||||
deleted: boolean
|
||||
fileHash: string
|
||||
oneshot: boolean
|
||||
}
|
||||
|
||||
export interface SeriesMetadata {
|
||||
status: string
|
||||
statusLock: boolean
|
||||
title: string
|
||||
titleLock: boolean
|
||||
titleSort: string
|
||||
titleSortLock: boolean
|
||||
summary: string
|
||||
summaryLock: boolean
|
||||
readingDirection: string
|
||||
readingDirectionLock: boolean
|
||||
publisher: string
|
||||
publisherLock: boolean
|
||||
ageRating: null | string
|
||||
ageRatingLock: boolean
|
||||
language: string
|
||||
languageLock: boolean
|
||||
genres: string[]
|
||||
genresLock: boolean
|
||||
tags: unknown[]
|
||||
tagsLock: boolean
|
||||
totalBookCount: null | number
|
||||
totalBookCountLock: boolean
|
||||
sharingLabels: unknown[]
|
||||
sharingLabelsLock: boolean
|
||||
links: Link[]
|
||||
linksLock: boolean
|
||||
alternateTitles: string[]
|
||||
alternateTitlesLock: boolean
|
||||
created: string
|
||||
lastModified: string
|
||||
}
|
||||
|
||||
export interface Series {
|
||||
id: string
|
||||
libraryId: string
|
||||
name: string
|
||||
url: string
|
||||
created: string
|
||||
lastModified: string
|
||||
fileLastModified: string
|
||||
booksCount: number
|
||||
booksReadCount: number
|
||||
booksUnreadCount: number
|
||||
booksInProgressCount: number
|
||||
metadata: SeriesMetadata
|
||||
booksMetadata: ShortBookMetadata
|
||||
deleted: boolean
|
||||
oneshot: boolean
|
||||
}
|
||||
|
||||
export interface ReadList {
|
||||
id: string
|
||||
name: string
|
||||
summary: string
|
||||
ordered: boolean
|
||||
bookIds: string[]
|
||||
createdDate: string
|
||||
lastModifiedDate: string
|
||||
filtered: boolean
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"extends": "../config/tsconfig.base.json",
|
||||
"includes": [
|
||||
"*.ts",
|
||||
"**/*.ts",
|
||||
"*.js",
|
||||
"**/*.js"
|
||||
]
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
use flake $FLAKE#node
|
||||
(cd ../config; npm ci)
|
||||
npm ci
|
|
@ -1,18 +0,0 @@
|
|||
{
|
||||
buildApp,
|
||||
nodejs_latest,
|
||||
...
|
||||
}:
|
||||
buildApp {
|
||||
src = ./.;
|
||||
npmDepsHash = "sha256-+0jcz/lWziDQDnmeQGX9IuPKywHNi6Cd1Y/vwweWsdU=";
|
||||
|
||||
runtimeInputs = [
|
||||
nodejs_latest
|
||||
];
|
||||
|
||||
meta.description = ''
|
||||
Checks if a list of mods have a version available for a specific Minecraft
|
||||
version and a specific loader.
|
||||
'';
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
import eslintConf from 'eslint-conf';
|
||||
|
||||
export default eslintConf;
|
1533
apps/mc-mods/package-lock.json
generated
1533
apps/mc-mods/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -1,20 +0,0 @@
|
|||
{
|
||||
"name": "mc-mods",
|
||||
"version": "0.0.0",
|
||||
"bin": "out/bin/app.cjs",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "node_ver=$(node -v); esbuild src/app.ts --bundle --platform=node --target=\"node${node_ver:1:2}\" --outfile=out/bin/app.cjs"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/node": "22.13.14",
|
||||
"esbuild": "0.25.1",
|
||||
"eslint": "9.23.0",
|
||||
"jiti": "2.4.2",
|
||||
"pkg-types": "2.1.0",
|
||||
"typescript": "5.8.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint-conf": "file:../config"
|
||||
}
|
||||
}
|
|
@ -1,147 +0,0 @@
|
|||
import { createWriteStream, mkdirSync, rmSync } from 'fs';
|
||||
import { Readable } from 'stream';
|
||||
|
||||
interface Hashes {
|
||||
sha1: string
|
||||
sha512: string
|
||||
}
|
||||
interface File {
|
||||
hashes: Hashes
|
||||
url: string
|
||||
filename: string
|
||||
primary: boolean
|
||||
size: number
|
||||
file_type: string
|
||||
}
|
||||
interface Dependency {
|
||||
version_id: string
|
||||
project_id: string
|
||||
file_name: string
|
||||
dependency_type: string
|
||||
}
|
||||
interface ModVersion {
|
||||
game_versions: string[]
|
||||
loaders: string[]
|
||||
id: string
|
||||
project_id: string
|
||||
author_id: string
|
||||
featured: boolean
|
||||
name: string
|
||||
version_number: string
|
||||
changelog: string
|
||||
changelog_url: string
|
||||
date_published: string
|
||||
downloads: number
|
||||
version_type: string
|
||||
status: string
|
||||
files: File[]
|
||||
dependencies: Dependency[]
|
||||
}
|
||||
|
||||
const LOADER = 'fabric';
|
||||
|
||||
const game_version = process.argv[2] ?? '';
|
||||
const action = process.argv[3] ?? 'check';
|
||||
|
||||
const getVersions = async(slug: string): Promise<ModVersion[]> => {
|
||||
const res = await fetch(`https://api.modrinth.com/v2/project/${slug}/version`);
|
||||
|
||||
return res.ok ?
|
||||
await res.json() as ModVersion[] :
|
||||
[];
|
||||
};
|
||||
|
||||
const checkModCompat = async(slug: string): Promise<ModVersion | null> => {
|
||||
const versions = await getVersions(slug);
|
||||
|
||||
const matching = versions.filter((ver) =>
|
||||
ver.game_versions.includes(game_version) &&
|
||||
ver.loaders.includes(LOADER));
|
||||
|
||||
if (matching.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const timeSorted = matching.sort((a, b) => {
|
||||
const dateA = new Date(a.date_published);
|
||||
const dateB = new Date(b.date_published);
|
||||
|
||||
return dateB.getTime() - dateA.getTime();
|
||||
});
|
||||
|
||||
return timeSorted.some((v) => v.version_type === 'release') ?
|
||||
timeSorted.filter((v) => v.version_type === 'release')[0] :
|
||||
timeSorted[0];
|
||||
};
|
||||
|
||||
const getDownloadUrls = (version: ModVersion): string[] => version.files.map((file) => file.url);
|
||||
|
||||
const showModDownloadUrls = async(modName: string): Promise<boolean> => {
|
||||
const ver = await checkModCompat(modName);
|
||||
|
||||
if (ver) {
|
||||
const urls = getDownloadUrls(ver);
|
||||
|
||||
console.log(`\n${modName}:`, urls);
|
||||
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const download = async(url: string, path: string) => Readable
|
||||
.fromWeb((await fetch(url)).body!).pipe(createWriteStream(path));
|
||||
|
||||
const main = () => {
|
||||
const mods = [
|
||||
'badpackets',
|
||||
'c2me-fabric',
|
||||
'cloth-config',
|
||||
'clumps',
|
||||
'fabric-api',
|
||||
'ferrite-core',
|
||||
'leaves-be-gone',
|
||||
'lithium',
|
||||
'modernfix',
|
||||
'no-chat-reports',
|
||||
'noisium',
|
||||
'vmp-fabric',
|
||||
'wthit',
|
||||
];
|
||||
|
||||
if (action === 'check') {
|
||||
mods.forEach(async(modName) => {
|
||||
if (!(await showModDownloadUrls(modName))) {
|
||||
console.error(`No matching releases of ${modName} were found for ${game_version}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (action === 'download') {
|
||||
rmSync('./out', { force: true, recursive: true });
|
||||
mkdirSync('./out');
|
||||
|
||||
mods.forEach(async(modName) => {
|
||||
const ver = await checkModCompat(modName);
|
||||
|
||||
if (ver === null) {
|
||||
console.error(`No matching releases of ${modName} were found for ${game_version}`);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const fileName =
|
||||
`${modName}-${ver.version_number}.jar`;
|
||||
|
||||
console.log(`Downloading ${fileName}`);
|
||||
|
||||
await download(
|
||||
ver.files[0].url,
|
||||
`./out/${fileName}`,
|
||||
);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
main();
|
|
@ -1,10 +0,0 @@
|
|||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"extends": "../config/tsconfig.base.json",
|
||||
"includes": [
|
||||
"*.ts",
|
||||
"**/*.ts",
|
||||
"*.js",
|
||||
"**/*.js"
|
||||
]
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
{inputs, ...}: (final: prev: {
|
||||
appsPackages = let
|
||||
inherit (final.lib) listToAttrs nameValuePair;
|
||||
|
||||
buildApp = attrs: (final.callPackage ./buildApp.nix ({} // inputs // attrs));
|
||||
callPackage = file: final.callPackage file ({inherit buildApp;} // inputs);
|
||||
in
|
||||
listToAttrs (map (x: nameValuePair x (callPackage ./${x})) [
|
||||
"extract-subs"
|
||||
"gen-docs"
|
||||
"list2series"
|
||||
"mc-mods"
|
||||
"pin-inputs"
|
||||
"update-sources"
|
||||
]);
|
||||
})
|
|
@ -1,3 +0,0 @@
|
|||
use flake $FLAKE#node
|
||||
(cd ../config; npm ci)
|
||||
npm ci
|
|
@ -1,11 +0,0 @@
|
|||
{buildApp, ...}:
|
||||
buildApp {
|
||||
src = ./.;
|
||||
npmDepsHash = "sha256-O5rNGEtBoH4itUjUG9dX3EPAEGYkQxPz1FePohLLKuA=";
|
||||
|
||||
runtimeInputs = [];
|
||||
|
||||
meta.description = ''
|
||||
Takes a list of inputs to pin to their current rev in `flake.lock`.
|
||||
'';
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
import eslintConf from 'eslint-conf';
|
||||
|
||||
export default eslintConf;
|
1533
apps/pin-inputs/package-lock.json
generated
1533
apps/pin-inputs/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -1,20 +0,0 @@
|
|||
{
|
||||
"name": "pin-inputs",
|
||||
"version": "0.0.0",
|
||||
"bin": "out/bin/app.cjs",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "node_ver=$(node -v); esbuild src/app.ts --bundle --platform=node --target=\"node${node_ver:1:2}\" --outfile=out/bin/app.cjs"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/node": "22.13.14",
|
||||
"esbuild": "0.25.1",
|
||||
"eslint": "9.23.0",
|
||||
"jiti": "2.4.2",
|
||||
"pkg-types": "2.1.0",
|
||||
"typescript": "5.8.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint-conf": "file:../config"
|
||||
}
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
import { readFileSync, writeFileSync } from 'fs';
|
||||
|
||||
export const replaceInFile = (replace: RegExp, replacement: string, file: string) => {
|
||||
const fileContents = readFileSync(file);
|
||||
|
||||
const replaced = fileContents.toString().replace(replace, replacement);
|
||||
|
||||
writeFileSync(file, replaced);
|
||||
};
|
||||
|
||||
/* Constants */
|
||||
const FLAKE = process.env.FLAKE;
|
||||
|
||||
if (!FLAKE) {
|
||||
console.error('Environment variable FLAKE not found');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const FLAKE_LOCK = JSON.parse(readFileSync(`${FLAKE}/flake.lock`, 'utf8')).nodes;
|
||||
const INPUT_REVS = new Map<string, string>();
|
||||
|
||||
Object.entries(FLAKE_LOCK).forEach(([key, val]) => {
|
||||
if (key !== 'root') {
|
||||
// eslint-disable-next-line
|
||||
INPUT_REVS.set(key, (val as any).locked.rev);
|
||||
}
|
||||
});
|
||||
|
||||
const INPUTS = process.argv.slice(2);
|
||||
|
||||
|
||||
/**
|
||||
* Gets the commit hash of the specified input in this flake.
|
||||
*
|
||||
* @param input the name of the input
|
||||
* @returns the commit hash
|
||||
*/
|
||||
const getCurrentRev = (input: string): string => {
|
||||
if (!INPUT_REVS.has(input)) {
|
||||
throw new Error(`Input ${input} could not be found.`);
|
||||
}
|
||||
|
||||
return INPUT_REVS.get(input) as string;
|
||||
};
|
||||
|
||||
INPUTS.forEach((input) => {
|
||||
try {
|
||||
const inputsFile = `${FLAKE}/inputs/default.nix`;
|
||||
const rev = getCurrentRev(input);
|
||||
|
||||
const msg = ['FIX', 'ME'].join('');
|
||||
|
||||
replaceInFile(
|
||||
new RegExp(`(\\n[ ]*)${input} =.*\\n.*\\n.*`),
|
||||
`$&\n$1 # ${msg}: $1 rev = "${rev}";`,
|
||||
inputsFile,
|
||||
);
|
||||
}
|
||||
catch (e) {
|
||||
console.error((e as Error).message);
|
||||
}
|
||||
});
|
|
@ -1,10 +0,0 @@
|
|||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"extends": "../config/tsconfig.base.json",
|
||||
"includes": [
|
||||
"*.ts",
|
||||
"**/*.ts",
|
||||
"*.js",
|
||||
"**/*.js"
|
||||
]
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
use flake $FLAKE#node
|
||||
(cd ../config; npm ci)
|
||||
npm ci
|
|
@ -1,32 +0,0 @@
|
|||
{
|
||||
buildApp,
|
||||
callPackage,
|
||||
curl,
|
||||
findutils,
|
||||
go,
|
||||
jq,
|
||||
nix-update,
|
||||
nodejs_latest,
|
||||
prefetch-npm-deps,
|
||||
...
|
||||
}:
|
||||
buildApp {
|
||||
src = ./.;
|
||||
npmDepsHash = "sha256-VkJXHhMLlRNCQvK1rP3bcXfkwrsSnBTDUuE6rpzPFyk=";
|
||||
|
||||
runtimeInputs = [
|
||||
curl
|
||||
findutils
|
||||
go
|
||||
jq
|
||||
nix-update
|
||||
nodejs_latest
|
||||
prefetch-npm-deps
|
||||
(callPackage ../../modules/docker/updateImage.nix {})
|
||||
];
|
||||
|
||||
meta.description = ''
|
||||
Updates all derivation sources in this repository and
|
||||
generates a commit message for the changes made.
|
||||
'';
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
import eslintConf from 'eslint-conf';
|
||||
|
||||
export default eslintConf;
|
1533
apps/update-sources/package-lock.json
generated
1533
apps/update-sources/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -1,20 +0,0 @@
|
|||
{
|
||||
"name": "update-sources",
|
||||
"version": "0.0.0",
|
||||
"bin": "out/bin/app.cjs",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "node_ver=$(node -v); esbuild src/app.ts --bundle --platform=node --target=\"node${node_ver:1:2}\" --outfile=out/bin/app.cjs"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/node": "22.13.14",
|
||||
"esbuild": "0.25.1",
|
||||
"eslint": "9.23.0",
|
||||
"jiti": "2.4.2",
|
||||
"pkg-types": "2.1.0",
|
||||
"typescript": "5.8.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint-conf": "file:../config"
|
||||
}
|
||||
}
|
|
@ -1,193 +0,0 @@
|
|||
import { spawnSync } from 'node:child_process';
|
||||
import { writeFileSync } from 'node:fs';
|
||||
|
||||
import { parseArgs } from './lib';
|
||||
|
||||
import { updateDocker } from './docker';
|
||||
import { updateFirefoxAddons } from '././firefox';
|
||||
import { updateFlakeInputs } from './flake';
|
||||
import updateNodeModules from './node-modules';
|
||||
|
||||
import {
|
||||
runNixUpdate,
|
||||
updateCaddyPlugins,
|
||||
updateVuetorrent,
|
||||
} from './misc';
|
||||
|
||||
|
||||
/* Constants */
|
||||
const FLAKE = process.env.FLAKE;
|
||||
|
||||
if (!FLAKE) {
|
||||
console.error('Env var FLAKE not found');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const args = parseArgs();
|
||||
|
||||
const main = async() => {
|
||||
if (args['c'] || args['custom-sidebar']) {
|
||||
console.log(runNixUpdate('scopedPackages', 'lovelace-components', 'custom-sidebar'));
|
||||
}
|
||||
|
||||
if (args['cp'] || args['caddy-plugins']) {
|
||||
console.log(updateCaddyPlugins());
|
||||
}
|
||||
|
||||
if (args['d'] || args['docker']) {
|
||||
console.log(updateDocker());
|
||||
}
|
||||
|
||||
if (args['f'] || args['firefox']) {
|
||||
console.log(updateFirefoxAddons());
|
||||
}
|
||||
|
||||
if (args['fcft']) {
|
||||
console.log(runNixUpdate('fcft'));
|
||||
}
|
||||
|
||||
if (args['h'] || args['homepage']) {
|
||||
console.log(runNixUpdate('homepage'));
|
||||
}
|
||||
|
||||
if (args['i'] || args['inputs']) {
|
||||
console.log(updateFlakeInputs());
|
||||
}
|
||||
|
||||
if (args['j'] || args['jmusicbot']) {
|
||||
console.log(runNixUpdate('jmusicbot'));
|
||||
}
|
||||
|
||||
if (args['m'] || args['material-rounded-theme']) {
|
||||
console.log(runNixUpdate('scopedPackages', 'lovelace-components', 'material-rounded-theme'));
|
||||
}
|
||||
|
||||
if (args['n'] || args['node_modules']) {
|
||||
console.log(await updateNodeModules());
|
||||
}
|
||||
|
||||
if (args['p'] || args['pam-fprint-grosshack']) {
|
||||
console.log(runNixUpdate('pam-fprint-grosshack'));
|
||||
}
|
||||
|
||||
if (args['ph'] || args['protonhax']) {
|
||||
console.log(runNixUpdate('protonhax'));
|
||||
}
|
||||
|
||||
if (args['s'] || args['some-sass-language-server']) {
|
||||
console.log(runNixUpdate('some-sass-language-server'));
|
||||
}
|
||||
|
||||
if (args['t'] || args['trash-d']) {
|
||||
console.log(runNixUpdate('trash-d'));
|
||||
}
|
||||
|
||||
if (args['v'] || args['vuetorrent']) {
|
||||
console.log(updateVuetorrent());
|
||||
}
|
||||
|
||||
if (args['a'] || args['all']) {
|
||||
// Update this first because of nix run cmd
|
||||
const firefoxOutput = updateFirefoxAddons();
|
||||
|
||||
console.log(firefoxOutput);
|
||||
|
||||
|
||||
const flakeOutput = updateFlakeInputs();
|
||||
|
||||
console.log(flakeOutput);
|
||||
|
||||
|
||||
const dockerOutput = updateDocker();
|
||||
|
||||
console.log(dockerOutput);
|
||||
|
||||
|
||||
const nodeModulesOutput = await updateNodeModules();
|
||||
|
||||
console.log(nodeModulesOutput);
|
||||
|
||||
|
||||
const vuetorrentOutput = updateVuetorrent();
|
||||
|
||||
console.log(vuetorrentOutput);
|
||||
|
||||
|
||||
const caddyPluginsOutput = updateCaddyPlugins();
|
||||
|
||||
console.log(caddyPluginsOutput);
|
||||
|
||||
|
||||
// nix-update executions
|
||||
let nixUpdateOutputs = '';
|
||||
|
||||
const updatePackage = (
|
||||
attr: string,
|
||||
scope?: string,
|
||||
scopeAttr?: string,
|
||||
): void => {
|
||||
const execution = runNixUpdate(attr, scope, scopeAttr);
|
||||
|
||||
nixUpdateOutputs += execution.stdout;
|
||||
console.log(execution.stderr);
|
||||
console.log(execution.stdout);
|
||||
};
|
||||
|
||||
updatePackage('fcft');
|
||||
updatePackage('homepage');
|
||||
updatePackage('jmusicbot');
|
||||
updatePackage('pam-fprint-grosshack');
|
||||
updatePackage('protonhax');
|
||||
updatePackage('some-sass-language-server');
|
||||
updatePackage('trash-d');
|
||||
updatePackage('scopedPackages', 'lovelace-components', 'custom-sidebar');
|
||||
updatePackage('scopedPackages', 'lovelace-components', 'material-rounded-theme');
|
||||
|
||||
|
||||
spawnSync('nixFastBuild', [], {
|
||||
shell: true,
|
||||
stdio: [process.stdin, process.stdout, process.stderr],
|
||||
});
|
||||
|
||||
const indentOutput = (output: string): string => {
|
||||
return ` ${output.split('\n').join('\n ')}`;
|
||||
};
|
||||
|
||||
const output = [
|
||||
'chore: update sources\n\n',
|
||||
];
|
||||
|
||||
if (flakeOutput.length > 5) {
|
||||
output.push(`Flake Inputs:\n${indentOutput(flakeOutput)}\n\n`);
|
||||
}
|
||||
if (dockerOutput.length > 5) {
|
||||
output.push(`Docker Images:\n${indentOutput(dockerOutput)}\n`);
|
||||
}
|
||||
if (firefoxOutput.length > 5) {
|
||||
output.push(`Firefox Addons:\n${indentOutput(firefoxOutput)}\n\n`);
|
||||
}
|
||||
if (nodeModulesOutput.length > 5) {
|
||||
output.push(`Node modules:\n${indentOutput(nodeModulesOutput)}\n`);
|
||||
}
|
||||
if (vuetorrentOutput.length > 5) {
|
||||
output.push(`Misc Sources:\n${indentOutput(vuetorrentOutput)}\n\n`);
|
||||
}
|
||||
if (caddyPluginsOutput.length > 5) {
|
||||
output.push(`Caddy Plugins:\n${indentOutput(caddyPluginsOutput)}\n\n`);
|
||||
}
|
||||
if (nixUpdateOutputs.length > 5) {
|
||||
output.push(`nix-update executions:\n${indentOutput(nixUpdateOutputs)}\n`);
|
||||
}
|
||||
|
||||
if (args['f']) {
|
||||
writeFileSync(args['f'] as string, output.join(''));
|
||||
}
|
||||
else {
|
||||
console.log(output.join(''));
|
||||
}
|
||||
}
|
||||
|
||||
spawnSync('alejandra', ['-q', FLAKE], { shell: true });
|
||||
};
|
||||
|
||||
main();
|
|
@ -1,33 +0,0 @@
|
|||
import { readdirSync } from 'node:fs';
|
||||
import { spawnSync } from 'node:child_process';
|
||||
|
||||
|
||||
/* Constants */
|
||||
const FLAKE = process.env.FLAKE;
|
||||
|
||||
const updateImages = (imagePath: string): string | undefined => {
|
||||
console.log(`Updating ${imagePath.split('/').at(-1)} images`);
|
||||
|
||||
const out = spawnSync('updateImages', [imagePath], { shell: true }).stdout.toString();
|
||||
|
||||
if (!out.startsWith('# Locked')) {
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
export const updateDocker = () => {
|
||||
let updates = '';
|
||||
|
||||
updates += updateImages(`${FLAKE}/configurations/nos/modules/jellyfin`) ?? '';
|
||||
updates += updateImages(`${FLAKE}/configurations/homie/modules/home-assistant/netdaemon`) ?? '';
|
||||
|
||||
const DIR = `${FLAKE}/configurations/nos/modules/docker`;
|
||||
|
||||
readdirSync(DIR, { withFileTypes: true, recursive: true }).forEach((path) => {
|
||||
if (path.name === 'compose.nix') {
|
||||
updates += updateImages(path.parentPath) ?? '';
|
||||
}
|
||||
});
|
||||
|
||||
return updates;
|
||||
};
|
|
@ -1,61 +0,0 @@
|
|||
import { spawnSync } from 'node:child_process';
|
||||
import { readFileSync } from 'node:fs';
|
||||
|
||||
|
||||
/* Constants */
|
||||
const FLAKE = process.env.FLAKE;
|
||||
|
||||
export const updateFirefoxAddons = () => {
|
||||
console.log('Updating firefox addons using mozilla-addons-to-nix');
|
||||
|
||||
const DIR = `${FLAKE}/scopedPackages/firefox-addons`;
|
||||
const GENERATED_FILE = `${DIR}/generated-firefox-addons.nix`;
|
||||
const SLUGS = `${DIR}/addons.json`;
|
||||
|
||||
const nameMap = Object.fromEntries([...JSON.parse(readFileSync(SLUGS, 'utf-8'))]
|
||||
.map((addon) => [addon.slug, addon.pname || addon.slug]));
|
||||
|
||||
const nixExpr = `'
|
||||
x: let
|
||||
inherit (builtins) attrValues filter hasAttr isAttrs map;
|
||||
in
|
||||
map (d: d.name) (filter (y:
|
||||
isAttrs y &&
|
||||
hasAttr "type" y &&
|
||||
y.type == "derivation") (attrValues x))
|
||||
'`;
|
||||
|
||||
const OLD_VERS = Object.fromEntries([...JSON.parse(spawnSync('nix', [
|
||||
'eval',
|
||||
'.#scopedPackages.x86_64-linux.firefoxAddons',
|
||||
'--apply',
|
||||
nixExpr,
|
||||
'--json',
|
||||
], { shell: true }).stdout.toString())]
|
||||
.map((p) => {
|
||||
const pname = p.replace(/-[0-9].*$/, '');
|
||||
|
||||
return [pname, p.replace(`${pname}-`, '')];
|
||||
})
|
||||
.filter((pinfo) => pinfo[0] !== 'frankerfacez'));
|
||||
|
||||
const NEW_VERS = Object.fromEntries(spawnSync(
|
||||
'nix',
|
||||
['run', 'sourcehut:~rycee/mozilla-addons-to-nix',
|
||||
SLUGS, GENERATED_FILE],
|
||||
{ shell: true },
|
||||
).stdout
|
||||
.toString()
|
||||
.split('\n')
|
||||
.map((p) => {
|
||||
const pinfo = p.replace('Fetched ', '').split(' ');
|
||||
|
||||
return [nameMap[pinfo[0]], pinfo[2]];
|
||||
}));
|
||||
|
||||
return Object.keys(OLD_VERS)
|
||||
.sort()
|
||||
.filter((pname) => OLD_VERS[pname] !== NEW_VERS[pname])
|
||||
.map((pname) => `${pname}: ${OLD_VERS[pname]} -> ${NEW_VERS[pname]}`)
|
||||
.join('\n');
|
||||
};
|
|
@ -1,45 +0,0 @@
|
|||
import { spawnSync } from 'node:child_process';
|
||||
|
||||
|
||||
/* Constants */
|
||||
const FLAKE = process.env.FLAKE;
|
||||
|
||||
export const updateFlakeInputs = () => {
|
||||
const output = spawnSync(
|
||||
`git restore flake.lock &> /dev/null; nix flake update --flake ${FLAKE}` +
|
||||
' |& grep -v "warning: updating lock file" |& grep -v "unpacking"',
|
||||
[],
|
||||
{ shell: true },
|
||||
).stdout
|
||||
.toString()
|
||||
// Add an extra blank line between inputs
|
||||
.split('\n•')
|
||||
// Filter out some inputs
|
||||
.filter((input) => ![
|
||||
'systems',
|
||||
'flake-compat',
|
||||
'flake-utils',
|
||||
'flake-parts',
|
||||
'treefmt-nix',
|
||||
'lib-aggregate',
|
||||
'lib-aggregate/nixpkgs-lib',
|
||||
'nix-gaming/umu',
|
||||
'nix-github-actions',
|
||||
'pre-commit-hooks',
|
||||
].some((inputName) => input.startsWith(` Updated input '${inputName}'`)))
|
||||
.join('\n\n•')
|
||||
// help readability of git revs
|
||||
.split('\n')
|
||||
.map((l) => l
|
||||
.replace(
|
||||
/\/(.{40})\?narHash=sha256[^']*(.*)/,
|
||||
(_, backref1, backref2) => `${backref2} rev: ${backref1}`,
|
||||
)
|
||||
.replace(
|
||||
/\?ref.*&rev=(.{40})[^'&]*(.*)/,
|
||||
(_, backref1, backref2) => `${backref2} rev: ${backref1}`,
|
||||
))
|
||||
.join('\n');
|
||||
|
||||
return output;
|
||||
};
|
|
@ -1,43 +0,0 @@
|
|||
import { spawnSync } from 'node:child_process';
|
||||
import { readFileSync, writeFileSync } from 'node:fs';
|
||||
|
||||
|
||||
export const parseArgs = () => {
|
||||
const args = {} as Record<string, unknown>;
|
||||
let lastFlag: string | null = null;
|
||||
|
||||
for (let i = 2; i < process.argv.length; ++i) {
|
||||
const arg = process.argv[i];
|
||||
|
||||
if (arg.toString().startsWith('-')) {
|
||||
lastFlag = arg.toString().replace(/^-{1,2}/, '');
|
||||
args[lastFlag] = true;
|
||||
}
|
||||
else if (lastFlag) {
|
||||
args[lastFlag] = arg;
|
||||
lastFlag = null;
|
||||
}
|
||||
else {
|
||||
console.error(`Could not parse args: ${arg.toString()}`);
|
||||
}
|
||||
}
|
||||
|
||||
return args;
|
||||
};
|
||||
|
||||
export const parseFetchurl = (url: string) => JSON.parse(spawnSync(
|
||||
'nix', ['store', 'prefetch-file', '--refresh', '--json',
|
||||
'--hash-type', 'sha256', url, '--name', '"escaped"'], { shell: true },
|
||||
).stdout.toString()).hash;
|
||||
|
||||
export const replaceInFile = (replace: RegExp, replacement: string, file: string) => {
|
||||
const fileContents = readFileSync(file);
|
||||
|
||||
const replaced = fileContents.toString().replace(replace, replacement);
|
||||
|
||||
writeFileSync(file, replaced);
|
||||
};
|
||||
|
||||
export const npmRun = (args: string[], workspaceDir: string) => spawnSync(
|
||||
'npm', args, { cwd: workspaceDir },
|
||||
).stdout.toString();
|
|
@ -1,161 +0,0 @@
|
|||
import { writeFileSync } from 'node:fs';
|
||||
import { spawnSync } from 'node:child_process';
|
||||
|
||||
import { parseFetchurl, replaceInFile } from './lib';
|
||||
|
||||
|
||||
/* Constants */
|
||||
const FLAKE = process.env.FLAKE;
|
||||
|
||||
const genVueText = (
|
||||
version: string,
|
||||
hash: string,
|
||||
url: string,
|
||||
) => `# This file was autogenerated. DO NOT EDIT!
|
||||
{
|
||||
version = "${version}";
|
||||
url = "${url}";
|
||||
hash = "${hash}";
|
||||
}
|
||||
`;
|
||||
|
||||
export const updateVuetorrent = () => {
|
||||
const FILE = `${FLAKE}/configurations/nos/modules/qbittorrent/vuetorrent.nix`;
|
||||
|
||||
const OLD_VERSION = JSON.parse(spawnSync('nix',
|
||||
['eval', '-f', FILE, '--json'],
|
||||
{ shell: true }).stdout.toString()).version;
|
||||
|
||||
const VERSION = JSON.parse(spawnSync('curl',
|
||||
['-s', 'https://api.github.com/repos/VueTorrent/VueTorrent/releases/latest'],
|
||||
{ shell: true }).stdout.toString()).tag_name.replace('v', '');
|
||||
|
||||
const URL = `https://github.com/VueTorrent/VueTorrent/releases/download/v${VERSION}/vuetorrent.zip`;
|
||||
const HASH = parseFetchurl(URL);
|
||||
|
||||
const fileText = genVueText(VERSION, HASH, URL);
|
||||
|
||||
writeFileSync(FILE, fileText);
|
||||
|
||||
return OLD_VERSION !== VERSION ? `Vuetorrent: ${OLD_VERSION} -> ${VERSION}` : '';
|
||||
};
|
||||
|
||||
|
||||
const getAttrVersion = (attr: string): string => spawnSync('nix',
|
||||
['eval', '--raw', `${FLAKE}#${attr}.version`],
|
||||
{ shell: true }).stdout.toString();
|
||||
|
||||
export const runNixUpdate = (
|
||||
attr: string,
|
||||
scope?: string,
|
||||
scopeAttr?: string,
|
||||
): { stdout: string, stderr: string } => {
|
||||
const getJsonArray = (jsonObj: string) => Array(JSON.parse(jsonObj))[0].slice(1).join(' ');
|
||||
|
||||
const realAttr = scope ? `${attr}.x86_64-linux.${scope}.${scopeAttr}` : attr;
|
||||
const OLD_VERSION = getAttrVersion(realAttr);
|
||||
|
||||
const execOptions = spawnSync(
|
||||
`nix eval --json ${FLAKE}#${realAttr}.updateScript`,
|
||||
[],
|
||||
{ shell: true, cwd: FLAKE },
|
||||
);
|
||||
|
||||
const options = execOptions.status === 0 ?
|
||||
execOptions.stdout.toString().startsWith('[') ?
|
||||
getJsonArray(execOptions.stdout.toString()) :
|
||||
'-u' :
|
||||
'';
|
||||
|
||||
const execution = spawnSync(
|
||||
`nix-update --flake ${realAttr} ${options} --quiet --commit-message | head -n 1`,
|
||||
[],
|
||||
{ shell: true, cwd: FLAKE },
|
||||
);
|
||||
|
||||
const NEW_VERSION = getAttrVersion(realAttr);
|
||||
|
||||
return {
|
||||
stdout: OLD_VERSION !== NEW_VERSION ?
|
||||
scope ?
|
||||
execution.stdout.toString().replaceAll(`${attr}.x86_64-linux.${scope}.`, '') :
|
||||
execution.stdout.toString() :
|
||||
'',
|
||||
stderr: execution.stderr.toString(),
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
const genPluginsText = (
|
||||
plugins: Record<string, { url: string, version: string }>,
|
||||
) => `# This file was autogenerated. DO NOT EDIT!
|
||||
{
|
||||
plugins = {
|
||||
${Object.entries(plugins)
|
||||
.map(([key, value]) => `
|
||||
${key} = {
|
||||
url = "${value.url}";
|
||||
version = "${value.version}";
|
||||
};
|
||||
`)
|
||||
.join('')}
|
||||
};
|
||||
|
||||
hash = "";
|
||||
}
|
||||
`;
|
||||
|
||||
export const updateCaddyPlugins = () => {
|
||||
let updates = '';
|
||||
const dir = `${FLAKE}/configurations/cluster/modules/caddy`;
|
||||
|
||||
// Setup workspace
|
||||
spawnSync(
|
||||
[
|
||||
'rm -rf /tmp/update-caddy',
|
||||
'mkdir -p /tmp/update-caddy',
|
||||
'cd /tmp/update-caddy || exit 1',
|
||||
'go mod init temp',
|
||||
].join('; '),
|
||||
[],
|
||||
{ shell: true, cwd: '/tmp' },
|
||||
);
|
||||
|
||||
const plugins = JSON.parse(spawnSync('nix',
|
||||
['eval', '-f', `${dir}/plugins.nix`, '--json'],
|
||||
{ shell: true }).stdout.toString()).plugins as Record<string, { url: string, version: string }>;
|
||||
|
||||
// Get most recent versions of plugins
|
||||
Object.entries(plugins).forEach(([key, value]) => {
|
||||
const NEW_VERSION = spawnSync([
|
||||
'go mod init temp > /dev/null',
|
||||
`go get ${value.url} > /dev/null`,
|
||||
`grep '${value.url}' go.mod`,
|
||||
].join('; '), [], { shell: true, cwd: '/tmp/update-caddy' })
|
||||
.stdout
|
||||
.toString()
|
||||
.trim()
|
||||
.replace(' // indirect', '')
|
||||
.split(' ')[1];
|
||||
|
||||
if (plugins[key].version !== NEW_VERSION) {
|
||||
updates += `${key}: ${plugins[key].version} -> ${NEW_VERSION}`;
|
||||
plugins[key].version = NEW_VERSION;
|
||||
}
|
||||
});
|
||||
|
||||
writeFileSync(`${dir}/plugins.nix`, genPluginsText(plugins));
|
||||
|
||||
// Get new hash
|
||||
const caddyPkgAttr = 'nixosConfigurations.thingone.config.services.caddy.package';
|
||||
|
||||
const NEW_HASH = spawnSync(
|
||||
`nix build "$FLAKE#${caddyPkgAttr}" |& sed -n 's/.*got: *//p'`,
|
||||
[],
|
||||
{ shell: true },
|
||||
).stdout.toString().trim();
|
||||
|
||||
replaceInFile(/hash = ".*";/, `hash = "${NEW_HASH}";`, `${dir}/plugins.nix`);
|
||||
|
||||
return updates;
|
||||
};
|
|
@ -1,121 +0,0 @@
|
|||
import { readPackageJSON, writePackageJSON } from 'pkg-types';
|
||||
import { accessSync, constants, existsSync } from 'node:fs';
|
||||
import { spawnSync } from 'node:child_process';
|
||||
|
||||
import { replaceInFile, npmRun } from './lib';
|
||||
|
||||
|
||||
/* Constants */
|
||||
const FLAKE = process.env.FLAKE as string;
|
||||
|
||||
const PINS = new Map([]);
|
||||
|
||||
|
||||
const updatePackageJson = async(workspaceDir: string, updates: object) => {
|
||||
const currentPackageJson = await readPackageJSON(`${workspaceDir}/package.json`);
|
||||
|
||||
const outdated = JSON.parse(npmRun(['outdated', '--json'], workspaceDir));
|
||||
|
||||
const updateDeps = (deps: string) => {
|
||||
Object.keys(currentPackageJson[deps]).forEach(async(dep) => {
|
||||
if (dep === 'astal') {
|
||||
const latestCommit = JSON.parse(spawnSync('curl',
|
||||
['-s', 'https://api.github.com/repos/Aylur/astal/commits/main'],
|
||||
{ shell: true }).stdout.toString()).sha;
|
||||
|
||||
currentPackageJson[deps][dep] = `https://gitpkg.vercel.app/Aylur/astal/lang/gjs/src?${latestCommit}`;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (PINS.has(dep)) {
|
||||
currentPackageJson[deps][dep] = PINS.get(dep);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const versions = outdated[dep];
|
||||
const current = versions?.wanted || versions?.current;
|
||||
|
||||
if (!current) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (current !== versions.latest) {
|
||||
updates[dep] = `${current} -> ${versions.latest}`;
|
||||
}
|
||||
|
||||
currentPackageJson[deps][dep] = versions.latest;
|
||||
});
|
||||
};
|
||||
|
||||
if (currentPackageJson.dependencies) {
|
||||
updateDeps('dependencies');
|
||||
}
|
||||
|
||||
if (currentPackageJson.devDependencies) {
|
||||
updateDeps('devDependencies');
|
||||
}
|
||||
|
||||
await writePackageJSON(`${workspaceDir}/package.json`, currentPackageJson);
|
||||
};
|
||||
|
||||
|
||||
const prefetchNpmDeps = (workspaceDir: string): string => {
|
||||
npmRun(['update', '--package-lock-only'], workspaceDir);
|
||||
|
||||
return spawnSync(
|
||||
'prefetch-npm-deps',
|
||||
[`${workspaceDir}/package-lock.json`],
|
||||
).stdout.toString().replace('\n', '');
|
||||
};
|
||||
|
||||
|
||||
export default async() => {
|
||||
console.log('Updating node modules');
|
||||
|
||||
const updates = {};
|
||||
|
||||
const packages = spawnSync('find', [FLAKE, '-name', 'package.json']).stdout.toString().split('\n')
|
||||
.filter((f) => f !== '')
|
||||
.filter((f) => ![
|
||||
'.direnv',
|
||||
'node_modules',
|
||||
'results',
|
||||
].some((dirName) => f.includes(dirName)));
|
||||
|
||||
for (const path of packages) {
|
||||
console.log(path);
|
||||
|
||||
try {
|
||||
accessSync(path, constants.R_OK | constants.W_OK);
|
||||
|
||||
const parentPath = path.replace('/package.json', '');
|
||||
|
||||
await updatePackageJson(parentPath, updates);
|
||||
|
||||
if (existsSync(`${parentPath}/default.nix`)) {
|
||||
const hash = prefetchNpmDeps(parentPath);
|
||||
|
||||
replaceInFile(
|
||||
/npmDepsHash = ".*";/,
|
||||
`npmDepsHash = "${hash}";`,
|
||||
`${parentPath}/default.nix`,
|
||||
);
|
||||
}
|
||||
|
||||
// Make sure we update the apps' config package-lock.json
|
||||
if (parentPath.includes('apps/config')) {
|
||||
npmRun(['i'], parentPath);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
console.warn(`Could not write to ${path}`);
|
||||
console.warn(e);
|
||||
}
|
||||
}
|
||||
|
||||
return Object.entries(updates)
|
||||
.map(([key, dep]) => `${key}: ${dep}`)
|
||||
.join('\n');
|
||||
};
|
|
@ -1,10 +0,0 @@
|
|||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"extends": "../config/tsconfig.base.json",
|
||||
"includes": [
|
||||
"*.ts",
|
||||
"**/*.ts",
|
||||
"*.js",
|
||||
"**/*.js"
|
||||
]
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
# NixosConfigurations
|
||||
|
||||
This directory contains every device's main configuration file, their `hardware-configuration.nix` and some custom modules
|
||||
unique to them.
|
||||
|
||||
## List of my devices
|
||||
|
||||
| Name | Model / Specs | Description |
|
||||
| --------- | ------------- | ------------------------------------------------------------------------------------------------ |
|
||||
| `android` | OnePlus 9 Pro | [Nix-On-Droid](https://github.com/nix-community/nix-on-droid) configuration for my OnePlus 9 Pro |
|
||||
| `bbsteamie` | 512GB OLED | My wife's SteamDeck that has a pink case (it took a lot of convincing for this) |
|
||||
| `binto` | NVIDIA 3070 with Ryzen 7 3700X | Desktop PC with a multi-monitor setup |
|
||||
| `homie` | Lenovo Thinkcentre M910q | Mini PC that serves as a Home-assistant server |
|
||||
| `live-image` | USB key | Basic configuration that serves as my custom ISO target |
|
||||
| `nos` | NVIDIA 3060 with i5-3600 | Custom built NAS and seedbox for Linux ISOs ;) |
|
||||
| `servivi` | Headless Ryzen 5 3600 | Gaming PC in a previous life, it is now used as a build farm and hosts game servers |
|
||||
| `thingone` | Lenovo ThinkCentre M900 | Mini PC that makes use of [NixOS-pcsd](https://github.com/matt1432/nixos-pcsd) to form a cluster with its twin. Files located in `cluster` |
|
||||
| `thingtwo` | Lenovo ThinkCentre M900 | Mini PC that makes use of [NixOS-pcsd](https://github.com/matt1432/nixos-pcsd) to form a cluster with its twin. Files located in `cluster` |
|
||||
| `wim` | ThinkPad L13 Yoga Gen 3 (Ryzen 7 PRO 5875U) | 2-1 Lenovo Laptop that I use for university |
|
|
@ -1,56 +0,0 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
inherit (lib) attrValues concatStringsSep;
|
||||
in {
|
||||
imports = [./nix-on-droid.nix];
|
||||
|
||||
environment.variables.FLAKE = "/data/data/com.termux.nix/files/home/.nix";
|
||||
|
||||
terminal.font = "${
|
||||
pkgs.nerd-fonts.jetbrains-mono
|
||||
}/share/fonts/truetype/NerdFonts/JetBrainsMono/JetBrainsMonoNerdFontMono-Regular.ttf";
|
||||
|
||||
environment.packages = [
|
||||
(pkgs.writeShellApplication {
|
||||
name = "switch";
|
||||
|
||||
runtimeInputs = attrValues {
|
||||
inherit
|
||||
(pkgs)
|
||||
coreutils
|
||||
nix-output-monitor
|
||||
nvd
|
||||
;
|
||||
};
|
||||
|
||||
text = ''
|
||||
oldProfile=$(realpath /nix/var/nix/profiles/per-user/nix-on-droid/profile)
|
||||
|
||||
nix-on-droid ${concatStringsSep " " [
|
||||
"switch"
|
||||
"--flake ${config.environment.variables.FLAKE}"
|
||||
"--builders ssh-ng://matt@100.64.0.7"
|
||||
''"$@"''
|
||||
"|&"
|
||||
"nom"
|
||||
]} &&
|
||||
|
||||
nvd diff "$oldProfile" "$(realpath /nix/var/nix/profiles/per-user/nix-on-droid/profile)"
|
||||
'';
|
||||
})
|
||||
];
|
||||
|
||||
environment.etcBackupExtension = ".bak";
|
||||
environment.motd = null;
|
||||
home-manager.backupFileExtension = "hm-bak";
|
||||
|
||||
# Set your time zone.
|
||||
time.timeZone = "America/Montreal";
|
||||
|
||||
# No touchy
|
||||
system.stateVersion = "23.05";
|
||||
}
|
|
@ -1,97 +0,0 @@
|
|||
{
|
||||
config,
|
||||
self,
|
||||
...
|
||||
}: {
|
||||
imports = [
|
||||
self.nixosModules.base-droid
|
||||
{
|
||||
roles.base = {
|
||||
enable = true;
|
||||
user = "nix-on-droid";
|
||||
};
|
||||
}
|
||||
|
||||
self.nixosModules.tmux
|
||||
{programs.tmux.enableCustomConf = true;}
|
||||
];
|
||||
|
||||
nix = {
|
||||
# Edit nix.conf
|
||||
extraOptions = ''
|
||||
experimental-features = nix-command flakes
|
||||
keep-outputs = true
|
||||
keep-derivations = true
|
||||
warn-dirty = false
|
||||
'';
|
||||
|
||||
substituters = [
|
||||
# Nix-community
|
||||
"https://nix-community.cachix.org"
|
||||
|
||||
# Personal cache
|
||||
"https://cache.nelim.org"
|
||||
];
|
||||
|
||||
trustedPublicKeys = [
|
||||
# Nix-community
|
||||
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
|
||||
|
||||
# Personal cache
|
||||
"cache.nelim.org:JmFqkUdH11EA9EZOFAGVHuRYp7EbsdJDHvTQzG2pPyY="
|
||||
];
|
||||
};
|
||||
|
||||
# Global hm settings
|
||||
home-manager.config = {
|
||||
imports = [
|
||||
self.homeManagerModules.neovim
|
||||
{
|
||||
programs.neovim = {
|
||||
enable = true;
|
||||
user = "nix-on-droid";
|
||||
|
||||
ideConfig = {
|
||||
enableJava = false;
|
||||
enableNix = false;
|
||||
enablePython = false;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
self.homeManagerModules.shell
|
||||
{programs.bash.enable = true;}
|
||||
|
||||
{
|
||||
programs.bash.sessionVariables = {
|
||||
FLAKE = config.environment.variables.FLAKE;
|
||||
};
|
||||
|
||||
programs.bash.shellAliases = {
|
||||
# Make ping work on nix-on-droid
|
||||
# https://github.com/nix-community/nix-on-droid/issues/185#issuecomment-1659294700
|
||||
ping = "/android/system/bin/linker64 /android/system/bin/ping";
|
||||
|
||||
# SSH
|
||||
# Desktop
|
||||
pc = "ssh -t matt@100.64.0.6 'tmux -2u new -At phone'";
|
||||
|
||||
# NAS
|
||||
nos = "ssh -t matt@100.64.0.4 'tmux -2u new -At phone'";
|
||||
|
||||
# Experimenting server
|
||||
servivi = "ssh -t matt@100.64.0.7 'tmux -2u new -At phone'";
|
||||
|
||||
# Home-assistant
|
||||
homie = "ssh -t matt@100.64.0.10 'tmux -2u new -At phone'";
|
||||
|
||||
# Cluster nodes
|
||||
thingone = "ssh -t matt@100.64.0.8 'tmux -2u new -At phone'";
|
||||
thingtwo = "ssh -t matt@100.64.0.9 'tmux -2u new -At phone'";
|
||||
};
|
||||
}
|
||||
];
|
||||
|
||||
home.stateVersion = "23.05";
|
||||
};
|
||||
}
|
|
@ -1,81 +0,0 @@
|
|||
{
|
||||
mainUser,
|
||||
self,
|
||||
...
|
||||
}: {
|
||||
# ------------------------------------------------
|
||||
# Imports
|
||||
# ------------------------------------------------
|
||||
imports = [
|
||||
./hardware-configuration.nix
|
||||
|
||||
./modules
|
||||
|
||||
self.nixosModules.base
|
||||
self.nixosModules.meta
|
||||
self.nixosModules.plymouth
|
||||
self.nixosModules.server
|
||||
];
|
||||
|
||||
# State Version: DO NOT CHANGE
|
||||
system.stateVersion = "24.11";
|
||||
|
||||
# ------------------------------------------------
|
||||
# User Settings
|
||||
# ------------------------------------------------
|
||||
users.users.${mainUser} = {
|
||||
isNormalUser = true;
|
||||
uid = 1000;
|
||||
|
||||
hashedPassword = "$y$j9T$b6YdvHx1b/HOD6Kt3Tw1W.$yIy5Km1xBViJA2kra9l38S/0auhEHPdXOMb6RBhgxID";
|
||||
|
||||
extraGroups = [
|
||||
"wheel"
|
||||
"adm"
|
||||
];
|
||||
};
|
||||
|
||||
networking = {
|
||||
hostName = "bbsteamie";
|
||||
networkmanager.enable = true;
|
||||
};
|
||||
|
||||
time.timeZone = "America/Montreal";
|
||||
|
||||
# ------------------------------------------------
|
||||
# `Self` Modules configuration
|
||||
# ------------------------------------------------
|
||||
meta = {
|
||||
roleDescription = "My wife's SteamDeck that has a pink case (it took a lot of convincing for this)";
|
||||
hardwareDescription = "512GB OLED";
|
||||
};
|
||||
|
||||
roles.base = {
|
||||
enable = true;
|
||||
user = mainUser;
|
||||
};
|
||||
|
||||
roles.server = {
|
||||
enable = true;
|
||||
user = mainUser;
|
||||
sshd.enable = true;
|
||||
};
|
||||
|
||||
boot.plymouth = {
|
||||
enable = true;
|
||||
theme = "bgrt";
|
||||
};
|
||||
|
||||
home-manager.users.${mainUser} = {
|
||||
imports = [
|
||||
self.homeManagerModules.shell
|
||||
];
|
||||
|
||||
programs = {
|
||||
bash = {
|
||||
enable = true;
|
||||
promptMainColor = "pink";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
{
|
||||
config,
|
||||
jovian,
|
||||
modulesPath,
|
||||
...
|
||||
}: {
|
||||
nixpkgs.hostPlatform = "x86_64-linux";
|
||||
|
||||
imports = [
|
||||
(modulesPath + "/installer/scan/not-detected.nix")
|
||||
jovian.nixosModules.default
|
||||
];
|
||||
|
||||
jovian = {
|
||||
steamos.useSteamOSConfig = true;
|
||||
|
||||
devices.steamdeck = {
|
||||
enable = true;
|
||||
enableGyroDsuService = true;
|
||||
};
|
||||
hardware.has.amd.gpu = true;
|
||||
};
|
||||
|
||||
boot = {
|
||||
kernelModules = ["kvm-amd"];
|
||||
initrd.availableKernelModules = ["nvme" "xhci_pci" "usbhid" "sdhci_pci"];
|
||||
|
||||
loader = {
|
||||
efi.canTouchEfiVariables = true;
|
||||
|
||||
systemd-boot = {
|
||||
enable = true;
|
||||
configurationLimit = 30;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
virtualisation.waydroid.enable = true;
|
||||
|
||||
fileSystems = {
|
||||
"/" = {
|
||||
device = "/dev/disk/by-label/NIXROOT";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
"/boot" = {
|
||||
device = "/dev/disk/by-label/NIXBOOT";
|
||||
fsType = "vfat";
|
||||
options = ["fmask=0022" "dmask=0022"];
|
||||
};
|
||||
};
|
||||
|
||||
swapDevices = [
|
||||
{
|
||||
device = "/.swapfile";
|
||||
size = 16 * 1024; # 16GB
|
||||
}
|
||||
];
|
||||
|
||||
hardware.cpu.amd.updateMicrocode = config.hardware.enableRedistributableFirmware;
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
{...}: {
|
||||
imports = [
|
||||
./desktop
|
||||
];
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
{pkgs, ...}: let
|
||||
defaultSession = "plasma";
|
||||
in {
|
||||
imports = [
|
||||
(import ./session-switching.nix defaultSession)
|
||||
(import ./steam.nix defaultSession)
|
||||
];
|
||||
|
||||
services.desktopManager.plasma6.enable = true;
|
||||
|
||||
programs = {
|
||||
kdeconnect.enable = true;
|
||||
xwayland.enable = true;
|
||||
};
|
||||
|
||||
# Flatpak support for Discover
|
||||
services.flatpak.enable = true;
|
||||
services.packagekit.enable = true;
|
||||
|
||||
# Wayland env vars
|
||||
environment.variables = {
|
||||
NIXOS_OZONE_WL = "1";
|
||||
ELECTRON_OZONE_PLATFORM_HINT = "auto";
|
||||
};
|
||||
|
||||
environment.systemPackages = builtins.attrValues {
|
||||
inherit
|
||||
(pkgs)
|
||||
firefox
|
||||
wl-clipboard
|
||||
xclip
|
||||
;
|
||||
|
||||
inherit
|
||||
(pkgs.kdePackages)
|
||||
discover
|
||||
krfb
|
||||
;
|
||||
};
|
||||
}
|
|
@ -1,81 +0,0 @@
|
|||
# How to install Palia Map and Overwolf on Linux
|
||||
|
||||
Dependencies:
|
||||
- latest GE-Proton: https://github.com/GloriousEggroll/proton-ge-custom
|
||||
- protontricks: https://github.com/Matoking/protontricks
|
||||
- protonhax: https://github.com/jcnils/protonhax
|
||||
|
||||
|
||||
## First Step: Install and run Palia at least once
|
||||
|
||||
|
||||
## Second Step: Setup Palia WINEPREFIX with latest GE-Proton
|
||||
|
||||
1. Delete prefix at /home/"$USER"/.steam/steam/steamapps/compatdata/2707930/pfx
|
||||
|
||||
```bash
|
||||
rm -r /home/"$USER"/.steam/steam/steamapps/compatdata/2707930/pfx
|
||||
```
|
||||
|
||||
2. Launch Palia with GE-Proton by going to game properties -> Compatibility -> Force the use ... -> Select GE-Proton...
|
||||
|
||||
3. Install dotnet48 and other Windows deps to allow for Overwolf installation
|
||||
|
||||
```bash
|
||||
# Force proton version of protontricks
|
||||
export PROTON_VERSION="GE-Proton9-10"
|
||||
protontricks 2707930 dotnet48
|
||||
|
||||
# If VC is needed
|
||||
protontricks 2707930 vcrun2010
|
||||
protontricks 2707930 vcrun2012
|
||||
protontricks 2707930 vcrun2013
|
||||
```
|
||||
|
||||
|
||||
## Third Step: Install Overwolf
|
||||
|
||||
1. Get this older version that worked for me here: https://overwolf.en.uptodown.com/windows/download/4714215
|
||||
|
||||
2. Install it with protontricks. Follow the GUI installer as if you were on Windows
|
||||
|
||||
```bash
|
||||
export PROTON_VERSION="GE-Proton9-10"
|
||||
protontricks-launch --appid 2707930 Downloads/overwolf-0-195-0-18.exe
|
||||
```
|
||||
|
||||
|
||||
## Fourth Step: Install Palia Map
|
||||
|
||||
1. Get the installer from here: https://www.overwolf.com/app/Leon_Machens-Palia_Map
|
||||
|
||||
2. Install it with protontricks.
|
||||
|
||||
```bash
|
||||
export PROTON_VERSION="GE-Proton9-10"
|
||||
protontricks-launch --appid 2707930 Downloads/Palia\ Map\ -\ Installer.exe
|
||||
```
|
||||
|
||||
3. An error should popup saying `Installation failed` or something along those lines.
|
||||
Close it and wait. You should see the Overwolf overlay on the left side of your screen
|
||||
with the Palia Map icon saying `Installing` and then when it's done: `Palia Map`.
|
||||
|
||||
If nothing happens, try rebooting your PC and retrying the above shell commands until it works.
|
||||
|
||||
|
||||
## Final Step: Setting it up in Steam
|
||||
|
||||
1. Add this line to Palia launch options
|
||||
```bash
|
||||
protonhax init %command%
|
||||
```
|
||||
|
||||
2. Add random non-steam game to your library and then edit its properties:
|
||||
|
||||
Change the name to `Palia Map` or anything you like
|
||||
|
||||
Change the target to this command:
|
||||
|
||||
```bash
|
||||
protonhax run 2707930 "/home/$USER/.local/share/Steam/steamapps/compatdata/2707930/pfx/drive_c/users/steamuser/AppData/Roaming/Microsoft/Windows/Start Menu/Programs/Overwolf/Palia Map.lnk"
|
||||
```
|
|
@ -1,134 +0,0 @@
|
|||
defaultSession: {
|
||||
config,
|
||||
lib,
|
||||
mainUser,
|
||||
pkgs,
|
||||
...
|
||||
}: {
|
||||
config = let
|
||||
inherit (lib) findFirst getExe mkForce;
|
||||
|
||||
restartNetwork = getExe (pkgs.writeShellApplication {
|
||||
name = "restart-network";
|
||||
runtimeInputs = with pkgs; [systemd];
|
||||
text = "systemctl restart NetworkManager";
|
||||
});
|
||||
|
||||
switch-session = pkgs.writeShellApplication {
|
||||
name = "switch-session";
|
||||
|
||||
text = ''
|
||||
mkdir -p /etc/sddm.conf.d
|
||||
|
||||
cat <<EOF | tee /etc/sddm.conf.d/autologin.conf
|
||||
[Autologin]
|
||||
User=${mainUser}
|
||||
Session=$1
|
||||
Relogin=true
|
||||
EOF
|
||||
'';
|
||||
};
|
||||
|
||||
gaming-mode = pkgs.writeShellScriptBin "gaming-mode" ''
|
||||
sudo ${pkgs.systemd}/bin/systemctl start to-gaming-mode.service
|
||||
'';
|
||||
in {
|
||||
services.displayManager.sddm = {
|
||||
enable = true;
|
||||
autoLogin.relogin = true;
|
||||
|
||||
wayland = {
|
||||
enable = true;
|
||||
compositorCommand = "kwin";
|
||||
};
|
||||
};
|
||||
|
||||
# Sets the default session at launch
|
||||
systemd.services."set-session" = {
|
||||
wantedBy = ["multi-user.target"];
|
||||
before = ["display-manager.service"];
|
||||
|
||||
path = [switch-session];
|
||||
|
||||
script = ''
|
||||
switch-session "${defaultSession}"
|
||||
'';
|
||||
};
|
||||
|
||||
# Disable getty on tty1 for seamless DE transitions
|
||||
systemd.services.display-manager.conflicts = ["getty@tty1.service"];
|
||||
|
||||
# Allows switching to gaming mode
|
||||
systemd.services."to-gaming-mode" = {
|
||||
wantedBy = mkForce [];
|
||||
|
||||
path = [switch-session];
|
||||
|
||||
script = ''
|
||||
switch-session "gamescope-wayland"
|
||||
systemctl restart display-manager
|
||||
sleep 10
|
||||
switch-session "${defaultSession}"
|
||||
'';
|
||||
};
|
||||
|
||||
security.sudo.extraRules = [
|
||||
{
|
||||
users = [mainUser];
|
||||
groups = [100];
|
||||
commands = [
|
||||
# Make it so we don't need root to switch to gaming mode
|
||||
{
|
||||
command = "${pkgs.systemd}/bin/systemctl start to-gaming-mode.service";
|
||||
options = ["SETENV" "NOPASSWD"];
|
||||
}
|
||||
# Make it so we don't need root to restart the network on launch
|
||||
{
|
||||
command = restartNetwork;
|
||||
options = ["SETENV" "NOPASSWD"];
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
|
||||
home-manager.users.${mainUser} = {
|
||||
# Add desktop entry to make it GUI friendly
|
||||
xdg.desktopEntries."Gaming Mode" = {
|
||||
name = "Gaming Mode";
|
||||
exec = getExe gaming-mode;
|
||||
icon = "steam";
|
||||
terminal = false;
|
||||
type = "Application";
|
||||
};
|
||||
|
||||
home.file."Desktop/Gaming Mode.desktop".source =
|
||||
(
|
||||
findFirst
|
||||
(x: x.meta.name == "Gaming Mode.desktop") {}
|
||||
config.home-manager.users.mariah.home.packages
|
||||
)
|
||||
+ "/share/applications/Gaming Mode.desktop";
|
||||
|
||||
# Fix remote control prompt showing up everytime
|
||||
xdg.configFile = let
|
||||
mkAutostart = name: exe: {
|
||||
"autostart/${name}.desktop".text = "[Desktop Entry]\nType=Application\nExec=${exe}";
|
||||
};
|
||||
in (
|
||||
(mkAutostart "restart-network" "sudo ${restartNetwork}")
|
||||
// (mkAutostart "steam" "steam -silent %U")
|
||||
// (mkAutostart "krfb" "krfb --nodialog %c")
|
||||
// (mkAutostart "kde-authorize-steam" (getExe (pkgs.writeShellApplication {
|
||||
name = "kde-authorize-steam";
|
||||
text = ''
|
||||
flatpak permission-set kde-authorized remote-desktop org.kde.krdpserver yes
|
||||
flatpak permission-set kde-authorized remote-desktop "" yes
|
||||
'';
|
||||
})))
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
# For accurate stack trace
|
||||
_file = ./session-switching.nix;
|
||||
}
|
|
@ -1,86 +0,0 @@
|
|||
defaultSession: {
|
||||
config,
|
||||
lib,
|
||||
mainUser,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
inherit (lib) attrValues makeSearchPathOutput;
|
||||
in {
|
||||
config = {
|
||||
# Normal Steam Stuff
|
||||
programs.steam = {
|
||||
enable = true;
|
||||
protontricks.enable = true;
|
||||
|
||||
remotePlay.openFirewall = true;
|
||||
extraCompatPackages = [
|
||||
pkgs.selfPackages.proton-ge-latest
|
||||
];
|
||||
|
||||
# https://github.com/NixOS/nixpkgs/issues/25444#issuecomment-1977416787
|
||||
extraPackages = with pkgs; [
|
||||
kdePackages.breeze
|
||||
];
|
||||
};
|
||||
|
||||
# Jovian Steam settings
|
||||
jovian.steam = {
|
||||
# Steam > Settings > System > Enable Developer Mode
|
||||
# Steam > Developer > CEF Remote Debugging
|
||||
enable = true;
|
||||
user = mainUser;
|
||||
|
||||
environment = {
|
||||
STEAM_EXTRA_COMPAT_TOOLS_PATHS =
|
||||
makeSearchPathOutput
|
||||
"steamcompattool"
|
||||
""
|
||||
config.programs.steam.extraCompatPackages;
|
||||
};
|
||||
|
||||
desktopSession = defaultSession;
|
||||
};
|
||||
|
||||
# Decky settings
|
||||
jovian.decky-loader = {
|
||||
enable = true;
|
||||
user = mainUser;
|
||||
stateDir = "/home/${mainUser}/.local/share/decky"; # Keep scoped to user
|
||||
# https://github.com/Jovian-Experiments/Jovian-NixOS/blob/1171169117f63f1de9ef2ea36efd8dcf377c6d5a/modules/decky-loader.nix#L80-L84
|
||||
|
||||
extraPackages = attrValues {
|
||||
inherit
|
||||
(pkgs)
|
||||
curl
|
||||
unzip
|
||||
util-linux
|
||||
gnugrep
|
||||
readline
|
||||
procps
|
||||
pciutils
|
||||
libpulseaudio
|
||||
;
|
||||
};
|
||||
|
||||
extraPythonPackages = p:
|
||||
with p; [
|
||||
click
|
||||
];
|
||||
};
|
||||
|
||||
# Misc Packages
|
||||
environment.systemPackages = [
|
||||
pkgs.steam-rom-manager
|
||||
pkgs.r2modman
|
||||
|
||||
pkgs.selfPackages.protonhax
|
||||
|
||||
# Ryujinx ACNH crashes on Vulkan
|
||||
pkgs.ryujinx
|
||||
];
|
||||
};
|
||||
|
||||
# For accurate stack trace
|
||||
_file = ./steam.nix;
|
||||
}
|
|
@ -1,107 +0,0 @@
|
|||
{
|
||||
mainUser,
|
||||
self,
|
||||
...
|
||||
}: {
|
||||
# ------------------------------------------------
|
||||
# Imports
|
||||
# ------------------------------------------------
|
||||
imports = [
|
||||
./hardware-configuration.nix
|
||||
|
||||
./modules
|
||||
|
||||
self.nixosModules.base
|
||||
self.nixosModules.desktop
|
||||
self.nixosModules.kmscon
|
||||
self.nixosModules.meta
|
||||
self.nixosModules.server
|
||||
];
|
||||
|
||||
# State Version: DO NOT CHANGE
|
||||
system.stateVersion = "23.11";
|
||||
|
||||
# ------------------------------------------------
|
||||
# User Settings
|
||||
# ------------------------------------------------
|
||||
users.users.${mainUser} = {
|
||||
isNormalUser = true;
|
||||
uid = 1000;
|
||||
|
||||
hashedPassword = "$y$j9T$uCv3kB5LI3Shj/5liU9cS0$4s3wWoH4iY29DLC3lJwNaIcurcjsj8L02cMY4EDtnC6";
|
||||
|
||||
extraGroups = [
|
||||
"wheel"
|
||||
"input"
|
||||
"uinput"
|
||||
"adm"
|
||||
"video"
|
||||
"libvirtd"
|
||||
"adbusers"
|
||||
];
|
||||
};
|
||||
|
||||
programs.adb.enable = true;
|
||||
|
||||
networking = {
|
||||
hostName = "binto";
|
||||
networkmanager.enable = true;
|
||||
firewall.enable = false;
|
||||
};
|
||||
|
||||
time.timeZone = "America/Montreal";
|
||||
|
||||
# ------------------------------------------------
|
||||
# `Self` Modules configuration
|
||||
# ------------------------------------------------
|
||||
meta = {
|
||||
roleDescription = "Desktop PC with a multi-monitor setup";
|
||||
hardwareDescription = "NVIDIA 3070 with Ryzen 7 3700X";
|
||||
};
|
||||
|
||||
roles.base = {
|
||||
enable = true;
|
||||
user = mainUser;
|
||||
};
|
||||
|
||||
roles.desktop = {
|
||||
enable = true;
|
||||
user = mainUser;
|
||||
|
||||
ags.enable = true;
|
||||
mainMonitor = "desc:GIGA-BYTE TECHNOLOGY CO. LTD. G27QC 0x00000B1D";
|
||||
|
||||
fontSize = 12.5;
|
||||
};
|
||||
|
||||
roles.server = {
|
||||
enable = true;
|
||||
user = mainUser;
|
||||
tailscale.enable = true;
|
||||
sshd.enable = true;
|
||||
};
|
||||
|
||||
services.kmscon.enable = true;
|
||||
|
||||
home-manager.users.${mainUser} = {
|
||||
imports = [
|
||||
self.homeManagerModules.firefox
|
||||
self.homeManagerModules.neovim
|
||||
self.homeManagerModules.shell
|
||||
];
|
||||
|
||||
programs = {
|
||||
bash = {
|
||||
enable = true;
|
||||
promptMainColor = "purple";
|
||||
};
|
||||
|
||||
firefox.enableCustomConf = true;
|
||||
|
||||
neovim = {
|
||||
enable = true;
|
||||
user = mainUser;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,117 +0,0 @@
|
|||
{
|
||||
config,
|
||||
modulesPath,
|
||||
pkgs,
|
||||
...
|
||||
}: {
|
||||
nixpkgs.hostPlatform = "x86_64-linux";
|
||||
imports = [(modulesPath + "/installer/scan/not-detected.nix")];
|
||||
|
||||
boot = {
|
||||
kernelPackages = pkgs.linuxPackages_zen;
|
||||
|
||||
kernelParams = [
|
||||
"amd_pstate=active"
|
||||
|
||||
# Remove these if I use plymouth module
|
||||
"quiet"
|
||||
"splash"
|
||||
"boot.shell_on_fail"
|
||||
"i915.fastboot=1"
|
||||
"loglevel=3"
|
||||
"rd.systemd.show_status=false"
|
||||
"rd.udev.log_level=3"
|
||||
"udev.log_priority=3"
|
||||
];
|
||||
kernelModules = ["kvm-amd"];
|
||||
|
||||
# Zenpower for ryzen cpu monitoring
|
||||
extraModulePackages = builtins.attrValues {
|
||||
inherit
|
||||
(config.boot.kernelPackages)
|
||||
v4l2loopback
|
||||
zenpower
|
||||
;
|
||||
};
|
||||
blacklistedKernelModules = ["k10temp"];
|
||||
|
||||
supportedFilesystems = ["ntfs"];
|
||||
|
||||
consoleLogLevel = 0;
|
||||
|
||||
initrd = {
|
||||
verbose = false;
|
||||
systemd.enable = true;
|
||||
availableKernelModules = ["nvme" "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod"];
|
||||
};
|
||||
|
||||
loader = {
|
||||
efi.canTouchEfiVariables = true;
|
||||
timeout = 0;
|
||||
|
||||
systemd-boot = {
|
||||
enable = true;
|
||||
consoleMode = "max";
|
||||
configurationLimit = 30;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
fileSystems = {
|
||||
"/" = {
|
||||
device = "/dev/disk/by-label/NIXROOT";
|
||||
fsType = "btrfs";
|
||||
};
|
||||
|
||||
# sudo btrfs subvolume create /@swap
|
||||
"/swap" = {
|
||||
device = "/dev/disk/by-label/NIXROOT";
|
||||
fsType = "btrfs";
|
||||
# Idk why this is the subvol
|
||||
options = ["subvol=@/@swap"];
|
||||
};
|
||||
|
||||
"/boot" = {
|
||||
device = "/dev/disk/by-label/NIXBOOT";
|
||||
fsType = "vfat";
|
||||
};
|
||||
|
||||
"/run/media/matt/Games" = {
|
||||
device = "/dev/disk/by-uuid/da62f4ee-d4a6-4fdd-ab12-9c5e131c6f30";
|
||||
fsType = "ext4";
|
||||
};
|
||||
};
|
||||
|
||||
swapDevices = [
|
||||
{
|
||||
device = "/swap/swapfile";
|
||||
size = 16 * 1024;
|
||||
}
|
||||
];
|
||||
|
||||
zramSwap.enable = true;
|
||||
|
||||
hardware = {
|
||||
cpu.amd.updateMicrocode = config.hardware.enableRedistributableFirmware;
|
||||
uinput.enable = true;
|
||||
};
|
||||
|
||||
virtualisation = {
|
||||
libvirtd.enable = true;
|
||||
spiceUSBRedirection.enable = true;
|
||||
};
|
||||
environment.systemPackages = builtins.attrValues {
|
||||
inherit
|
||||
(pkgs)
|
||||
qemu
|
||||
virtiofsd
|
||||
;
|
||||
};
|
||||
|
||||
nvidia = {
|
||||
enable = true;
|
||||
enableNvidiaSettings = true;
|
||||
enableWayland = true;
|
||||
enableCUDA = true;
|
||||
};
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
{...}: {
|
||||
imports = [
|
||||
./gpu-replay
|
||||
./nix-gaming
|
||||
];
|
||||
}
|
|
@ -1,98 +0,0 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
mainUser,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
inherit (lib) concatStringsSep getExe removePrefix;
|
||||
inherit (pkgs.selfPackages) gpu-screen-recorder gsr-kms-server;
|
||||
|
||||
hyprPkgs = config.home-manager.users.${mainUser}.wayland.windowManager.hyprland.finalPackage;
|
||||
|
||||
cfgDesktop = config.roles.desktop;
|
||||
in {
|
||||
security.wrappers = {
|
||||
gpu-screen-recorder = {
|
||||
owner = "root";
|
||||
group = "video";
|
||||
capabilities = "cap_sys_nice+ep";
|
||||
source = getExe gpu-screen-recorder;
|
||||
};
|
||||
|
||||
gsr-kms-server = {
|
||||
owner = "root";
|
||||
group = "video";
|
||||
capabilities = "cap_sys_admin+ep";
|
||||
source = getExe gsr-kms-server;
|
||||
};
|
||||
};
|
||||
|
||||
home-manager.users.${mainUser} = {
|
||||
home.packages = [
|
||||
(pkgs.writeShellApplication {
|
||||
name = "gpu-save-replay";
|
||||
|
||||
runtimeInputs = with pkgs; [procps];
|
||||
|
||||
text = ''
|
||||
pkill --signal SIGUSR1 -f gpu-screen-recorder
|
||||
'';
|
||||
})
|
||||
|
||||
(pkgs.writeShellApplication {
|
||||
name = "gsr-start";
|
||||
|
||||
runtimeInputs = [
|
||||
pkgs.pulseaudio
|
||||
pkgs.xorg.xrandr
|
||||
|
||||
hyprPkgs
|
||||
];
|
||||
|
||||
text = ''
|
||||
main="${removePrefix "desc:" cfgDesktop.mainMonitor}"
|
||||
WINDOW=$(hyprctl -j monitors | jq '.[] |= (.description |= gsub(","; ""))' | jq -r ".[] | select(.description | test(\"$main\")) | .name")
|
||||
|
||||
# Fix fullscreen game resolution
|
||||
xrandr --output "$WINDOW" --primary
|
||||
|
||||
gpu-screen-recorder ${concatStringsSep " " [
|
||||
# Prints fps and damage info once per second.
|
||||
"-v no"
|
||||
|
||||
# Replay buffer time in seconds.
|
||||
"-r 1200"
|
||||
|
||||
# Organise replays in folders based on the current date.
|
||||
"-df yes"
|
||||
"-o /home/matt/Videos/Replay"
|
||||
|
||||
# Audio codec to use.
|
||||
"-ac aac"
|
||||
|
||||
# Audio device or application to record from (pulse audio device).
|
||||
"-a desktop/default_output"
|
||||
"-a microphone/default_input"
|
||||
|
||||
# Window id to record, display (monitor name), "screen", "screen-direct", "focused" or "portal".
|
||||
"-w \"$WINDOW\""
|
||||
|
||||
# Frame rate to record at.
|
||||
"-f 60"
|
||||
|
||||
# Container format for output file.
|
||||
"-c mkv"
|
||||
|
||||
# Video codec to use.
|
||||
"-k hevc"
|
||||
]}
|
||||
'';
|
||||
})
|
||||
];
|
||||
|
||||
wayland.windowManager.hyprland.settings = {
|
||||
bind = [",F8, exec, ags request 'save-replay'"];
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
{
|
||||
nix-gaming,
|
||||
pkgs,
|
||||
...
|
||||
}: {
|
||||
imports = [
|
||||
nix-gaming.nixosModules.platformOptimizations
|
||||
];
|
||||
|
||||
programs = {
|
||||
steam = {
|
||||
enable = true;
|
||||
protontricks.enable = true;
|
||||
remotePlay.openFirewall = true;
|
||||
|
||||
extraCompatPackages = [
|
||||
pkgs.selfPackages.proton-ge-latest
|
||||
];
|
||||
|
||||
platformOptimizations.enable = true;
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = [
|
||||
(pkgs.lutris.override {
|
||||
extraLibraries = pkgs: [
|
||||
# List library dependencies here
|
||||
];
|
||||
extraPkgs = pkgs: [
|
||||
# List extra packages available to lutris here
|
||||
];
|
||||
})
|
||||
|
||||
pkgs.r2modman
|
||||
pkgs.ryujinx
|
||||
];
|
||||
}
|
|
@ -1,113 +0,0 @@
|
|||
deviceName: {
|
||||
config,
|
||||
mainUser,
|
||||
self,
|
||||
...
|
||||
}: let
|
||||
clusterIP = (builtins.head config.services.pcsd.virtualIps).ip;
|
||||
in {
|
||||
# ------------------------------------------------
|
||||
# Imports
|
||||
# ------------------------------------------------
|
||||
imports = [
|
||||
./hardware-configuration.nix
|
||||
|
||||
./modules
|
||||
|
||||
self.nixosModules.base
|
||||
self.nixosModules.kmscon
|
||||
self.nixosModules.meta
|
||||
self.nixosModules.server
|
||||
];
|
||||
|
||||
config = {
|
||||
# State Version: DO NOT CHANGE
|
||||
system.stateVersion = "24.05";
|
||||
|
||||
# ------------------------------------------------
|
||||
# User Settings
|
||||
# ------------------------------------------------
|
||||
users.users.${mainUser} = {
|
||||
isNormalUser = true;
|
||||
uid = 1000;
|
||||
|
||||
hashedPassword =
|
||||
if deviceName == "thingone"
|
||||
then "$y$j9T$H.Uu5T7k5OLomqiPtFkVX0$ojaLWjxi.MDjxY00rT5r2dhJkt.9h.pXHgOtlhf3sN/"
|
||||
else "$y$j9T$dXC7oiLsG7fCBXS1HUxo21$JjDm17jEwM41gnjMUaFdvgSzWXoGYQbqm867VtDAjF7";
|
||||
|
||||
extraGroups = [
|
||||
"wheel"
|
||||
"adm"
|
||||
];
|
||||
};
|
||||
|
||||
networking = {
|
||||
hostName = deviceName;
|
||||
resolvconf.enable = true;
|
||||
nameservers = [
|
||||
clusterIP
|
||||
"1.0.0.1"
|
||||
];
|
||||
extraHosts = ''
|
||||
10.0.0.244 thingone
|
||||
10.0.0.159 thingtwo
|
||||
'';
|
||||
firewall.enable = false;
|
||||
};
|
||||
|
||||
time.timeZone = "America/Montreal";
|
||||
|
||||
# ------------------------------------------------
|
||||
# `Self` Modules configuration
|
||||
# ------------------------------------------------
|
||||
meta = {
|
||||
roleDescription = ''
|
||||
Mini PC that makes use of [NixOS-pcsd](https://github.com/matt1432/nixos-pcsd)
|
||||
to form a cluster with its twin. Files located in `cluster`
|
||||
'';
|
||||
hardwareDescription = "Lenovo ThinkCentre M900";
|
||||
};
|
||||
|
||||
roles.base = {
|
||||
enable = true;
|
||||
user = mainUser;
|
||||
};
|
||||
|
||||
roles.server = {
|
||||
enable = true;
|
||||
user = mainUser;
|
||||
tailscale.enable = true;
|
||||
sshd.enable = true;
|
||||
};
|
||||
|
||||
services.kmscon.enable = true;
|
||||
|
||||
home-manager.users.${mainUser} = {
|
||||
imports = [
|
||||
self.homeManagerModules.neovim
|
||||
self.homeManagerModules.shell
|
||||
];
|
||||
|
||||
programs = {
|
||||
bash = {
|
||||
enable = true;
|
||||
promptMainColor =
|
||||
if deviceName == "thingone"
|
||||
then "green"
|
||||
else if deviceName == "thingtwo"
|
||||
then "red"
|
||||
else "purple";
|
||||
};
|
||||
|
||||
neovim = {
|
||||
enable = true;
|
||||
user = mainUser;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# For accurate stack trace
|
||||
_file = ./default.nix;
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
{
|
||||
config,
|
||||
modulesPath,
|
||||
...
|
||||
}: {
|
||||
nixpkgs.hostPlatform = "x86_64-linux";
|
||||
imports = [(modulesPath + "/installer/scan/not-detected.nix")];
|
||||
|
||||
boot = {
|
||||
loader = {
|
||||
efi.canTouchEfiVariables = true;
|
||||
timeout = 2;
|
||||
|
||||
systemd-boot = {
|
||||
enable = true;
|
||||
consoleMode = "max";
|
||||
configurationLimit = 30;
|
||||
};
|
||||
};
|
||||
|
||||
initrd.availableKernelModules = [
|
||||
"xhci_pci"
|
||||
"ahci"
|
||||
"usbhid"
|
||||
"usb_storage"
|
||||
"sd_mod"
|
||||
];
|
||||
};
|
||||
|
||||
fileSystems = {
|
||||
"/" = {
|
||||
device = "/dev/disk/by-label/NIXROOT";
|
||||
fsType = "btrfs";
|
||||
};
|
||||
|
||||
# sudo btrfs subvolume create /@swap
|
||||
"/swap" = {
|
||||
device = "/dev/disk/by-label/NIXROOT";
|
||||
fsType = "btrfs";
|
||||
options = ["subvol=@swap"];
|
||||
};
|
||||
|
||||
"/boot" = {
|
||||
device = "/dev/disk/by-label/NIXBOOT";
|
||||
fsType = "vfat";
|
||||
};
|
||||
};
|
||||
|
||||
swapDevices = [
|
||||
{
|
||||
device = "/swap/swapfile";
|
||||
size = 16 * 1024;
|
||||
}
|
||||
];
|
||||
|
||||
zramSwap.enable = true;
|
||||
|
||||
hardware.cpu.intel.updateMicrocode = config.hardware.enableRedistributableFirmware;
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
{...}: {
|
||||
services = {
|
||||
blocky = {
|
||||
enable = true;
|
||||
|
||||
settings = {
|
||||
upstream = {
|
||||
default = [
|
||||
"127.0.0.1:5335"
|
||||
"127.0.0.1:5335"
|
||||
];
|
||||
};
|
||||
|
||||
blocking = {
|
||||
blackLists = {
|
||||
ads = [
|
||||
"https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,188 +0,0 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
mainUser,
|
||||
pkgs,
|
||||
self,
|
||||
...
|
||||
}: let
|
||||
inherit (lib) attrValues head removeAttrs;
|
||||
|
||||
inherit (config.sops) secrets;
|
||||
inherit (config.networking) hostName;
|
||||
in {
|
||||
imports = [self.nixosModules.caddy-plus];
|
||||
|
||||
users.users.${mainUser}.extraGroups = ["caddy"];
|
||||
|
||||
boot.kernel.sysctl."net.ipv4.ip_nonlocal_bind" = 1;
|
||||
|
||||
systemd.services.caddy.serviceConfig = {
|
||||
EnvironmentFile = secrets.caddy-cloudflare.path;
|
||||
};
|
||||
|
||||
services.caddy = {
|
||||
enable = true;
|
||||
enableReload = false;
|
||||
|
||||
package = let
|
||||
pluginsInfo = import ./plugins.nix;
|
||||
in
|
||||
pkgs.caddy.withPlugins {
|
||||
plugins = map (x: "${x.url}@${x.version}") (attrValues pluginsInfo.plugins);
|
||||
inherit (pluginsInfo) hash;
|
||||
};
|
||||
|
||||
virtualHosts = let
|
||||
clusterIP = (head config.services.pcsd.virtualIps).ip;
|
||||
nosIP = "10.0.0.121";
|
||||
serviviIP = "10.0.0.249";
|
||||
homieIP = "100.64.0.10";
|
||||
|
||||
tlsConf = ''
|
||||
tls {
|
||||
dns cloudflare {$CLOUDFLARE_API_TOKEN}
|
||||
resolvers 1.0.0.1
|
||||
}
|
||||
'';
|
||||
|
||||
mkPublicReverseProxy = subdomain: ip: extraConf:
|
||||
{
|
||||
hostName = "${subdomain}.nelim.org";
|
||||
reverseProxy = ip;
|
||||
listenAddresses = [clusterIP];
|
||||
extraConfig = tlsConf + (extraConf.extraConfig or "");
|
||||
}
|
||||
// (removeAttrs extraConf ["extraConfig"]);
|
||||
in {
|
||||
# Public
|
||||
"Home-Assistant" = mkPublicReverseProxy "homie" "${homieIP}:8123" {};
|
||||
"Vaultwarden" = mkPublicReverseProxy "vault" "${nosIP}:8781" {};
|
||||
"Hauk" = mkPublicReverseProxy "hauk" "${nosIP}:3003" {};
|
||||
"Headscale" = mkPublicReverseProxy "headscale" "${clusterIP}:8085" {};
|
||||
"SearXNG" = mkPublicReverseProxy "search" "${clusterIP}:8080" {};
|
||||
|
||||
"Jellyfin" = mkPublicReverseProxy "jelly" "${nosIP}:8096" {
|
||||
subDirectories.jfa-go = {
|
||||
subDirName = "accounts";
|
||||
reverseProxy = "${nosIP}:8056";
|
||||
};
|
||||
};
|
||||
|
||||
"Jellyseer" = mkPublicReverseProxy "seerr" "${nosIP}:5055" {};
|
||||
|
||||
"Komga" = mkPublicReverseProxy "komga" "${nosIP}:7080" {};
|
||||
|
||||
"Gameyfin" = mkPublicReverseProxy "games" "${nosIP}:8074" {};
|
||||
|
||||
"Forgejo" = mkPublicReverseProxy "git" "${nosIP}:3000" {};
|
||||
|
||||
"Nextcloud" = mkPublicReverseProxy "cloud" "${nosIP}:8042" {
|
||||
extraConfig = ''
|
||||
redir /.well-known/carddav /remote.php/dav 301
|
||||
redir /.well-known/caldav /remote.php/dav 301
|
||||
redir /.well-known/webfinger /index.php/.well-known/webfinger 301
|
||||
redir /.well-known/nodeinfo /index.php/.well-known/nodeinfo 301
|
||||
'';
|
||||
};
|
||||
"OnlyOffice" = mkPublicReverseProxy "office" "http://${nosIP}:8055" {};
|
||||
|
||||
"Immich" = mkPublicReverseProxy "photos" "${nosIP}:2283" {};
|
||||
|
||||
"ObsidianLiveSync" = mkPublicReverseProxy "livesync" "${nosIP}:5984" {};
|
||||
|
||||
"Binary Cache" = mkPublicReverseProxy "cache" "${serviviIP}:5000" {};
|
||||
|
||||
# Private
|
||||
"nelim.org" = {
|
||||
serverAliases = ["*.nelim.org"];
|
||||
extraConfig = tlsConf;
|
||||
listenAddresses = [
|
||||
(
|
||||
if hostName == "thingone"
|
||||
then "100.64.0.8"
|
||||
else "100.64.0.9"
|
||||
)
|
||||
];
|
||||
|
||||
subDomains = {
|
||||
esphome.reverseProxy = "${homieIP}:6052";
|
||||
pr-tracker.reverseProxy = "${serviviIP}:3000";
|
||||
|
||||
pcsd = {
|
||||
extraConfig = ''
|
||||
reverse_proxy https://${clusterIP}:2224 {
|
||||
transport http {
|
||||
tls_insecure_skip_verify
|
||||
}
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
komf.reverseProxy = "${nosIP}:8085";
|
||||
|
||||
# Resume builder
|
||||
resume.reverseProxy = "${nosIP}:3060";
|
||||
resauth.reverseProxy = "${nosIP}:3100";
|
||||
|
||||
# FreshRSS & Co
|
||||
bridge.reverseProxy = "${nosIP}:3006";
|
||||
drss.reverseProxy = "${nosIP}:3007";
|
||||
freshrss = {
|
||||
subDomainName = "rss";
|
||||
reverseProxy = "${nosIP}:2800";
|
||||
};
|
||||
|
||||
wgui.reverseProxy = "${nosIP}:51821";
|
||||
|
||||
lan = {
|
||||
reverseProxy = "${nosIP}:3020";
|
||||
extraConfig = ''
|
||||
redir /index.html /
|
||||
'';
|
||||
|
||||
subDirectories = {
|
||||
bazarr.reverseProxy = "${nosIP}:6767";
|
||||
jellystat.reverseProxy = "${nosIP}:3070";
|
||||
prowlarr.reverseProxy = "${nosIP}:9696";
|
||||
radarr.reverseProxy = "${nosIP}:7878";
|
||||
sonarr.reverseProxy = "${nosIP}:8989";
|
||||
kapowarr.reverseProxy = "${nosIP}:5676";
|
||||
|
||||
jdownloader2 = {
|
||||
subDirName = "jd2";
|
||||
experimental = true;
|
||||
reverseProxy = "${nosIP}:5800";
|
||||
};
|
||||
|
||||
qbittorent = {
|
||||
subDirName = "qbt";
|
||||
experimental = true;
|
||||
reverseProxy = "${nosIP}:8080";
|
||||
};
|
||||
|
||||
vaultwarden = {
|
||||
subDirName = "vault";
|
||||
experimental = true;
|
||||
reverseProxy = "${nosIP}:8780";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Top secret Business
|
||||
joal.extraConfig = ''
|
||||
route {
|
||||
rewrite * /joal/ui{uri}
|
||||
reverse_proxy * ${nosIP}:5656
|
||||
}
|
||||
'';
|
||||
joalws.extraConfig = ''
|
||||
route {
|
||||
reverse_proxy ${nosIP}:5656
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue