this also reformats everything with alejandra and moves the pre-commit config to the framework by github:cachix/pre-commit-hooks.nix
3OAFCHK7EIRUD3ZLAGZ3MAXVYOGFAJVDOF63ZIGNU7I3RWIPMAOQC TDB7ST53L77BX5VJ2WR3JK5CIXNSLARB25HP36SQXXDWAWUGPCSAC 5TV7PKKVOU5ZI54V25KW4GSHHF4SJUDOV6TODQ7FKKSJZGXY2IQAC CUFEZOOL3ITGUC2NOLN3WFVWTETYM7L5QU3UNVXVOH6GQYI4R5FQC YVDXUA2QK7TLURRMLOYX4DBTLHEMAAROTF3L2PIRCPDVJNOL7EDAC IKVV4XDUTXIEYX6G3GRZEVXK5IWGKZOMG76BO25GS6K3JOUTXK4AC GVZHFU756PCUMRRHHDNHBYW5QFCJ5W3WRB62Q3OIBIWIFEMTHTJQC 453U6GRFTTGLAAGWCKCNHTVUF2FRH7DVCMBSSZHLTMGTPTPAZHAAC B6XTNCPKQCL7GHNQEHAJ7YUBSTODBSI4C7RF7LA3IPG7BELTFP2AC PVZI36WHTCMRPPMQRHNXTP63OT557JZUJI5UAB3DN6FB3XZOALKAC 5KERTK24BRCTXLSFWTOMBAWWVN7C6A2M4KKE5FPARSLBONOUUJRAC 3NPXCY4ENVBVSJZB655T7KVWTGYLTHN6XVS5YYWUXXUQ2IUJRTAQC 3XLJNJNO3AXFFQ25H7VCI565BOS46XK2C6EZJQRQTZOWJCNHDIJAC ZIKMEP6COCUDQUM7UMN57BWYK7FZEXSEWJ74KW2YCHVSEGJ5EBDAC JSALME2CH2BEWU75UIGJQPFRIIGCXHJ7Z45HODUW5EKB2T7Q4BFQC 5HXGJ3EZ5G7GSZ6A2PBFOQBYXP7WYU4QOCKG2ND2TX47XADKURQQC YLLCGI2YBTBMN2EO5D4CQ4EPHMHBWTYBUVEUSS5NAQYTJDN352WQC KUTBHT3LPAECGVN2NRJHGKBQP2WEPYO6BCG3RCH4YFHPL3MWVWXAC WJXAODNJYL54BUFSRF3G2AEBWEI6Q4YH5DXYLK3UYC6JRJYGG7TQC 5FLTMCXWFLP6MI36R73NDC5ZZGKRB66IXOWY7ZTESTLC7M357H2QC QYSR4PDNVTQOISVLQMO5M7MYBEG37SV6Y7JGM6QPC3CA2BJAYPYQC X3IANZNCU5AF7H3YGJ4EUOIP3TKSQNZKVEY7I36NZY7NLI7R6YXQC H5AVZMA7X5KIKSR7LZPDCYTYU5E25XGKWESBYC6S5DR2BVI3QWJAC DCOF764JDXAREHUOIUZ5LCO47QEOPHSS2KKAYQGV7PDHOWDG5WDAC 5HLAP6OIMUSEZK2JBMEG7LUHNZZIBWPJBPZBB4S6FUBHD5L43VAQC HGOULRA3TXXOSJADMYYUAN74YKYJCD6TRTHDFKCTJPEKACLES22AC XGCXHTW2NG3AV27H6BLO3EHD65Z2GTZISEGATGP2N2CB2TNCKLIAC NHRF46PF2N726G4UW743BDBKZU6K5BEOQ44DCI6TDIZ3TAB4NNCQC HZ4SV4CG73RCVZ3B4FX3VQA44JEW546NYJWOQF6VGEVRGDR5TAUAC T7CTIGVFEE6SQAQTZ3PENHCH5RRFJ3EBWXGHVALXA7BSI4ZY2NUAC DTNETCKQOYKWBQCHFC3EUTRFBHB4E3VZVCBRN6OFD6KWTBR3W5RQC 4A5J4ZQ3HM2ZK6OO7N3RZ2WX3YHNGA3X5WJIB4UQJPQGUG4O3AYQC VXESMJDKIRYTNWV6PVDZUSECSP7ESMK5LZPEE72DFBUU5MH7GWLAC BX2EXA45RHKBK4ZFZYUMHYDYKRVIUQJZDW6O643XUHKI5LVNDSJAC DCJDPW7CQ5OR75ECIVESHYVC5JSXZ5CKV6E3EWLRFHHKAKE7JGKAC ENRHXIAOXEVZGED76KL4CZJ5SPZDX5IRS3WICJ22WRKSCCU6IC2QC COUSBBHL5XPZC5KWCYFFAE554D4VFFO55QOD726ODWIRZGWOUSUAC IZ6I7IFHKZLD4EUJHSRGGRMVNKMOBNHCV7HPQUK2CUGP5M7EGEFAC A4YNQVE34SZHRGN2HGBT2M5L7ROU4D5HFHTYUSVZHKTXD2PLM5VQC MWV72ACT6D63U5I4UUNIO4WK7ZN3Q5WYRI72K3DCKCNWZ22QUR5AC NJ5ENURMCBSNFQPNXXNUBMUXVJEBIGNH2T7EWGB63F3FV723BUWAC G5GQ67PH3P4PUNWAR43D6W4PP35E3LBPIG5WE4HCUM5IODT4VDHAC 4PEXC6EE4FNTPUYT64XDSOD6X5IVDY3Y2QDKYTSHEBOYS4JATQTQC CL7RP3ZICLJT7YUI3O54IB2GZY7QMKK7ZC6GZPDXFYQKOOM64CHQC EAV6XCAV7SQXSOO3UX3UYKEPNCNQ26BCFJ64ALU646ZZELDJ2ALQC ROMB2RDGX2LJ4U2XAWJ5S7YANTEY7ICEHIV3FJCPXTTHM5DOYFHQC INKINKWN6MRRH4CGUVTWI5TQ7VSCHA6ODXMLHVVFCHYPM27AYNNQC PS2VFJMZVN77RHZFVUVD2DA3MZNMXYPHT6XRHW2EUTZRGLAXF4YQC 7BNKOFCPOMGW4OEIPGZJF76J4CTD65TZ7CLJPKJOWOIJ65EDVWEQC VMKJ4UOWNB2QFRPYKWNOOVY6PU7QH6A6EFEKDLWRU3VIQIEHI7QAC ZH5LGJE4YAOHG5UP6P4X3NPIUROJWHEXR3PX56PATR5KNIMQL35QC TXU55BEHKBJLAFQATXNK36M3CM2KNH3YCQCVF54NK7O2CO4LHM4QC TIAN54QWQA6YCIYL6C7YXXELA3SKBSMP2Y3ET2YLRWHHOPDE3Y3AC W6GZ3OOBTJG4IYCGZIB5L2KQ623JSGOTBUTLDVM5JB4LXFFMYCUQC BPBU3VMEUPTXFVYKEPATHO6O5ZUN3I4MW6MRWHPIUXSWJ73WTX5AC 3GK6JF2XEWIG6EUSVTQ4ZFMH34RAHROOVZ2KOMF7AMR4HZKEGD5AC 2KXMUFYOTAZO5GFGRFG6GGFJ3BIFO42O7CXBQRP2XH5WWZUOT6UAC S6TTLG2JJJNDFDBBGOYLA67OGTSLXY4E64FMB25EYDTJSTGITR7QC MAIEPZVQNNMHNN5MJ4UVPR5D7M3EE4B6QEBTR7L3KQERPUKOD5IQC QADXBPZPPIAICY2HTCAZSZYX33TG72CXI2XZOG3DCNMOIXAPWQMQC 2MH4TU2HSSXKDWLUQXEBJER4F52ALDFAKVUVNT5O4XSFZHPYV53QC IAC34BX3IZTFOKNNPGVY7VYLLDOLTWBOXGXAO7B5SLGFDF7RAAQQC ZQKZM3SWCUV4E4BM76UDKEKHBN4FFDJ52ZJUF5XMWR2D2BGRMABQC TAHNZ4UZMQJ5SM5GGVXCSZNX2ZFA5MBPBEDZLBR3NPT6ECC5OEWQC QRSG7RJSX5R255Y2HHTLYBXMBR374QS3PV2UJDWK2ZPMG7V66SSAC GY6B4NDD7FQNTOOFR53SFU4RVX4CVFV6NG5S6ZQ2J37HFAZSFSBQC UNZZPAQTA6ONYPQXUICTU6QFQCUM2TRBWVWO2L3PAZTZY6F5FPHQC ADHAOXXNVKFWHEYV77O74MZRNCUSS2A2AIHNPQT62EWX2AY4XH4AC O64A6IJJGMWJYUDR6VUFGYFPWWPN222BEMMLFCMLKDEFO5OVRE4QC 5KTOFVFDH2TUKNVY7VIL4GHFK7KPW5WDYMRU6EMI4276SF7CXBGQC H6LIOHTE46GHT5OK3HFCWZ56A7PTNWH476VS3HHKT3K5RQ5QJRWQC 6NRXEHSO2O7ERNNCXKCIHIZSTBXC7RMRO4SKOBDUPFXMTNDZJ53AC 3RG3K64UNBVMFYBBHNYCI7Y6GI7NZAHCCT76GMBBGK7PO4744BLAC SFZ7ZFEJSWMSBJVTVQJRH4SAX3LTYO3AGFVPD24HYTQDESKHMLUQC LTSFJDOV7PWQTVB44ZAPDHR6HUOAG4WZJQPP7TBCXRBS57EZ5T3AC K25EHKGA7AW7YAZLYLB27DXGX4QPHFQEXU4B4S7WLRPVIV3WUJ7QC YETF5UHCE3GS27IXWNLS4I3PVVBCFYRJTLPUETD5WILFFBEPTPRAC EWSZ2QIQQBG2EOVAU2IDFXQXE7D3PNFX3HE5LV2YPXEZONHM4MTQC WBQMAQLSGL2ZMUGJAJHTHF2DWAYL3LQO56VM7PMGNHSLHUNGZPJQC HYP7NYOZCLUZSNM3AA234JVSU3JNSQFN3G3DDPKR6IDEJA3MCRWQC U6GSJX5ZG4O7R3XO4CA7G62TTDE22HRZ2LL7EQKLQSYCHCAA3CQQC VBIKNV64COAFFZXT2MWPUFAZPSPFIIK2TOPGBXKIOU7XCVQ4LJ6AC WHTEZBXRS7R3AM44LJZFR2YE6RP4IWE3AB5V3DYGO4YJU7PBTMQAC QLLKRJFQMIZ6UDEN44E2Z6KZNBJN75FKMPDWIT4EKMIXZPKHEY2AC IU7QFC7V4DK5WB5D4VDQN7ZFTZNBQ5U7E2TGZVR7MIXFJDW2CXIQC IGP7FHYGXFXSDYGO5ABKFXBO2V2ZMYL6GSB2BWKB64T7GTGVXWKQC C4JNLSVRIR3BVGJRE7JOE5DADBGZTNKKTHLHHIAFTS6KCY4W63RAC EAPJCWPUTO4MRRM3TAMQC2AMLFVAOQPFDP4BQYT74ZLHGI5IISOAC OEG6DPRQVUDPTETGTOR7WYOJTIB4SWUPXGYW4FEPWSYYNULOCTIQC BKU3SBYQV4NMFT4HI3LPNSZ55M4OV2GVWZAQZUAIXXGLL7RPI7GAC E56TRR6IFFHTTJWJ4UUGKDSDGTN4YBIDYJCVLDRLMNY3MS3TWXSQC YBD5JJV7JVV6BVGGMNKQDV4U2QPAOKGNRUK2OVY7LFSDU5RWHCKAC TEJLAHEG6JYVPWBHUHIO6NTSB7HO62RJ6G5J2B6UNPDVG7XK4XIAC MW575RFTDFT5GPNR373ECHKFG6T66IKMSIMRGB3ZBKLAYATGVDVQC HQAWYBVCFQ2PBNEKQFMBBJRIJAWU75TAKYMREN6TSXDXNN7ORXWAC HBLAD3UT5OW4AVVJKVN55YQBJNWEACH5IOC5IFBKXJ33XQLUIHGQC BYGEHAR6KNZXJ2QWH5ASEB7SVDXTWANYRGHBPAO4FHBTBQJOGMRAC 2NMPOND2YKPM2UAML57TJ6NZXPDUHWPMWY6WJMLQ3BXVA6SXS2CAC 47GPXWYAN5HMMVVIWFEAY63MID4U2UHIBH4HNMDYWNQ2J6E2WX6AC BJKOD7ZFG2DJGJ6E4WZJD6ITNMRNNCALRVTNX26LMDSRK6VLNJGAC IVJFJ675FQ2V7JVOYEFISWM47QMESRSZQYGXBMIGAU3NG5E4MQWAC H4PTMRYDGOSGYLS5JK3IADXSWOXEWTZMUJ6OYSNODEWS7OMCBV3QC UPKMMJFFBYJRZHQDUNLVXKVJH32VNY5ZGEH3GXI3KOG7NO5OJF3AC M47OO2CYU6I4IGSY76VPSERKWG7AC6NGU343YAMGGTFPGYMWCXHAC ENVJVMMFPGW7UZNC5A27IQ4VZJDKXSNZ4I24BGYTTJXZXU6GAF7AC SC7MDSHCX3734KSWU4YFGJTKLJRSRM7AHC4MALZKQGDAHH42ILJQC QOTSIIJGJAYIO5PLOSYF6NFUJSY4ITXDSJUE4IN6ZSJK6HOQTBJAC 6DZO6E3ALZ477IYSCGVKASDYM54CZEDON55NR2UTUGOCZR3BMTAAC X575KR6QP76HLPGLLS6XINQGQEAQD76SNOKPJMTGKGR3JJW6A5EQC 6QF3TT2JA5DYRPTSEPZMZX352OY45GVZXJJ525EAUZEEOSLUKEDQC FMMNSJMBROWJ6OC4MUBK6KSBJDQ7R26S33HZTQRAF5CF5VMFNE6QC N7DHDONTAB6UEU4PHQR7BNSUQFAA4JBIVSTKDQ7V7OF3CLOEWXOQC A32NGEIBDOOKELILD6YPAGDCEDVVSYBSNJNS4RDXB7SHBQNIVNPQC BYCLZBRJTN2ZIINK42SBGJHKCPVXECL632SYTV6EEQROEUNZJFHAC 7UWOMG432IHX7BGGN7PPQUGSSUP6CCQNBXOO7TKNMKMK2R2WFOGAC ZH6EAGFIDERASR6IRHMOHY3RFYDIXB6SXBQZHA36X6NOENM6W43QC 723QWZKMMKC44ZAQQYSSOPCB65TKSORXU2D4PIHWOUEKICJGUBVAC BN7PSYS5IMGH4CXNCQZGOWBETO7KY4TKICB4ESZEZVXVGLOPVV7QC { pkgs ? import <nixpkgs> { } }:blackflake8importmagicipdbipythonisortpytesttyper];inpkgs.mkShell {buildInputs = with pkgs; [nixpkgs-fmtpre-commitshellcheckshfmt}] ++ pypkgs;shellHook = '''';export PYTHONBREAKPOINT=ipdb.set_trace;export PYTHONDONTWRITEBYTECODE=true;statixmdlletpkgs.python39pkgs.nodePackages.pyright# typer doesn't support click 8 which is what's packaged upstream# https://github.com/NixOS/nixpkgs/issues/129479# override it here 👍👍python39Packages = pkgs.python39Packages.override {overrides = self: super: {version = "7.1.2";src = super.fetchPypi {inherit version;sha256 = "d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a";};});};};pypkgs = with python39Packages; [inherit (old) pname;click = super.click.overrideAttrs (old: rec {
{ pkgs ? import <nixpkgs> { }, lib ? pkgs.lib, ... }:pkgs.python39Packages.buildPythonApplication {pname = "path_finder";version = "0.0.1";}checkInputs = with pkgs.python39Packages; [ pytestCheckHook ];propagatedBuildInputs = with pkgs.python39Packages; [ typer ];src = pkgs.lib.cleanSource ./.;
from typing import Optionalimport typercli = typer.Typer()@cli.command()def main(name: str, find_all: bool = False, parent_name: Optional[str] = None):parent_name = parent_name or ""path_finder = PathFinder.from_env()paths = path_finder.find(name, parent_name=parent_name)if not find_all:path = next(paths, None)paths = [path] if path else []for path in paths:typer.echo(path)if __name__ == "__main__":cli()if __package__:from .lib import PathFinderelse:from lib import PathFinder
import osfrom dataclasses import dataclassfrom pathlib import Pathfrom typing import Generator, Optional@dataclassclass PathFinder:paths: list[Path]@classmethoddef from_env(cls) -> "PathFinder":path = os.getenv("PATH")if not path:raise RuntimeError("PATH environment variable is not set.")return cls(list(map(Path, path.split(":"))))def find_first(self, name: str, parent_name: str = "") -> Optional[Path]:return next(self.find(name, parent_name=parent_name), None)def find(self, name: str, parent_name: str = "") -> Generator[Path, None, None]:for path in self.paths:if not path.is_dir():path = path.parentif parent_name:parents = (parent.joinpath(parent_name) for parent in path.parents)path = next((parent for parent in parents if parent.exists()), path)result_path = path.joinpath(name)if result_path.exists():yield result_pathpath = path.resolve()
from setuptools import find_packages, setupsetup(name="path_finder",version="0.0.1",py_modules=["path_finder.cli", "path_finder.lib"],entry_points={"console_scripts": ["path_finder = path_finder.cli:cli"]},pacakges=find_packages(),)
from unittest.mock import patchimport pytestfrom typer.testing import CliRunner@pytest.fixturedef invoke_cli():def invoke(*args):return CliRunner(mix_stderr=False).invoke(cli, args)yield invokedef test_cli_help_parent_name_no_bad_default(invoke_cli):"""typer produces [default: ] if main's signature for parent_name isn't Optionalso yeah we 💯 want to enforce a nice help message by making main's signaturea little more annoying"""result = invoke_cli("--help")for line in result.stdout.splitlines():if "--parent-name TEXT" in line:assert "default" not in linebreakelse:pytest.fail("expected --parent-name TEXT in stdout")@pytest.mark.parametrize("arg_find_all,search_results,expected_output",[("--no-find-all", ["one", "two"], ["one"]),("--find-all", ["one", "two"], ["one", "two"]),("--find-all", ["two"], ["two"]),("--no-find-all", ["two", "one"], ["two"]),("--find-all", [], []),("--no-find-all", [], []),],)def test_cli_find_all(arg_find_all, search_results, expected_output, invoke_cli):with patch.object(PathFinder, "find", return_value=iter(search_results)):result = invoke_cli("whatever", arg_find_all)assert expected_output == result.stdout.splitlines()from path_finder.cli import clifrom path_finder.lib import PathFinder
from pathlib import Pathdef test_find_first_does_not_exist(tmp_path: Path):path_finder = PathFinder([tmp_path])assert not tmp_path.joinpath("needle.txt").exists()assert path_finder.find_first("needle") is Noneassert path_finder.find_first("needle", parent_name="anything") is Nonedef test_find_first_parent_exists_needle_does_not(tmp_path: Path):tmp_path.joinpath("parent").mkdir()nest_one = tmp_path.joinpath("parent/nest_one")nest_two = tmp_path.joinpath("parent/nest_two")nest_one.mkdir()nest_two.mkdir()path_finder = PathFinder([nest_one])assert path_finder.find_first("needle") is Noneassert path_finder.find_first("needle", parent_name="nest_two") is Nonedef test_find_first_success_needle_in_parent_nested(tmp_path):search_dir = tmp_path.joinpath("thing/nested/bin")bundle_dir = search_dir.parent.parent.joinpath("bundle_dir")search_dir.mkdir(parents=True)bundle_dir.mkdir(parents=True)bundle_dir.joinpath("Bundle.app").write_text("app here 😎")actual = PathFinder(paths=[search_dir]).find_first("Bundle.app", parent_name="bundle_dir")assert actual is not None and actual.exists()def test_find_first_needle_in_path(tmp_path: Path):path_dir = tmp_path.joinpath("thing/nested/bin")path_dir.mkdir(parents=True)(path_dir / "file.txt").write_text("hi there :)")actual = PathFinder(paths=[path_dir]).find_first("file.txt")assert actual is not None and actual.exists()def test_find_first_depends_on_sort_order_of_paths(tmp_path: Path):no_match = tmp_path.joinpath("nomatch")no_match.mkdir()match_one = tmp_path.joinpath("one/file.txt")match_two = tmp_path.joinpath("two/file.txt")match_one.parent.mkdir()match_two.parent.mkdir()match_one.write_text("hi from match_one :)")match_two.write_text("hi from match_two :)")assert (PathFinder([no_match, match_one, match_two]).find_first("file.txt") == match_one)assert (PathFinder([no_match, match_two, match_one]).find_first("file.txt") == match_two)def test_find_many(tmp_path: Path):no_match = tmp_path.joinpath("nomatch")no_match.mkdir()match_one = tmp_path.joinpath("one/file.txt")match_two = tmp_path.joinpath("two/file.txt")match_one.parent.mkdir()match_two.parent.mkdir()match_one.write_text("hi from match_one :)")match_two.write_text("hi from match_two :)")path_finder = PathFinder([no_match.parent, match_one.parent, match_two])assert list(path_finder.find("file.txt")) == [match_one, match_two]def test_find_many_paths_contain_result(tmp_path: Path):"""if given full path PathFinder.find should return it."""no_match = tmp_path.joinpath("nomatch")no_match.mkdir()match_one = tmp_path.joinpath("one/file.txt")match_two = tmp_path.joinpath("two/file.txt")match_one.parent.mkdir()match_two.parent.mkdir()match_one.write_text("hi from match_one :)")match_two.write_text("hi from match_two :)")path_finder = PathFinder([no_match, match_one, match_two])assert list(path_finder.find("file.txt")) == [match_one, match_two]from path_finder.lib import PathFinder
repos:hooks:hooks:hooks:- id: mdl-markdown-lintername: markdown-linterdescription: ruby gem to lint markdown filesentry: mdl -glanguage: systemtypes: [markdown]minimum_pre_commit_version: 1.14.2- id: python-format-blackname: python-blackdescription: format python with blackentry: blacklanguage: systemtypes: [python]- id: python-sort-importsname: python-isortdescription: format python imports with isortentry: isortlanguage: systemtypes: [python]- id: python-lint-flake8name: python-flake8description: python flake8entry: flake8language: systemtypes: [python]# - id: python-pytest# name: python-pytest# description: python pytest# entry: pytest# language: system# types: [python]# pass_filenames: false# always_run: true# TODO getting these to work will be a pain# TODO consider using something like# TODO https://github.com/cachix/pre-commit-hooks.nix## - id: python-type-check-pyright# name: python-type-check-pyright# description: python type check pyright# entry: pyright# args: [./]# language: system# types: [python]# pass_filenames: false# always_run: true- id: nixpkgs-fmtname: nixpkgs-fmtdescription: Format nix code with nixpkgs-fmt.entry: nixpkgs-fmtlanguage: systemfiles: \.nix$always_run: trueminimum_pre_commit_version: 1.14.2- id: statixname: statixdescription: static linter for nix codeentry: statix check .language: systemfiles: \.nix$always_run: trueminimum_pre_commit_version: 1.14.2pass_filenames: false- repo: local- repo: https://github.com/executablebooks/mdformatrev: 0.7.8hooks:- id: mdformat# NOTE: these require shellcheck and shfmt to be installed# in the environment they should be installed by# lorri -> direnv -> nix-shell# automatically from ~/dotfiles/shell.nix- id: shellcheck- id: shfmt- repo: https://github.com/syntaqx/git-hooksrev: v0.0.17- id: trailing-whitespace- id: end-of-file-fixer- id: check-yaml- id: check-added-large-files- id: destroyed-symlinks- id: mixed-line-endingrev: v4.0.1- repo: https://github.com/pre-commit/pre-commit-hooks
mkKeyValue = key: value:letv =if pkgs.lib.isBool value then(if value then "True" else "False")else toString value;in"${key} = ${v}";
mkKeyValue = key: value: letv =if pkgs.lib.isBool valuethen(if valuethen "True"else "False")else toString value;in "${key} = ${v}";
stringify ={ mkKey ? (k: "${k}"), mkValue ? pkgs.lib.generators.mkValueStringDefault,}: attrs:(pkgs.lib.strings.concatStringsSep"\n"(pkgs.lib.attrsets.mapAttrsToList(key: value: "${mkKey key} ${mkValue value}")attrs));
stringify = {mkKey ? (k: "${k}"),mkValue ? pkgs.lib.generators.mkValueStringDefault,}: attrs: (pkgs.lib.strings.concatStringsSep"\n"(pkgs.lib.attrsets.mapAttrsToList(key: value: "${mkKey key} ${mkValue value}")attrs));
{ config, pkgs, ... }:lettmuxModal = with pkgs; tmuxPlugins.mkTmuxPlugin rec {pluginName = "tmux-modal";version = "unstable-2022-02-19";src = fetchFromGitHub {owner = "whame";repo = "tmux-modal";rev = "5ecffca7af0950e49f47a2681c9fb07ccfb9b407";sha256 = "sha256-pcleS1lyJQ5qV3B3actjNHJJwly6zi50FXegFMe5Iis=";};rtpFilePath = "${pluginName}.tmux";meta = {homepage = "https://github.com/whame/tmux-modal";description = "A modal mode for tmux.";longDescription =''
{config,pkgs,...}: lettmuxModal = with pkgs;tmuxPlugins.mkTmuxPlugin rec {pluginName = "tmux-modal";version = "unstable-2022-02-19";src = fetchFromGitHub {owner = "whame";repo = "tmux-modal";rev = "5ecffca7af0950e49f47a2681c9fb07ccfb9b407";sha256 = "sha256-pcleS1lyJQ5qV3B3actjNHJJwly6zi50FXegFMe5Iis=";};rtpFilePath = "${pluginName}.tmux";meta = {homepage = "https://github.com/whame/tmux-modal";description = "A modal mode for tmux.";longDescription = ''
license = lib.licenses.mit;platforms = lib.platforms.unix;maintainers = with lib.maintainers; [ ];
license = lib.licenses.mit;platforms = lib.platforms.unix;maintainers = with lib.maintainers; [];};postInstall = ''sed -i -e 's|KBD_CMD=M-m|KBD_CMD=C-x |g' $target/${rtpFilePath}sed -i -e 's|KBD_CMD_EXIT=M-m|KBD_CMD_EXIT=C-x|g' $target/${rtpFilePath}'';
postInstall = ''sed -i -e 's|KBD_CMD=M-m|KBD_CMD=C-x |g' $target/${rtpFilePath}sed -i -e 's|KBD_CMD_EXIT=M-m|KBD_CMD_EXIT=C-x|g' $target/${rtpFilePath}'';};in{
in {
modules-left = [ "clock" "custom/media" ];modules-center = [ "sway/mode" "sway/workspaces" ];modules-right = [ "idle_inhibitor" "pulseaudio" "network" "bluetooth" "battery" ];
modules-left = ["clock" "custom/media"];modules-center = ["sway/mode" "sway/workspaces"];modules-right = ["idle_inhibitor" "pulseaudio" "network" "bluetooth" "battery"];
exec = with pkgs; writeShellApplication {name = "waybar_media_play_pause_toggler";runtimeInputs = [ playerctl ];text = ''player_status=$(playerctl status 2>/dev/null)
exec = with pkgs;writeShellApplication {name = "waybar_media_play_pause_toggler";runtimeInputs = [playerctl];text = ''player_status=$(playerctl status 2>/dev/null)
compose_mode = {# a mode for entering other modes, or inserting commands based on# sequential key presses# e.g. Shift+space -> k -> s == bemenu_try_restart_systemd_user_servicesf = "fullscreen toggle; mode default;";k = "mode kill_mode";r = "mode resize_mode";t = ''exec swaymsg [app_id="scratch_terminal"] scratchpad show; mode default;'';v = "mode volume_mode";"Shift+space" = "mode disabled_mode";} // leaveModeKeys;kill_mode = {"Shift+q" = "exec swaymsg exit";q = "${execNwgBar}";r = "exec systemctl reboot -i";s = "exec bemenu_try_restart_systemd_user_services; mode default;";w = "kill; mode default;";} // leaveModeKeys;resize_mode = {"${cfg.up}" = "resize shrink width 15 px";"${cfg.down}" = "resize grow height 15 px";"${cfg.left}" = "resize shrink height 15 px";"${cfg.right}" = "resize grow width 15 px";"Shift+${cfg.up}" = "resize shrink width 45 px";"Shift+${cfg.down}" = "resize grow height 45 px";"Shift+${cfg.left}" = "resize shrink height 45 px";"Shift+${cfg.right}" = "resize grow width 45 px";} // leaveModeKeys;volume_mode = {"${cfg.up}" = "${setVolume} +1%";"Shift+${cfg.up}" = "${setVolume} +10%";"${cfg.down}" = "${setVolume} -1%";"Shift+${cfg.down}" = "${setVolume} -10%";} // leaveModeKeys;workspace_mode = {"0" = "workspace 0";"1" = "workspace 1";"2" = "workspace 2";"3" = "workspace 3";"4" = "workspace 4";"5" = "workspace 5";"6" = "workspace 6";"7" = "workspace 7";"8" = "workspace 8";"9" = "workspace 9";"${cfg.right}" = "workspace next";"${cfg.left}" = "workspace prev";} // leaveModeKeys;
compose_mode ={# a mode for entering other modes, or inserting commands based on# sequential key presses# e.g. Shift+space -> k -> s == bemenu_try_restart_systemd_user_servicesf = "fullscreen toggle; mode default;";k = "mode kill_mode";r = "mode resize_mode";t = ''exec swaymsg [app_id="scratch_terminal"] scratchpad show; mode default;'';v = "mode volume_mode";"Shift+space" = "mode disabled_mode";}// leaveModeKeys;kill_mode ={"Shift+q" = "exec swaymsg exit";q = "${execNwgBar}";r = "exec systemctl reboot -i";s = "exec bemenu_try_restart_systemd_user_services; mode default;";w = "kill; mode default;";}// leaveModeKeys;resize_mode ={"${cfg.up}" = "resize shrink width 15 px";"${cfg.down}" = "resize grow height 15 px";"${cfg.left}" = "resize shrink height 15 px";"${cfg.right}" = "resize grow width 15 px";"Shift+${cfg.up}" = "resize shrink width 45 px";"Shift+${cfg.down}" = "resize grow height 45 px";"Shift+${cfg.left}" = "resize shrink height 45 px";"Shift+${cfg.right}" = "resize grow width 45 px";}// leaveModeKeys;volume_mode ={"${cfg.up}" = "${setVolume} +1%";"Shift+${cfg.up}" = "${setVolume} +10%";"${cfg.down}" = "${setVolume} -1%";"Shift+${cfg.down}" = "${setVolume} -10%";}// leaveModeKeys;workspace_mode ={"0" = "workspace 0";"1" = "workspace 1";"2" = "workspace 2";"3" = "workspace 3";"4" = "workspace 4";"5" = "workspace 5";"6" = "workspace 6";"7" = "workspace 7";"8" = "workspace 8";"9" = "workspace 9";"${cfg.right}" = "workspace next";"${cfg.left}" = "workspace prev";}// leaveModeKeys;
preBuild = old.preBuild or "" + ''substituteInPlace setup.py --replace 'version = "3.0.0"' 'version = "2.8.0"''';preConfigure = (old.preConfigure or "") + ''cat << EOF > requirements.txtblessed==1.19.0readchar==2.0.1python-editor==1.0.4EOF
preBuild =old.preBuildor ""+ ''substituteInPlace setup.py --replace 'version = "3.0.0"' 'version = "2.8.0"''';preConfigure =(old.preConfigure or "")+ '' cat << EOF > requirements.txtblessed==1.19.0readchar==2.0.1python-editor==1.0.4EOF
"profile non-production-connect" = awscliConfig // {sso_account_id = "186258024085";sso_role_name = "non-production-backend-access";};
"profile non-production-connect" =awscliConfig// {sso_account_id = "186258024085";sso_role_name = "non-production-backend-access";};
ph-widget() {ph info | grep -q 'Database Version' && ph show --field password "$(ph grep -i . | fzf)" | wl-copy --trim-newline}
ph-widget() {ph info | grep -q 'Database Version' && ph show --field password "$(ph grep -i . | fzf)" | wl-copy --trim-newline}
sessionVariables = rec {EDITOR = if isEmacsEnabled then "emacsclient -t" else "nvim";GIT_EDITOR = EDITOR;KEYTIMEOUT = "1";LESS = "-SRXF";} // (if isEmacsEnabled then {VISUAL = "emacs";} else { });
sessionVariables =rec {EDITOR =if isEmacsEnabledthen "emacsclient -t"else "nvim";GIT_EDITOR = EDITOR;KEYTIMEOUT = "1";LESS = "-SRXF";}// (if isEmacsEnabledthen {VISUAL = "emacs";}else {});
home.packages = with pkgs; [curldirenvfdhtopjqneofetchpre-commitprocsripgrepsshfswget] ++ builtins.attrValues (import ./shell_extras.nix { inherit pkgs; });
home.packages = with pkgs;[curldirenvfdhtopjqneofetchpre-commitprocsripgrepsshfswget]++ builtins.attrValues (import ./shell_extras.nix {inherit pkgs;});
xdg.configFile."pgcli/config".text = ''# Generated by home-manager from nixpkgs.pgcli in ~/dotfiles# For a list of options see: https://www.pgcli.com/config
xdg.configFile."pgcli/config".text =''# Generated by home-manager from nixpkgs.pgcli in ~/dotfiles# For a list of options see: https://www.pgcli.com/config
buildPythonApplication rec {pname = "passhole";version = "1.9.7";src = fetchPypi {inherit pname version;sha256 = "sha256-0qOxGv6YdcK4AjbE+IbBxYNBe/NE/z4k6PuVGCPdjFk=";};propagatedBuildInputs = [coloramafuturepykeepass_cachepynputpyotppkgs.gnome.zenity];}
buildPythonApplication rec {pname = "passhole";version = "1.9.7";src = fetchPypi {inherit pname version;sha256 = "sha256-0qOxGv6YdcK4AjbE+IbBxYNBe/NE/z4k6PuVGCPdjFk=";};propagatedBuildInputs = [coloramafuturepykeepass_cachepynputpyotppkgs.gnome.zenity];}
boot.initrd.availableKernelModules = [ "xhci_pci" "thunderbolt" "vmd" "nvme" "usb_storage" "sd_mod" "rtsx_pci_sdmmc" ];boot.initrd.kernelModules = [ "dm-snapshot" ];boot.kernelModules = [ "kvm-intel" ];boot.extraModulePackages = [ ];
boot.initrd.availableKernelModules = ["xhci_pci" "thunderbolt" "vmd" "nvme" "usb_storage" "sd_mod" "rtsx_pci_sdmmc"];boot.initrd.kernelModules = ["dm-snapshot"];boot.kernelModules = ["kvm-intel"];boot.extraModulePackages = [];
fileSystems."/" ={device = "/dev/disk/by-uuid/316096c1-57d0-4536-8397-3ad8d2710647";fsType = "ext4";};
fileSystems."/" = {device = "/dev/disk/by-uuid/316096c1-57d0-4536-8397-3ad8d2710647";fsType = "ext4";};
boot.initrd.availableKernelModules = [ "virtio_pci" "virtio_scsi" "ahci" "sd_mod" ];boot.initrd.kernelModules = [ ];boot.kernelModules = [ ];boot.extraModulePackages = [ ];
boot.initrd.availableKernelModules = ["virtio_pci" "virtio_scsi" "ahci" "sd_mod"];boot.initrd.kernelModules = [];boot.kernelModules = [];boot.extraModulePackages = [];
boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" ];boot.initrd.kernelModules = [ "dm-snapshot" ];boot.kernelModules = [ "kvm-amd" ];boot.extraModulePackages = [ ];
boot.initrd.availableKernelModules = ["nvme" "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod"];boot.initrd.kernelModules = ["dm-snapshot"];boot.kernelModules = ["kvm-amd"];boot.extraModulePackages = [];
after = [ "network-pre.target" "tailscale.service" ];wants = [ "network-pre.target" "tailscale.service" ];wantedBy = [ "multi-user.target" ];
after = ["network-pre.target" "tailscale.service"];wants = ["network-pre.target" "tailscale.service"];wantedBy = ["multi-user.target"];
postFixup = old.postFixup + ''wrapProgram $out/bin/zoom-us --unset XDG_SESSION_TYPEwrapProgram $out/bin/zoom --unset XDG_SESSION_TYPE'';
postFixup =old.postFixup+ ''wrapProgram $out/bin/zoom-us --unset XDG_SESSION_TYPEwrapProgram $out/bin/zoom --unset XDG_SESSION_TYPE'';
} else { } // {# allows firefox to see userChrome.css etc"toolkit.legacyUserProfileCustomizations.stylesheets" = true;
}else{}// {# allows firefox to see userChrome.css etc"toolkit.legacyUserProfileCustomizations.stylesheets" = true;
"browser.startup.homepage" = "https://duckduckgo.com";"browser.search.region" = "US";"browser.search.isUS" = true;"browser.bookmarks.showMobileBookmarks" = true;"browser.toolbars.bookmarks.visibility" = "never";};
"browser.startup.homepage" = "https://duckduckgo.com";"browser.search.region" = "US";"browser.search.isUS" = true;"browser.bookmarks.showMobileBookmarks" = true;"browser.toolbars.bookmarks.visibility" = "never";};
python39Packages.buildPythonApplication rec {pname = "lastpass-authenticator-export";version = "unstable-2022-03-31";src = fetchFromGitHub {owner = "dmaasland";repo = "lastpass-authenticator-export";rev = "154422b60152f328435e71bed722be5788808486";sha256 = "sha256-CmNBrEFuwWCdFijU5VUzg/zzLQ2ALaIjAWKtAZnehes=";};setup = ''from setuptools import find_packages, setup
python39Packages.buildPythonApplication rec {pname = "lastpass-authenticator-export";version = "unstable-2022-03-31";src = fetchFromGitHub {owner = "dmaasland";repo = "lastpass-authenticator-export";rev = "154422b60152f328435e71bed722be5788808486";sha256 = "sha256-CmNBrEFuwWCdFijU5VUzg/zzLQ2ALaIjAWKtAZnehes=";};setup = ''from setuptools import find_packages, setup
setup(name="${pname}",version="${version}",py_modules=["lastpass_authenticator_export"],entry_points={"console_scripts": ["lastpass_authenticator_export = lastpass_authenticator_export:main"]},pacakges=find_packages(),)'';postUnpack = ''echo '${setup}' > $sourceRoot/setup.pymv $sourceRoot/lastpass-authenticator-export.py $sourceRoot/lastpass_authenticator_export.py'';
setup(name="${pname}",version="${version}",py_modules=["lastpass_authenticator_export"],entry_points={"console_scripts": ["lastpass_authenticator_export = lastpass_authenticator_export:main"]},pacakges=find_packages(),)'';postUnpack = ''echo '${setup}' > $sourceRoot/setup.pymv $sourceRoot/lastpass-authenticator-export.py $sourceRoot/lastpass_authenticator_export.py'';
{ email, realName, imapHost, smtpHost, gmail ? false }: {flavor = if gmail then "gmail.com" else "plain";address = email;userName = email;realName = realName;
{email,realName,imapHost,smtpHost,gmail ? false,}: {inherit realName;flavor =if gmailthen "gmail.com"else "plain";address = email;userName = email;
passwordCommand =if pkgs.stdenv.hostPlatform.isLinux then"${pkgs.gnome3.libsecret}/bin/secret-tool lookup email ${email}"else# TODO use config.home.username"security find-generic-password -a christophercummings -s ${email} -w";
passwordCommand =if pkgs.stdenv.hostPlatform.isLinuxthen "${pkgs.gnome3.libsecret}/bin/secret-tool lookup email ${email}"else# TODO use config.home.username"security find-generic-password -a christophercummings -s ${email} -w";
mbsync = {enable = true;create = "both";expunge = "both";remove = "both";extraConfig.account = {# NOTE microsoft office 365 imap servers may require this to be 1# because they do not support concurrent imap commandsPipelineDepth = 50;
mbsync = {enable = true;create = "both";expunge = "both";remove = "both";extraConfig.account = {# NOTE microsoft office 365 imap servers may require this to be 1# because they do not support concurrent imap commandsPipelineDepth = 50;};
(template "email@email.domain" "Real Name" "imap.email.domain" "smtp.email.domain") // {# you can pass extra params here if necessary. otherwise omit the `// { ... }`primary = true;}
(template "email@email.domain" "Real Name" "imap.email.domain" "smtp.email.domain")// {# you can pass extra params here if necessary. otherwise omit the `// { ... }`primary = true;}
outputs ={ self, nixpkgs, emacs-overlay, home-manager, nixos-hardware, nix-doom-emacs, wayland-overlay, ...}@inputs:
outputs = {self,nixpkgs,emacs-overlay,home-manager,nixos-hardware,nix-doom-emacs,wayland-overlay,pre-commit-hooks,...} @ inputs: letoverlays = [emacs-overlay.overlay wayland-overlay.overlay];pkgs = nixpkgs.legacyPackages.x86_64-linux;helloDotfiles = pkgs.writeShellApplication {name = "helloDotfiles";text = ''echo 👋👋 hello from github:averagechris/dotfilesecho have a nice day 😎'';};in {overlays = {emacs = emacs-overlay.overlay;wayland = wayland-overlay.overlay;};
letoverlays = [ emacs-overlay.overlay wayland-overlay.overlay ];in{inherit overlays;
nixosConfigurations = {thelio-nixos = nixpkgs.lib.nixosSystem {system = "x86_64-linux";specialArgs = {inherit inputs overlays;};modules = [./nixpkgs/nixos/thelionixos-hardware.nixosModules.system76./nixpkgs/nixos/common.nix./nixpkgs/nixos/desktop_common.nix./nixpkgs/nixos/graphical.nix./nixpkgs/nixos/greetd.nix./nixpkgs/nixos/networking.nix./nixpkgs/nixos/docker.nix./nixpkgs/nixos/sound.nix./nixpkgs/nixos/tailscale.nix./nixpkgs/nixos/users/chris.nix./nixpkgs/nixos/users/chris-focus.nixhome-manager.nixosModules.home-manager{home-manager.useGlobalPkgs = true;home-manager.useUserPackages = true;}];};xps-nixos = nixpkgs.lib.nixosSystem {system = "x86_64-linux";specialArgs = {inherit inputs overlays;};modules = [./nixpkgs/nixos/xpsnixos-hardware.nixosModules.system76./nixpkgs/nixos/common.nix./nixpkgs/nixos/desktop_common.nix./nixpkgs/nixos/docker.nix./nixpkgs/nixos/graphical.nix./nixpkgs/nixos/greetd.nix./nixpkgs/nixos/networking.nix./nixpkgs/nixos/sound.nix./nixpkgs/nixos/tailscale.nix./nixpkgs/nixos/users/chris-focus.nix./nixpkgs/nixos/users/chris.nixhome-manager.nixosModules.home-manager{home-manager.useGlobalPkgs = true;home-manager.useUserPackages = true;}];};tootsie = nixpkgs.lib.nixosSystem {system = "x86_64-linux";specialArgs = {inherit inputs overlays;};modules = [./nixpkgs/nixos/tootsie./nixpkgs/nixos/common.nix./nixpkgs/nixos/tailscale.nix./nixpkgs/nixos/users/chris-minimal.nixhome-manager.nixosModules.home-manager{home-manager.useGlobalPkgs = true;home-manager.useUserPackages = true;}];};};
nixosConfigurations = {thelio-nixos = nixpkgs.lib.nixosSystem {system = "x86_64-linux";specialArgs = { inherit inputs overlays; };modules = [./nixpkgs/nixos/thelionixos-hardware.nixosModules.system76./nixpkgs/nixos/common.nix./nixpkgs/nixos/desktop_common.nix./nixpkgs/nixos/graphical.nix./nixpkgs/nixos/greetd.nix./nixpkgs/nixos/networking.nix./nixpkgs/nixos/docker.nix./nixpkgs/nixos/sound.nix./nixpkgs/nixos/tailscale.nix./nixpkgs/nixos/users/chris.nix./nixpkgs/nixos/users/chris-focus.nixhome-manager.nixosModules.home-manager{home-manager.useGlobalPkgs = true;home-manager.useUserPackages = true;}];};
packages.x86_64-linux.default = helloDotfiles;
xps-nixos = nixpkgs.lib.nixosSystem {system = "x86_64-linux";specialArgs = { inherit inputs overlays; };modules = [./nixpkgs/nixos/xpsnixos-hardware.nixosModules.system76./nixpkgs/nixos/common.nix./nixpkgs/nixos/desktop_common.nix./nixpkgs/nixos/docker.nix./nixpkgs/nixos/graphical.nix./nixpkgs/nixos/greetd.nix./nixpkgs/nixos/networking.nix./nixpkgs/nixos/sound.nix./nixpkgs/nixos/tailscale.nix./nixpkgs/nixos/users/chris-focus.nix./nixpkgs/nixos/users/chris.nixhome-manager.nixosModules.home-manager{home-manager.useGlobalPkgs = true;home-manager.useUserPackages = true;}];
checks.x86_64-linux = {pre-commit = pre-commit-hooks.lib.x86_64-linux.run {src = ./.;hooks = {alejandra.enable = true;statix.enable = true;shellcheck.enable = true;markdown-formatter = {enable = true;name = "markdown-formatter";types = ["markdown"];language = "system";pass_filenames = true;entry = with pkgs.python310Packages; "${mdformat}/bin/mdformat";};markdown-linter = {enable = true;name = "markdown-linter";types = ["markdown"];language = "system";pass_filenames = true;entry = with pkgs; "${mdl}/bin/mdl -g";};
tootsie = nixpkgs.lib.nixosSystem {system = "x86_64-linux";specialArgs = { inherit inputs overlays; };modules = [./nixpkgs/nixos/tootsie./nixpkgs/nixos/common.nix./nixpkgs/nixos/tailscale.nix./nixpkgs/nixos/users/chris-minimal.nixhome-manager.nixosModules.home-manager{home-manager.useGlobalPkgs = true;home-manager.useUserPackages = true;}];};
devShells = {x86_64-linux.default = pkgs.mkShell {inherit (self.checks.x86_64-linux.pre-commit) shellHook;buildInputs = with pkgs; [alejandracachixhelloDotfilesmdlstatixpython310Packages.mdformat];
"locked": {"lastModified": 1644229661,"narHash": "sha256-1YdnJAsNy69bpcjuoKdOYQX0YxZBiCYZo4Twxerqv7k=","owner": "numtide","repo": "flake-utils","rev": "3cecb5b042f7f209c56ffd8371b2711a290ec797","type": "github"},"original": {"owner": "numtide","repo": "flake-utils","type": "github"}},"flake-utils_4": {
"pre-commit-hooks": {"inputs": {"flake-utils": "flake-utils_3","nixpkgs": ["nixpkgs"]},"locked": {"lastModified": 1652714503,"narHash": "sha256-qQKVEfDe5FqvGgkZtg5Pc491foeiDPIOeycHMqnPDps=","owner": "cachix","repo": "pre-commit-hooks.nix","rev": "521a524771a8e93caddaa0ac1d67d03766a8b0b3","type": "github"},"original": {"owner": "cachix","repo": "pre-commit-hooks.nix","type": "github"}},
/.direnv/