about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--.cargo/config.toml13
-rw-r--r--.envrc23
-rw-r--r--.gitignore17
-rw-r--r--.reuse/templates/default.jinja230
-rw-r--r--Cargo.toml91
-rw-r--r--README.md21
-rw-r--r--cog.toml36
-rw-r--r--crates/rocie/Cargo.toml39
-rw-r--r--flake.lock48
-rw-r--r--flake.lock.license9
-rw-r--r--flake.nix84
-rw-r--r--nix/package.nix140
-rw-r--r--rustfmt.toml29
-rwxr-xr-xscripts/mkdb.sh30
-rw-r--r--treefmt.nix81
-rwxr-xr-xupdate.sh18
16 files changed, 709 insertions, 0 deletions
diff --git a/.cargo/config.toml b/.cargo/config.toml
new file mode 100644
index 0000000..cdfede7
--- /dev/null
+++ b/.cargo/config.toml
@@ -0,0 +1,13 @@
+# rocie - An enterprise grocery management system
+#
+# Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of Rocie.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
+[build]
+rustflags = ["-Clink-arg=-fuse-ld=mold", "-Ctarget-cpu=native"]
diff --git a/.envrc b/.envrc
new file mode 100644
index 0000000..fd8433f
--- /dev/null
+++ b/.envrc
@@ -0,0 +1,23 @@
+#!/usr/bin/env sh
+
+# rocie - An enterprise grocery management system
+#
+# Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of Rocie.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
+use flake
+
+root="$(git rev-parse --show-toplevel)"
+
+PATH_add ./scripts
+PATH_add ./target/debug
+PATH_add ./target/release
+PATH_add ./target/profiling
+
+export DATABASE_URL="sqlite://$root/target/database.sqlx"
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..7fe97c8
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,17 @@
+# rocie - An enterprise grocery management system
+#
+# Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of Rocie.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
+# build dirs
+/target
+/result
+
+# dev shell
+.direnv
diff --git a/.reuse/templates/default.jinja2 b/.reuse/templates/default.jinja2
new file mode 100644
index 0000000..a9c5443
--- /dev/null
+++ b/.reuse/templates/default.jinja2
@@ -0,0 +1,30 @@
+{#
+rocie - An enterprise grocery management system
+
+Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+SPDX-License-Identifier: GPL-3.0-or-later
+
+This file is part of Rocie.
+
+You should have received a copy of the License along with this program.
+If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+#}
+
+rocie - An enterprise grocery management system
+
+{% for copyright_line in copyright_lines %}
+{{ copyright_line }}
+{% endfor %}
+{% for contributor_line in contributor_lines %}
+SPDX-FileContributor: {{ contributor_line }}
+{% endfor %}
+{% for expression in spdx_expressions %}
+SPDX-License-Identifier: {{ expression }}
+{% endfor %}
+
+This file is part of Rocie.
+
+You should have received a copy of the License along with this program.
+If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+{# vim: ft=htmldjango #}
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..015e878
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,91 @@
+# rocie - An enterprise grocery management system
+#
+# Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of Rocie.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
+[workspace]
+resolver = "2"
+members = [
+  "crates/rocie",
+]
+
+[workspace.package]
+edition = "2024"
+version = "1.8.0"
+rust-version = "1.85.0"
+authors = ["Benedikt Peetz <benedikt.peetz@b-peetz.de>"]
+repository = "https://git.vhack.eu/soispha/clients/yt"
+license = "GPL-3.0-or-later"
+description = "An enterprise grocery management system"
+
+[workspace.dependencies]
+
+[profile.profiling]
+inherits = "release"
+debug = true
+
+[profile.release]
+lto = true
+codegen-units = 1
+panic = "abort"
+split-debuginfo = "off"
+
+[workspace.lints.rust]
+# rustc lint groups https://doc.rust-lang.org/rustc/lints/groups.html
+warnings = "warn"
+future_incompatible = { level = "warn", priority = -1 }
+let_underscore = { level = "warn", priority = -1 }
+nonstandard_style = { level = "warn", priority = -1 }
+rust_2018_compatibility = { level = "warn", priority = -1 }
+rust_2018_idioms = { level = "warn", priority = -1 }
+rust_2021_compatibility = { level = "warn", priority = -1 }
+unused = { level = "warn", priority = -1 }
+
+# rustc allowed-by-default lints https://doc.rust-lang.org/rustc/lints/listing/allowed-by-default.html
+# missing_docs = "warn"
+macro_use_extern_crate = "warn"
+meta_variable_misuse = "warn"
+missing_abi = "warn"
+missing_copy_implementations = "warn"
+missing_debug_implementations = "warn"
+non_ascii_idents = "warn"
+noop_method_call = "warn"
+single_use_lifetimes = "warn"
+trivial_casts = "warn"
+trivial_numeric_casts = "warn"
+unreachable_pub = "warn"
+unsafe_op_in_unsafe_fn = "warn"
+unused_crate_dependencies = "warn"
+unused_import_braces = "warn"
+unused_lifetimes = "warn"
+unused_qualifications = "warn"
+variant_size_differences = "warn"
+
+[workspace.lints.rustdoc]
+# rustdoc lints https://doc.rust-lang.org/rustdoc/lints.html
+broken_intra_doc_links = "warn"
+private_intra_doc_links = "warn"
+missing_crate_level_docs = "warn"
+private_doc_tests = "warn"
+invalid_codeblock_attributes = "warn"
+invalid_rust_codeblocks = "warn"
+bare_urls = "warn"
+
+[workspace.lints.clippy]
+# clippy allowed by default
+dbg_macro = "warn"
+
+# clippy categories https://doc.rust-lang.org/clippy/
+all = { level = "warn", priority = -1 }
+correctness = { level = "warn", priority = -1 }
+suspicious = { level = "warn", priority = -1 }
+style = { level = "warn", priority = -1 }
+complexity = { level = "warn", priority = -1 }
+perf = { level = "warn", priority = -1 }
+pedantic = { level = "warn", priority = -1 }
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..371f98a
--- /dev/null
+++ b/README.md
@@ -0,0 +1,21 @@
+<!--
+rocie - An enterprise grocery management system
+
+Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+SPDX-License-Identifier: GPL-3.0-or-later
+
+This file is part of Rocie.
+
+You should have received a copy of the License along with this program.
+If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+-->
+
+# Rocie
+
+> An enterprise grocery management system
+
+## Licensing
+
+This project complies with the REUSE v3.2 specification. This means that every
+file clearly states its copyright.
diff --git a/cog.toml b/cog.toml
new file mode 100644
index 0000000..963d405
--- /dev/null
+++ b/cog.toml
@@ -0,0 +1,36 @@
+# rocie - An enterprise grocery management system
+#
+# Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of Rocie.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
+tag_prefix = "v"
+branch_whitelist = ["main", "prime"]
+ignore_merge_commits = false
+
+pre_bump_hooks = [
+  "reuse lint",                    # Check licensing status
+  "nix fmt",                       # format
+  "nix flake check",               # verify the project builds
+  "cargo set-version {{version}}", # bump version in Cargo.toml
+]
+post_bump_hooks = [
+  "git push",
+  # "cargo publish",
+  "git push origin v{{version}}", # push the new tag to origin
+]
+
+[bump_profiles]
+
+[changelog]
+path = "NEWS.md"
+template = "remote"
+remote = "git.foss-syndicate.org"
+repository = "servecs/rocie"
+owner = "soispha"
+authors = [{ signature = "Benedikt Peetz", username = "bpeetz" }]
diff --git a/crates/rocie/Cargo.toml b/crates/rocie/Cargo.toml
new file mode 100644
index 0000000..a0ae4aa
--- /dev/null
+++ b/crates/rocie/Cargo.toml
@@ -0,0 +1,39 @@
+# rocie - An enterprise grocery management system
+#
+# Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of Rocie.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
+[package]
+name = "rocie"
+keywords = []
+categories = []
+default-run = "rocie"
+version.workspace = true
+edition.workspace = true
+authors.workspace = true
+license.workspace = true
+repository.workspace = true
+rust-version.workspace = true
+description.workspace = true
+publish = false
+
+[dependencies]
+
+[[bin]]
+name = "rocie"
+doc = false
+path = "src/main.rs"
+
+[lints]
+workspace = true
+
+[dev-dependencies]
+
+[package.metadata.docs.rs]
+all-features = true
diff --git a/flake.lock b/flake.lock
new file mode 100644
index 0000000..dff34d3
--- /dev/null
+++ b/flake.lock
@@ -0,0 +1,48 @@
+{
+  "nodes": {
+    "nixpkgs": {
+      "locked": {
+        "lastModified": 1756662818,
+        "narHash": "sha256-Opggp4xiucQ5gBceZ6OT2vWAZOjQb3qULv39scGZ9Nw=",
+        "owner": "NixOS",
+        "repo": "nixpkgs",
+        "rev": "2e6aeede9cb4896693434684bb0002ab2c0cfc09",
+        "type": "github"
+      },
+      "original": {
+        "owner": "NixOS",
+        "ref": "nixos-unstable-small",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    },
+    "root": {
+      "inputs": {
+        "nixpkgs": "nixpkgs",
+        "treefmt-nix": "treefmt-nix"
+      }
+    },
+    "treefmt-nix": {
+      "inputs": {
+        "nixpkgs": [
+          "nixpkgs"
+        ]
+      },
+      "locked": {
+        "lastModified": 1756662192,
+        "narHash": "sha256-F1oFfV51AE259I85av+MAia221XwMHCOtZCMcZLK2Jk=",
+        "owner": "numtide",
+        "repo": "treefmt-nix",
+        "rev": "1aabc6c05ccbcbf4a635fb7a90400e44282f61c4",
+        "type": "github"
+      },
+      "original": {
+        "owner": "numtide",
+        "repo": "treefmt-nix",
+        "type": "github"
+      }
+    }
+  },
+  "root": "root",
+  "version": 7
+}
diff --git a/flake.lock.license b/flake.lock.license
new file mode 100644
index 0000000..131e564
--- /dev/null
+++ b/flake.lock.license
@@ -0,0 +1,9 @@
+rocie - An enterprise grocery management system
+
+Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+SPDX-License-Identifier: GPL-3.0-or-later
+
+This file is part of Rocie.
+
+You should have received a copy of the License along with this program.
+If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
diff --git a/flake.nix b/flake.nix
new file mode 100644
index 0000000..a0c5b0e
--- /dev/null
+++ b/flake.nix
@@ -0,0 +1,84 @@
+# rocie - An enterprise grocery management system
+#
+# Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of Rocie.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
+{
+  description = "rocie";
+
+  inputs = {
+    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable-small";
+
+    treefmt-nix = {
+      url = "github:numtide/treefmt-nix";
+      inputs = {
+        nixpkgs.follows = "nixpkgs";
+      };
+    };
+  };
+
+  outputs = {
+    self,
+    nixpkgs,
+    treefmt-nix,
+  }: let
+    system = "x86_64-linux";
+    pkgs = nixpkgs.legacyPackages."${system}";
+
+    buildInputs = [
+    ];
+
+    nativeBuildInputs = [
+    ];
+
+    rocie = pkgs.callPackage ./nix/package.nix {};
+
+    treefmtEval = import ./treefmt.nix {inherit treefmt-nix pkgs;};
+  in {
+    packages."${system}" = {
+      inherit rocie;
+      default = self.packages.${system}.rocie;
+    };
+
+    checks."${system}" = {
+      inherit rocie;
+      formatting = treefmtEval.config.build.check self;
+    };
+
+    formatter."${system}" = treefmtEval.config.build.wrapper;
+
+    devShells."${system}".default = pkgs.mkShell {
+      inherit buildInputs nativeBuildInputs;
+
+      packages = [
+        # rust stuff
+        pkgs.cargo
+        pkgs.clippy
+        pkgs.rustc
+        pkgs.rustfmt
+        pkgs.mold-wrapped
+
+        pkgs.cargo-edit
+        pkgs.cargo-expand
+        pkgs.cargo-flamegraph
+
+        # Releng
+        pkgs.git-bug
+        pkgs.reuse
+        pkgs.cocogitto
+
+        # Perf
+        pkgs.hyperfine
+
+        # Sqlite
+        pkgs.sqlite-interactive
+      ];
+    };
+  };
+}
diff --git a/nix/package.nix b/nix/package.nix
new file mode 100644
index 0000000..a9e925d
--- /dev/null
+++ b/nix/package.nix
@@ -0,0 +1,140 @@
+# rocie - An enterprise grocery management system
+#
+# Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of Rocie.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
+{
+  lib,
+  rustPlatform,
+  installShellFiles,
+  # buildInputs
+  mpv-unwrapped,
+  ffmpeg,
+  openssl,
+  libffi,
+  zlib,
+  curl,
+  # NativeBuildInputs
+  makeWrapper,
+  llvmPackages_latest,
+  glibc,
+  sqlite,
+  fd,
+  pkg-config,
+  SDL2,
+  python3,
+  # Passthru
+  tree-sitter-yts,
+}: let
+  python = python3.withPackages (ps: [ps.yt-dlp]);
+in
+  rustPlatform.buildRustPackage (finalAttrs: {
+    pname = "yt";
+    inherit
+      ((builtins.fromTOML (builtins.readFile
+            ../Cargo.toml)).workspace.package)
+      version
+      ;
+
+    src = lib.cleanSourceWith {
+      src = lib.cleanSource ./..;
+      filter = name: type:
+        (type == "directory")
+        || (builtins.elem (builtins.baseNameOf name) [
+          "Cargo.toml"
+          "Cargo.lock"
+          "mkdb.sh"
+          "help.str"
+          "raw_error_warning.txt"
+          "golden.txt"
+        ])
+        || (lib.strings.hasSuffix ".rs" (builtins.baseNameOf name))
+        || (lib.strings.hasSuffix ".h" (builtins.baseNameOf name))
+        || (lib.strings.hasSuffix ".sql" (builtins.baseNameOf name));
+    };
+
+    nativeBuildInputs = [
+      installShellFiles
+      makeWrapper
+      sqlite
+      fd
+      pkg-config
+    ];
+
+    buildInputs = [
+      mpv-unwrapped.dev
+      ffmpeg
+      openssl
+      libffi
+      zlib
+      curl.dev
+      python
+    ];
+
+    checkInputs = [
+      # Needed for the tests in `libmpv2`
+      SDL2
+    ];
+
+    env = let
+      clang_version =
+        lib.versions.major
+        llvmPackages_latest.clang-unwrapped.version;
+    in {
+      # Needed for the compile time sqlite checks.
+      DATABASE_URL = "sqlite://database.sqlx";
+
+      # Required by yt_dlp
+      FFMPEG_LOCATION = "${lib.getExe ffmpeg}";
+
+      # Tell pyo3 which python to use.
+      PYO3_PYTHON = lib.getExe python;
+
+      # Needed for the libmpv2.
+      C_INCLUDE_PATH = "${glibc.dev}/include";
+      LIBCLANG_INCLUDE_PATH = "${llvmPackages_latest.clang-unwrapped.lib}/lib/clang/${clang_version}/include";
+      LIBCLANG_PATH = "${llvmPackages_latest.clang-unwrapped.lib}/lib/libclang.so";
+    };
+
+    doCheck = true;
+    checkFlags = [
+      # All of these tests try to connect to the internet to download test data.
+      "--skip=select::base::test_base"
+      "--skip=select::file::test_file"
+      "--skip=select::options::test_options"
+      "--skip=subscriptions::import_export::test_import_export"
+      "--skip=subscriptions::naming_subscriptions::test_naming_subscriptions"
+      "--skip=videos::downloading::test_downloading"
+    ];
+
+    prePatch = ''
+      # Generate the sqlite db, so that we can run the comp-time sqlite checks.
+      bash ./scripts/mkdb.sh
+    '';
+
+    passthru = {
+      inherit tree-sitter-yts;
+    };
+
+    cargoLock = {
+      lockFile = ../Cargo.lock;
+    };
+
+    postInstall = ''
+      installShellCompletion --cmd yt \
+        --bash <(COMPLETE=bash $out/bin/yt) \
+        --fish <(COMPLETE=fish $out/bin/yt) \
+        --zsh <(COMPLETE=zsh $out/bin/yt)
+
+      # NOTE: We cannot clear the path, because we need access to the $EDITOR. <2025-04-04>
+      wrapProgram $out/bin/yt \
+        --prefix PATH : ${lib.makeBinPath finalAttrs.buildInputs} \
+        --set YTDLP_NO_PLUGINS 1
+    '';
+  })
diff --git a/rustfmt.toml b/rustfmt.toml
new file mode 100644
index 0000000..d6e14b3
--- /dev/null
+++ b/rustfmt.toml
@@ -0,0 +1,29 @@
+# rocie - An enterprise grocery management system
+#
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of Rocie.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
+# https://github.com/rust-lang/rustfmt/blob/master/Configurations.md#imports_granularity
+imports_granularity = "Crate"
+group_imports = "StdExternalCrate"
+
+# https://github.com/rust-lang/rustfmt/blob/master/Configurations.md#format_code_in_doc_comments
+format_code_in_doc_comments = true
+
+style_edition = "2024"
+edition = "2024"
+
+wrap_comments = true
+format_strings = true
+
+error_on_line_overflow = true
+error_on_unformatted = true
+
+format_macro_matchers = true
+
+reorder_impl_items = true
diff --git a/scripts/mkdb.sh b/scripts/mkdb.sh
new file mode 100755
index 0000000..c9895f8
--- /dev/null
+++ b/scripts/mkdb.sh
@@ -0,0 +1,30 @@
+#!/usr/bin/env sh
+
+# rocie - An enterprise grocery management system
+#
+# Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of Rocie.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
+root="$(dirname "$0")/.."
+db="${DATABASE_URL#sqlite://}"
+
+[ -f "$db" ] && rm "$db"
+[ -d "$root/target" ] || mkdir "$root/target"
+
+fd . "$root/crates/yt/src/storage/migrate/sql" | while read -r sql_file; do
+    echo "Applying sql migration file: $(basename "$sql_file").."
+    {
+        # NOTE(@bpeetz): The wrapping in a transaction is needed to simulate the rust code. <2025-05-07>
+        echo "BEGIN TRANSACTION;"
+        cat "$sql_file"
+        echo "COMMIT TRANSACTION;"
+    } | sqlite3 "$db"
+done
+
+# vim: ft=sh
diff --git a/treefmt.nix b/treefmt.nix
new file mode 100644
index 0000000..8f78ebb
--- /dev/null
+++ b/treefmt.nix
@@ -0,0 +1,81 @@
+# rocie - An enterprise grocery management system
+#
+# Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of Rocie.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
+{
+  treefmt-nix,
+  pkgs,
+}:
+treefmt-nix.lib.evalModule pkgs (
+  {pkgs, ...}: {
+    # Used to find the project root
+    projectRootFile = "flake.nix";
+
+    programs = {
+      alejandra.enable = true;
+      rustfmt.enable = true;
+      clang-format.enable = true;
+      mdformat.enable = true;
+      shfmt = {
+        enable = true;
+        indent_size = 4;
+      };
+      shellcheck.enable = true;
+      prettier = {
+        enable = true;
+        settings = {
+          arrowParens = "always";
+          bracketSameLine = false;
+          bracketSpacing = true;
+          editorconfig = true;
+          embeddedLanguageFormatting = "auto";
+          endOfLine = "lf";
+          # experimentalTernaries = false;
+          htmlWhitespaceSensitivity = "css";
+          insertPragma = false;
+          jsxSingleQuote = true;
+          printWidth = 80;
+          proseWrap = "always";
+          quoteProps = "consistent";
+          requirePragma = false;
+          semi = true;
+          singleAttributePerLine = true;
+          singleQuote = false;
+          trailingComma = "all";
+          useTabs = false;
+          vueIndentScriptAndStyle = false;
+
+          tabWidth = 2;
+        };
+      };
+      stylua.enable = true;
+      ruff = {
+        enable = true;
+        format = true;
+      };
+      taplo.enable = true;
+    };
+
+    settings = {
+      global.excludes = [
+        "CHANGELOG.md"
+        "NEWS.md"
+      ];
+      formatter = {
+        clang-format = {
+          options = ["--style" "GNU"];
+        };
+        shfmt = {
+          includes = ["*.bash"];
+        };
+      };
+    };
+  }
+)
diff --git a/update.sh b/update.sh
new file mode 100755
index 0000000..96231c5
--- /dev/null
+++ b/update.sh
@@ -0,0 +1,18 @@
+#!/usr/bin/env sh
+
+# rocie - An enterprise grocery management system
+#
+# Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+# This file is part of Rocie.
+#
+# You should have received a copy of the License along with this program.
+# If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
+
+nix flake update
+
+[ "$1" = "upgrade" ] && cargo upgrade --incompatible allow --pinned allow --recursive true
+cargo update --recursive
+# vim: ft=sh