diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..9be5f5f --- /dev/null +++ b/.envrc @@ -0,0 +1,2 @@ +# devenv needs to know the path to the current working directory to create and manage mutable state +use flake . --no-pure-eval diff --git a/.gitignore b/.gitignore index 641a18d..501611b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,12 @@ result result-* +.venv +.direnv +.devenv dist +config.ini test.db -.ruff_cache \ No newline at end of file +.ruff_cache diff --git a/README.md b/README.md index 08b54ab..a081cf3 100644 --- a/README.md +++ b/README.md @@ -3,29 +3,46 @@ EDB-system for PVVVV ## Nix + ### Hvordan kjøre -`nix run github:Prograrmvarverkstedet/dibbler` + nix run github:Programvareverkstedet/dibbler +### Hvordan utvikle? -### Bygge nytt image + python -m venv .venv + source .venv/activate + pip install -e . + cp example-config.ini config.ini + dibbler -c config.ini create-db + dibbler -c config.ini loop + +eller hvis du tolererer nix og postgres: + + direnv allow # eller bare `nix develop` + devenv up + dibbler create-db + dibbler loop + +### Bygge image For å bygge et image trenger du en builder som takler å bygge for arkitekturen du skal lage et image for. -(Eller be til gudene om at cross compile funker) +_(Eller be til gudene om at cross compile funker)_ Flaket exposer en modul som autologger inn med en bruker som automatisk kjører dibbler, og setter opp et minimalistisk miljø. -Før du bygger imaget burde du endre conf.py lokalt til å inneholde instillingene dine. **NB: Denne kommer til å ligge i nix storen.** +Før du bygger imaget burde du lage en `config.ini` fil lokalt som inneholder instillingene dine. **NB: Denne kommer til å ligge i nix storen.** -Du kan også endre hvilken conf.py som blir brukt direkte i pakken eller i modulen. +Du kan også endre hvilken `config.ini` som blir brukt direkte i pakken eller i modulen. -Se eksempelet for hvordan skrot er satt opp i flake.nix +Se eksempelet for hvordan skrot er satt opp i `flake.nix` ### Bygge image for skrot -Skrot har et image definert i flake.nix: -1. endre conf.py +Skrot har et system image definert i `flake.nix`: + +1. lag `config.ini` (`cp {example-,}config.ini`) 2. `nix build .#images.skrot` 3. ??? -4. non-profit \ No newline at end of file +4. non-profit! diff --git a/conf.py b/conf.py deleted file mode 100644 index 9bff83f..0000000 --- a/conf.py +++ /dev/null @@ -1,13 +0,0 @@ -db_url = "postgresql://robertem@127.0.0.1/pvvvv" -quit_allowed = True -stop_allowed = False -show_tracebacks = True -input_encoding = "utf8" - -low_credit_warning_limit = -100 -user_recent_transaction_limit = 100 - -# See https://pypi.org/project/brother_ql/ for label types -# Set rotate to False for endless labels -label_type = "62" -label_rotate = False diff --git a/dibbler/db.py b/dibbler/db.py index a091476..604cba5 100644 --- a/dibbler/db.py +++ b/dibbler/db.py @@ -1,7 +1,12 @@ +import os + from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from dibbler.conf import config -engine = create_engine(config.get("database", "url")) +engine = create_engine( + os.environ.get("DIBBLER_DATABASE_URL") + or config.get("database", "url") +) Session = sessionmaker(bind=engine) diff --git a/dibbler/main.py b/dibbler/main.py index bd0c424..41b97f8 100644 --- a/dibbler/main.py +++ b/dibbler/main.py @@ -1,4 +1,6 @@ import argparse +import sys +import os from dibbler.conf import config @@ -10,6 +12,7 @@ parser.add_argument( help="Path to the config file", type=str, required=False, + default=os.environ.get("DIBBLER_CONFIG_FILE", None) ) subparsers = parser.add_subparsers( @@ -24,6 +27,8 @@ subparsers.add_parser("slabbedasker", help="Find out who is slabbedasker") def main(): args = parser.parse_args() + if args.config is None: + print("ERROR: no config was provided", file=sys.stderr) config.read(args.config) if args.subcommand == "loop": diff --git a/example-config.ini b/example-config.ini index c382fc9..9f7cc1d 100644 --- a/example-config.ini +++ b/example-config.ini @@ -1,18 +1,20 @@ [general] -quit_allowed = true -stop_allowed = false +; quit_allowed = false +; stop_allowed = false +quit_allowed = true ; not for prod +stop_allowed = true ; not for prod show_tracebacks = true input_encoding = 'utf8' [database] -; url = postgresql://robertem@127.0.0.1/pvvvv -url = sqlite:///test.db +; url = postgresql://dibbler:hunter2@127.0.0.1/pvvvv +url = sqlite:///test.db ; devenv will override this to postgres using DIBBLER_DATABASE_URL [limits] low_credit_warning_limit = -100 user_recent_transaction_limit = 100 -# See https://pypi.org/project/brother_ql/ for label types +# See https://pypi.org/project/brother_ql_next/ for label types # Set rotate to False for endless labels [printer] label_type = "62" diff --git a/flake.lock b/flake.lock index 3f5c267..c4bfcdc 100644 --- a/flake.lock +++ b/flake.lock @@ -1,15 +1,103 @@ { "nodes": { + "cachix": { + "inputs": { + "devenv": [ + "devenv" + ], + "flake-compat": [ + "devenv" + ], + "git-hooks": [ + "devenv" + ], + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1728672398, + "narHash": "sha256-KxuGSoVUFnQLB2ZcYODW7AVPAh9JqRlD5BrfsC/Q4qs=", + "owner": "cachix", + "repo": "cachix", + "rev": "aac51f698309fd0f381149214b7eee213c66ef0a", + "type": "github" + }, + "original": { + "owner": "cachix", + "ref": "latest", + "repo": "cachix", + "type": "github" + } + }, + "devenv": { + "inputs": { + "cachix": "cachix", + "flake-compat": "flake-compat", + "git-hooks": "git-hooks", + "nix": "nix", + "nixpkgs": "nixpkgs_3" + }, + "locked": { + "lastModified": 1731619804, + "narHash": "sha256-wyxFaVooL8SzvQNpolpx32X+GoBPnCAg9E0i/Ekn3FU=", + "owner": "cachix", + "repo": "devenv", + "rev": "87edaaf1dddf17fe16eabab3c8edaf7cca2c3bc2", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "devenv", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": [ + "devenv", + "nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1712014858, + "narHash": "sha256-sB4SWl2lX95bExY2gMFG5HIzvva5AVMJd4Igm+GpZNw=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "9126214d0a59633752a136528f5f3b9aa8565b7d", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, "flake-utils": { "inputs": { "systems": "systems" }, "locked": { - "lastModified": 1692799911, - "narHash": "sha256-3eihraek4qL744EvQXsK1Ha6C3CR7nnT8X2qWap4RNk=", + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", "owner": "numtide", "repo": "flake-utils", - "rev": "f9e7cf818399d17d347f847525c5a5a8032e4e44", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", "type": "github" }, "original": { @@ -18,24 +106,174 @@ "type": "github" } }, + "git-hooks": { + "inputs": { + "flake-compat": [ + "devenv" + ], + "gitignore": "gitignore", + "nixpkgs": [ + "devenv", + "nixpkgs" + ], + "nixpkgs-stable": [ + "devenv" + ] + }, + "locked": { + "lastModified": 1730302582, + "narHash": "sha256-W1MIJpADXQCgosJZT8qBYLRuZls2KSiKdpnTVdKBuvU=", + "owner": "cachix", + "repo": "git-hooks.nix", + "rev": "af8a16fe5c264f5e9e18bcee2859b40a656876cf", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "git-hooks.nix", + "type": "github" + } + }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "devenv", + "git-hooks", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1709087332, + "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "libgit2": { + "flake": false, + "locked": { + "lastModified": 1697646580, + "narHash": "sha256-oX4Z3S9WtJlwvj0uH9HlYcWv+x1hqp8mhXl7HsLu2f0=", + "owner": "libgit2", + "repo": "libgit2", + "rev": "45fd9ed7ae1a9b74b957ef4f337bc3c8b3df01b5", + "type": "github" + }, + "original": { + "owner": "libgit2", + "repo": "libgit2", + "type": "github" + } + }, + "nix": { + "inputs": { + "flake-compat": [ + "devenv" + ], + "flake-parts": "flake-parts", + "libgit2": "libgit2", + "nixpkgs": "nixpkgs_2", + "nixpkgs-23-11": [ + "devenv" + ], + "nixpkgs-regression": [ + "devenv" + ], + "pre-commit-hooks": [ + "devenv" + ] + }, + "locked": { + "lastModified": 1727438425, + "narHash": "sha256-X8ES7I1cfNhR9oKp06F6ir4Np70WGZU5sfCOuNBEwMg=", + "owner": "domenkozar", + "repo": "nix", + "rev": "f6c5ae4c1b2e411e6b1e6a8181cc84363d6a7546", + "type": "github" + }, + "original": { + "owner": "domenkozar", + "ref": "devenv-2.24", + "repo": "nix", + "type": "github" + } + }, "nixpkgs": { "locked": { - "lastModified": 1693145325, - "narHash": "sha256-Gat9xskErH1zOcLjYMhSDBo0JTBZKfGS0xJlIRnj6Rc=", + "lastModified": 1730531603, + "narHash": "sha256-Dqg6si5CqIzm87sp57j5nTaeBbWhHFaVyG7V6L8k3lY=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "cddebdb60de376c1bdb7a4e6ee3d98355453fe56", + "rev": "7ffd9ae656aec493492b44d0ddfb28e79a1ea25d", "type": "github" }, "original": { - "id": "nixpkgs", - "type": "indirect" + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1717432640, + "narHash": "sha256-+f9c4/ZX5MWDOuB1rKoWj+lBNm0z0rs4CK47HBLxy1o=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "88269ab3044128b7c2f4c7d68448b2fb50456870", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "release-24.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1716977621, + "narHash": "sha256-Q1UQzYcMJH4RscmpTkjlgqQDX5yi1tZL0O345Ri6vXQ=", + "owner": "cachix", + "repo": "devenv-nixpkgs", + "rev": "4267e705586473d3e5c8d50299e71503f16a6fb6", + "type": "github" + }, + "original": { + "owner": "cachix", + "ref": "rolling", + "repo": "devenv-nixpkgs", + "type": "github" + } + }, + "nixpkgs_4": { + "locked": { + "lastModified": 1731611831, + "narHash": "sha256-R51rOqkWMfubBkZ9BY4Y1VaRoeqEBshlfQ8mMH5RjqI=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "cea28c811faadb50bee00d433bbf2fea845a43e4", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable-small", + "repo": "nixpkgs", + "type": "github" } }, "root": { "inputs": { + "devenv": "devenv", "flake-utils": "flake-utils", - "nixpkgs": "nixpkgs" + "nixpkgs": "nixpkgs_4" } }, "systems": { diff --git a/flake.nix b/flake.nix index 499a8de..a100d23 100644 --- a/flake.nix +++ b/flake.nix @@ -1,35 +1,85 @@ { description = "Dibbler samspleisebod"; - inputs.flake-utils.url = "github:numtide/flake-utils"; + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable-small"; + flake-utils.url = "github:numtide/flake-utils"; + devenv.url = "github:cachix/devenv"; + }; - outputs = { self, nixpkgs, flake-utils }: - flake-utils.lib.eachDefaultSystem (system: let - pkgs = nixpkgs.legacyPackages.${system}; + nixConfig = { + extra-trusted-public-keys = [ + "devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw=" + ]; + extra-substituters = [ + "https://devenv.cachix.org" + ]; + }; + + outputs = { self, ... } @ inputs: + inputs.flake-utils.lib.eachDefaultSystem (system: let + pkgs = inputs.nixpkgs.legacyPackages.${system}; + inherit (pkgs) lib; in { + packages = { default = self.packages.${system}.dibbler; - dibbler = pkgs.callPackage ./nix/dibbler.nix { - python3Packages = pkgs.python311Packages; - }; - }; - apps = { - default = self.apps.${system}.dibbler; - dibbler = flake-utils.lib.mkApp { - drv = self.packages.${system}.dibbler; - }; + dibbler = pkgs.python311Packages.callPackage ./nix/dibbler.nix { }; + skrot-vm = self.nixosConfigurations.skrot.config.system.build.vm; + + # devenv cruft + devenv-up = self.devShells.${system}.default.config.procfileScript; + devenv-test = self.devShells.${system}.default.config.test; }; devShells = { default = self.devShells.${system}.dibbler; - dibbler = pkgs.mkShell { - packages = with pkgs; [ - python311Packages.black - ruff - ]; + dibbler = inputs.devenv.lib.mkShell { + inherit inputs pkgs; + modules = [({ config, ... }: { + # https://devenv.sh/reference/options/ + + enterShell = '' + if [[ ! -f config.ini ]]; then + cp -v example-config.ini config.ini + fi + + export REPO_ROOT=$(realpath .) # used by mkPythonEditablePackage + export DIBBLER_CONFIG_FILE=$(realpath config.ini) + export DIBBLER_DATABASE_URL=postgresql://dibbler:hunter2@/dibbler?host=${config.env.PGHOST} + ''; + + packages = [ + + /* self.packages.${system}.dibbler */ + (pkgs.python311Packages.mkPythonEditablePackage { + inherit (self.packages.${system}.dibbler) + pname version + build-system dependencies; + scripts = (lib.importTOML ./pyproject.toml).project.scripts; + root = "$REPO_ROOT"; + }) + + pkgs.python311Packages.black + pkgs.ruff + ]; + + services.postgres = { + enable = true; + initialDatabases = [ + { + name = "dibbler"; + user = "dibbler"; + pass = "hunter2"; + } + ]; + }; + + })]; }; }; + }) // @@ -41,10 +91,10 @@ images.skrot = self.nixosConfigurations.skrot.config.system.build.sdImage; - nixosConfigurations.skrot = nixpkgs.lib.nixosSystem { + nixosConfigurations.skrot = inputs.nixpkgs.lib.nixosSystem { system = "aarch64-linux"; modules = [ - (nixpkgs + "/nixos/modules/installer/sd-card/sd-image-aarch64.nix") + (inputs.nixpkgs + "/nixos/modules/installer/sd-card/sd-image-aarch64.nix") self.nixosModules.default ({...}: { system.stateVersion = "22.05"; @@ -73,5 +123,6 @@ }) ]; }; + }; } diff --git a/nix/dibbler.nix b/nix/dibbler.nix index 527b7ba..5aaecf5 100644 --- a/nix/dibbler.nix +++ b/nix/dibbler.nix @@ -1,17 +1,25 @@ { lib -, python3Packages , fetchFromGitHub +, buildPythonApplication +, setuptools +, brother-ql +, matplotlib +, psycopg2 +, python-barcode +, sqlalchemy }: -python3Packages.buildPythonApplication { + +buildPythonApplication { pname = "dibbler"; - version = "unstable-2021-09-07"; + version = "0.0.0"; + pyproject = true; + src = lib.cleanSource ../.; - format = "pyproject"; - - nativeBuildInputs = with python3Packages; [ setuptools ]; - propagatedBuildInputs = with python3Packages; [ - brother-ql + build-system = [ setuptools ]; + dependencies = [ + # we override pname to satisfy mkPythonEditablePackage + (brother-ql.overridePythonAttrs { pname = "brother-ql-next"; }) matplotlib psycopg2 python-barcode diff --git a/nix/module.nix b/nix/module.nix index 69aa1a1..e9a63b3 100644 --- a/nix/module.nix +++ b/nix/module.nix @@ -23,7 +23,10 @@ in { group = "dibbler"; extraGroups = [ "lp" ]; isNormalUser = true; - shell = ((pkgs.writeShellScriptBin "login-shell" "${screen} -x dibbler") // {shellPath = "/bin/login-shell";}); + shell = ( + (pkgs.writeShellScriptBin "login-shell" "${screen} -x dibbler") + // {shellPath = "/bin/login-shell";} + ); }; }; diff --git a/pyproject.toml b/pyproject.toml index 0de40ff..40f8655 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,7 @@ classifiers = [ ] dependencies = [ "SQLAlchemy >= 2.0, <2.1", - "brother-ql", + "brother_ql_next", "matplotlib", "psycopg2 >= 2.8, <2.10", "python-barcode", @@ -32,4 +32,3 @@ line-length = 100 [tool.ruff] line-length = 100 -