summaryrefslogtreecommitdiff
path: root/Biz
diff options
context:
space:
mode:
authorBen Sima <ben@bsima.me>2023-08-16 14:18:10 -0400
committerBen Sima <ben@bsima.me>2023-08-16 18:25:00 -0400
commit7d7e0c02351303489d5555627337a39b519b536a (patch)
tree794817b6d6046a265a129c910885339058773198 /Biz
parent30d03210f7ac5b12235760f625bac5ff3aa3f85a (diff)
Get python targets building
I added 'black' to Biz/Lint.hs, but not the others because they rely on dependencies being in the PYTHONPATH to work, so they are only relevant in nix builds and repls. I also made some other tweaks to the python checkPhase and linted all the files. Everything should be building and linting correctly now.
Diffstat (limited to 'Biz')
-rw-r--r--Biz/Bild.nix2
-rw-r--r--Biz/Bild/Builder.nix11
-rw-r--r--Biz/Bild/Deps/exllama.nix1
-rw-r--r--Biz/Bild/Deps/llama-cpp.nix1
-rw-r--r--Biz/Bild/Deps/nostr-rs-relay.nix2
-rw-r--r--Biz/Bild/Example.py13
-rw-r--r--Biz/Bild/Sources.nix2
-rw-r--r--Biz/Cloud/Comms.nix2
-rw-r--r--Biz/Cloud/Comms/Jitsi.nix2
-rw-r--r--Biz/Cloud/Comms/Mumble.nix2
-rw-r--r--Biz/Cloud/NostrRelay.nix2
-rw-r--r--Biz/Cloud/Web.nix2
-rwxr-xr-xBiz/Dragons/main.py69
-rwxr-xr-xBiz/Ide/mktags2
-rwxr-xr-xBiz/Ide/repl1
-rw-r--r--Biz/Lint.hs12
-rw-r--r--Biz/Nixpert.nix2
-rwxr-xr-xBiz/Que/Client.py36
18 files changed, 103 insertions, 61 deletions
diff --git a/Biz/Bild.nix b/Biz/Bild.nix
index dca1b3b..918d6b1 100644
--- a/Biz/Bild.nix
+++ b/Biz/Bild.nix
@@ -146,7 +146,7 @@ rec {
} // { env = ghc; };
env = let
- linters = with nixpkgs.pkgs; [ ormolu hlint deadnix indent ];
+ linters = with nixpkgs.pkgs; [ ormolu hlint deadnix indent black];
in nixpkgs.pkgs.mkShell {
name = "bizdev";
# this should just be dev tools
diff --git a/Biz/Bild/Builder.nix b/Biz/Bild/Builder.nix
index 214c110..2b1403a 100644
--- a/Biz/Bild/Builder.nix
+++ b/Biz/Bild/Builder.nix
@@ -59,10 +59,13 @@ in {
buildInputs = sysdeps_;
checkInputs = [(private.pythonWith (p: with p; [black mypy pylint]))];
checkPhase = ''
- black --quiet --exclude 'setup\.py$' --check .
- pylint --errors-only .
- mypy --strict --no-error-summary --exclude 'setup\.py$' .
- python -m ${main} test
+ check() {
+ $@ || { echo "fail: $name: $3"; exit 1; }
+ }
+ check python -m black --quiet --exclude 'setup\.py$' --check .
+ check python -m pylint --errors-only .
+ check python -m mypy --strict --no-error-summary --exclude 'setup\.py$' .
+ check python -m ${main} test
'';
preBuild = ''
# initialize possibly-empty subdirectories as python modules
diff --git a/Biz/Bild/Deps/exllama.nix b/Biz/Bild/Deps/exllama.nix
index 54d6df1..1f7e529 100644
--- a/Biz/Bild/Deps/exllama.nix
+++ b/Biz/Bild/Deps/exllama.nix
@@ -2,7 +2,6 @@
, sources
, buildPythonPackage
, pythonOlder
-, fetchFromGitHub
, torch # tested on 2.0.1 and 2.1.0 (nightly) with cu118
, safetensors
, sentencepiece
diff --git a/Biz/Bild/Deps/llama-cpp.nix b/Biz/Bild/Deps/llama-cpp.nix
index 85bd778..b247252 100644
--- a/Biz/Bild/Deps/llama-cpp.nix
+++ b/Biz/Bild/Deps/llama-cpp.nix
@@ -1,5 +1,4 @@
{ stdenv
-, pkgs
, sources
, python3
, cmake
diff --git a/Biz/Bild/Deps/nostr-rs-relay.nix b/Biz/Bild/Deps/nostr-rs-relay.nix
index 83d477c..bb0a1cd 100644
--- a/Biz/Bild/Deps/nostr-rs-relay.nix
+++ b/Biz/Bild/Deps/nostr-rs-relay.nix
@@ -1,4 +1,4 @@
-{ lib, fetchFromSourcehut, rustPlatform, pkg-config, openssl }:
+{ fetchFromSourcehut, rustPlatform, pkg-config, openssl }:
rustPlatform.buildRustPackage rec {
pname = "nostr-rs-relay";
diff --git a/Biz/Bild/Example.py b/Biz/Bild/Example.py
index 78a8a6a..25686fa 100644
--- a/Biz/Bild/Example.py
+++ b/Biz/Bild/Example.py
@@ -1,15 +1,16 @@
+"""
+Example Python file that also serves as a test case for bild.
+fernet."""
# : out example
# : dep cryptography
import sys
-from typing import List
-
-from cryptography.fernet import Fernet
+import cryptography.fernet
def cryptic_hello(name: str) -> str:
"Example taken from `cryptography` docs."
- key = Fernet.generate_key()
- f = Fernet(key)
+ key = cryptography.fernet.Fernet.generate_key()
+ f = cryptography.fernet.Fernet(key)
token = f.encrypt(hello(name).encode("utf-8"))
ret = f.decrypt(token).decode("utf-8")
assert ret == hello(name)
@@ -17,10 +18,12 @@ def cryptic_hello(name: str) -> str:
def hello(name: str) -> str:
+ "Say hello"
return f"Hello {name}"
def main() -> None:
+ "Entrypoint"
if "test" in sys.argv:
print("testing success")
print(cryptic_hello("world"))
diff --git a/Biz/Bild/Sources.nix b/Biz/Bild/Sources.nix
index 1938409..927683a 100644
--- a/Biz/Bild/Sources.nix
+++ b/Biz/Bild/Sources.nix
@@ -126,6 +126,7 @@ let
optionalAttrs = cond: as: if cond then as else {};
# fetchTarball version that is compatible between all the versions of Nix
+ # deadnix: skip
builtins_fetchTarball = { url, name ? null, sha256 }@attrs:
let
inherit (builtins) lessThan nixVersion fetchTarball;
@@ -136,6 +137,7 @@ let
fetchTarball attrs;
# fetchurl version that is compatible between all the versions of Nix
+ # deadnix: skip
builtins_fetchurl = { url, name ? null, sha256 }@attrs:
let
inherit (builtins) lessThan nixVersion fetchurl;
diff --git a/Biz/Cloud/Comms.nix b/Biz/Cloud/Comms.nix
index 64fe7c7..700296d 100644
--- a/Biz/Cloud/Comms.nix
+++ b/Biz/Cloud/Comms.nix
@@ -1,4 +1,4 @@
-{ pkgs, config, ... }:
+{ ... }:
{
imports = [
diff --git a/Biz/Cloud/Comms/Jitsi.nix b/Biz/Cloud/Comms/Jitsi.nix
index 30e6b44..17aeced 100644
--- a/Biz/Cloud/Comms/Jitsi.nix
+++ b/Biz/Cloud/Comms/Jitsi.nix
@@ -1,4 +1,4 @@
-{ config, pkgs, ... }:
+{ config, ... }:
{
services.jitsi-meet = {
diff --git a/Biz/Cloud/Comms/Mumble.nix b/Biz/Cloud/Comms/Mumble.nix
index fed305e..d728a07 100644
--- a/Biz/Cloud/Comms/Mumble.nix
+++ b/Biz/Cloud/Comms/Mumble.nix
@@ -1,4 +1,4 @@
-{ config, pkgs, ... }:
+{ config, ... }:
# mumble and related services
let
diff --git a/Biz/Cloud/NostrRelay.nix b/Biz/Cloud/NostrRelay.nix
index d8ffd3a..73c1366 100644
--- a/Biz/Cloud/NostrRelay.nix
+++ b/Biz/Cloud/NostrRelay.nix
@@ -1,4 +1,4 @@
-{ config, lib, pkgs, ... }:
+{ config, pkgs, ... }:
let
ports = import ./Ports.nix;
diff --git a/Biz/Cloud/Web.nix b/Biz/Cloud/Web.nix
index 3afc2ae..913bded 100644
--- a/Biz/Cloud/Web.nix
+++ b/Biz/Cloud/Web.nix
@@ -1,4 +1,4 @@
-{ config, pkgs, ... }:
+{ config, ... }:
let
rootDomain = config.networking.domain;
diff --git a/Biz/Dragons/main.py b/Biz/Dragons/main.py
index bb10441..7813f45 100755
--- a/Biz/Dragons/main.py
+++ b/Biz/Dragons/main.py
@@ -1,4 +1,5 @@
#!/usr/bin/env python
+# : out dragons.py
"""
Analyze developer allocation across a codebase.
"""
@@ -10,15 +11,16 @@ import os
import re
import subprocess
import sys
+import typing
-def find_user(line):
+def find_user(line: str) -> typing.Any:
"""Given 'Ben Sima <ben@bsima.me>', finds `Ben Sima'. Returns the first
matching string."""
return re.findall(r"^[^<]*", line)[0].strip()
-def authors_for(path, active_users):
+def authors_for(path: str, active_users: typing.List[str]) -> typing.Dict[str, str]:
"""Return a dictionary of {author: commits} for given path. Usernames not in
the 'active_users' list will be filtered out."""
raw = subprocess.check_output(
@@ -35,10 +37,10 @@ def authors_for(path, active_users):
return data
-def mailmap_users():
+def mailmap_users() -> typing.List[str]:
"""Returns users from the .mailmap file."""
users = []
- with open(".mailmap") as file:
+ with open(".mailmap", encoding="utf-8") as file:
lines = file.readlines()
for line in lines:
users.append(find_user(line))
@@ -48,7 +50,7 @@ def mailmap_users():
MAX_SCORE = 10
-def score(blackhole, liability, good, total):
+def score(blackhole: float, liability: float, good: int, total: int) -> float:
"Calculate the score."
weights = {
"blackhole": 0.5,
@@ -65,9 +67,10 @@ def score(blackhole, liability, good, total):
)
-def get_args():
+def get_args() -> typing.Any:
"Parse CLI arguments."
cli = argparse.ArgumentParser(description=__doc__)
+ cli.add_argument("test", action="store_true", help="run the test suite")
cli.add_argument("repo", default=".", help="the git repo to run on", metavar="REPO")
cli.add_argument(
"-b",
@@ -88,7 +91,11 @@ def get_args():
help="print stale files (haven't been touched in 6 months)",
)
cli.add_argument(
- "-i", "--ignored", nargs="+", default=[], help="patterns to ignore in paths",
+ "-i",
+ "--ignored",
+ nargs="+",
+ default=[],
+ help="patterns to ignore in paths",
)
cli.add_argument(
"--active-users",
@@ -106,19 +113,7 @@ def get_args():
return cli.parse_args()
-def guard_git(repo):
- "Guard against non-git repos."
- is_git = subprocess.run(
- ["git", "rev-parse"],
- stderr=subprocess.PIPE,
- stdout=subprocess.PIPE,
- check=False,
- ).returncode
- if is_git != 0:
- sys.exit(f"error: not a git repository: {repo}")
-
-
-def staleness(path, now):
+def staleness(path: str, now: datetime.datetime) -> int:
"How long has it been since this file was touched?"
timestamp = datetime.datetime.strptime(
subprocess.check_output(["git", "log", "-n1", "--pretty=%aI", path])
@@ -133,7 +128,9 @@ def staleness(path, now):
class Repo:
"Represents a repo and stats for the repo."
- def __init__(self, ignored_paths, active_users):
+ def __init__(
+ self, ignored_paths: typing.List[str], active_users: typing.List[str]
+ ) -> None:
self.paths = [
p
for p in subprocess.check_output(["git", "ls-files", "--no-deleted"])
@@ -158,7 +155,7 @@ class Repo:
if _staleness > 180:
self.stale[path] = _staleness
- def print_blackholes(self, full):
+ def print_blackholes(self, full: bool) -> None:
"Print number of blackholes, or list of all blackholes."
# note: file renames may result in false positives
n_blackhole = len(self.blackholes)
@@ -167,7 +164,7 @@ class Repo:
for path in self.blackholes:
print(f" {path}")
- def print_liabilities(self, full):
+ def print_liabilities(self, full: bool) -> None:
"Print number of liabilities, or list of all liabilities."
n_liabilities = len(self.liabilities)
print(f"Liabilities: {n_liabilities}")
@@ -175,20 +172,17 @@ class Repo:
for path, authors in self.liabilities.items():
print(f" {path} ({', '.join(authors)})")
- def print_score(self):
+ def print_score(self) -> None:
"Print the overall score."
n_total = len(self.stats.keys())
n_blackhole = len(self.blackholes)
n_liabilities = len(self.liabilities)
n_good = n_total - n_blackhole - n_liabilities
print("Total:", n_total)
- print(
- "Score: {:.2f}/{}".format(
- score(n_blackhole, n_liabilities, n_good, n_total), MAX_SCORE
- )
- )
+ this_score = score(n_blackhole, n_liabilities, n_good, n_total)
+ print(f"Score: {this_score:.2f}/{MAX_SCORE}".format())
- def print_stale(self, full):
+ def print_stale(self, full: bool) -> None:
"Print stale files"
n_stale = len(self.stale)
print(f"Stale files: {n_stale}")
@@ -197,8 +191,23 @@ class Repo:
print(f" {path} ({days} days)")
+def guard_git(repo: Repo) -> None:
+ "Guard against non-git repos."
+ is_git = subprocess.run(
+ ["git", "rev-parse"],
+ stderr=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ check=False,
+ ).returncode
+ if is_git != 0:
+ sys.exit(f"error: not a git repository: {repo}")
+
+
if __name__ == "__main__":
ARGS = get_args()
+ if ARGS.test:
+ print("ok")
+ sys.exit()
logging.basicConfig(stream=sys.stderr, level=ARGS.verbosity.upper())
logging.debug("starting")
diff --git a/Biz/Ide/mktags b/Biz/Ide/mktags
index ebad39a..b984fb1 100755
--- a/Biz/Ide/mktags
+++ b/Biz/Ide/mktags
@@ -2,7 +2,7 @@
#
# script to generate tags automatically if there are none.
#
- set -euxo pipefail
+ set -euo pipefail
files=$@
vimtags=${BIZ_ROOT:?}/tags
emacstags=${BIZ_ROOT:?}/TAGS
diff --git a/Biz/Ide/repl b/Biz/Ide/repl
index e62c7b2..5a7b615 100755
--- a/Biz/Ide/repl
+++ b/Biz/Ide/repl
@@ -63,6 +63,7 @@ fi
command=bash
;;
Py)
+ langdeps="$langdeps pylint mypy"
flags+=(--packages "$BILD.private.$packageSet (p: with p; [$langdeps])")
command=${CMD:-"python -i $targets"}
;;
diff --git a/Biz/Lint.hs b/Biz/Lint.hs
index f9b16d0..be73229 100644
--- a/Biz/Lint.hs
+++ b/Biz/Lint.hs
@@ -123,6 +123,14 @@ hlint =
fixArgs = Nothing
}
+black :: Linter
+black =
+ Linter
+ { exe = "black",
+ checkArgs = ["--check"],
+ fixArgs = Just []
+ }
+
deadnix :: Linter
deadnix =
Linter
@@ -164,7 +172,9 @@ runOne mode root cwd path_ = results +> traverse_ printResult >> results
[ lint mode ormolu path_,
lint mode hlint path_
]
- Just (Namespace _ Py) -> [] -- python linters are run in Builder.nix checkPhase
+ Just (Namespace _ Py) ->
+ [ lint mode black path_
+ ]
Just (Namespace _ Sh) -> [lint mode shellcheck path_]
Just (Namespace _ Nix) -> [lint mode deadnix path_]
Just (Namespace _ Scm) -> [pure <| NoOp path_]
diff --git a/Biz/Nixpert.nix b/Biz/Nixpert.nix
index d6d6d4f..faf27b2 100644
--- a/Biz/Nixpert.nix
+++ b/Biz/Nixpert.nix
@@ -1,4 +1,4 @@
-{ config, pkgs, ... }:
+{ pkgs, ... }:
let
salespage = pkgs.runCommand "salespage" {} ''
diff --git a/Biz/Que/Client.py b/Biz/Que/Client.py
index 58877bf..90e560f 100755
--- a/Biz/Que/Client.py
+++ b/Biz/Que/Client.py
@@ -1,4 +1,5 @@
#!/usr/bin/env python3
+# : out que
"""
simple client for que.run
"""
@@ -15,6 +16,7 @@ import textwrap
import time
import urllib.parse
import urllib.request as request
+import typing
MAX_TIMEOUT = 9999999
RETRIES = 10
@@ -22,7 +24,7 @@ DELAY = 3
BACKOFF = 1
-def auth(args):
+def auth(args: argparse.Namespace) -> typing.Union[str, None]:
"Returns the auth key for the given ns from ~/.config/que.conf"
logging.debug("auth")
namespace = args.target.split("/")[0]
@@ -36,7 +38,7 @@ def auth(args):
return cfg[namespace]["key"]
-def autodecode(bytestring):
+def autodecode(bytestring: bytes) -> typing.Any:
"""Attempt to decode bytes into common codecs, preferably utf-8. If no
decoding is available, just return the raw bytes.
@@ -54,12 +56,18 @@ def autodecode(bytestring):
return bytestring
-def retry(exception, tries=RETRIES, delay=DELAY, backoff=BACKOFF):
+@typing.no_type_check
+def retry(
+ exception: str,
+ tries: typing.Any = RETRIES,
+ delay: typing.Any = DELAY,
+ backoff: typing.Any = BACKOFF,
+) -> typing.Any:
"Decorator for retrying an action."
- def decorator(func):
+ def decorator(func: typing.Any) -> typing.Any:
@functools.wraps(func)
- def func_retry(*args, **kwargs):
+ def func_retry(*args: typing.Any, **kwargs: typing.Any) -> typing.Any:
mtries, mdelay = tries, delay
while mtries > 1:
try:
@@ -77,10 +85,11 @@ def retry(exception, tries=RETRIES, delay=DELAY, backoff=BACKOFF):
return decorator
+@typing.no_type_check
@retry(urllib.error.URLError)
@retry(http.client.IncompleteRead)
@retry(http.client.RemoteDisconnected)
-def send(args):
+def send(args: argparse.Namespace) -> None:
"Send a message to the que."
logging.debug("send")
key = auth(args)
@@ -93,12 +102,14 @@ def send(args):
if args.serve:
logging.debug("serve")
while not time.sleep(1):
+ # pylint: disable=consider-using-with
request.urlopen(req, data=data, timeout=MAX_TIMEOUT)
else:
+ # pylint: disable=consider-using-with
request.urlopen(req, data=data, timeout=MAX_TIMEOUT)
-def then(args, msg):
+def then(args: argparse.Namespace, msg: str) -> None:
"Perform an action when passed `--then`."
if args.then:
logging.debug("then")
@@ -109,10 +120,11 @@ def then(args, msg):
)
+@typing.no_type_check
@retry(urllib.error.URLError)
@retry(http.client.IncompleteRead)
@retry(http.client.RemoteDisconnected)
-def recv(args):
+def recv(args: argparse.Namespace) -> None:
"Receive a message from the que."
logging.debug("recv on: %s", args.target)
if args.poll:
@@ -127,7 +139,7 @@ def recv(args):
if args.poll:
logging.debug("polling")
while not time.sleep(1):
- reply =_req.readline()
+ reply = _req.readline()
if reply:
msg = autodecode(reply)
logging.debug("read")
@@ -141,7 +153,7 @@ def recv(args):
then(args, msg)
-def get_args():
+def get_args() -> argparse.Namespace:
"Command line parser"
cli = argparse.ArgumentParser(
description=__doc__,
@@ -150,6 +162,7 @@ def get_args():
between attempts."""
),
)
+ cli.add_argument("test", action="store_true", help="run tests")
cli.add_argument("--debug", action="store_true", help="log to stderr")
cli.add_argument(
"--host", default="http://que.run", help="where que-server is running"
@@ -192,6 +205,9 @@ def get_args():
if __name__ == "__main__":
ARGV = get_args()
+ if ARGV.test:
+ print("ok")
+ sys.exit()
if ARGV.debug:
logging.basicConfig(
format="%(asctime)s: %(levelname)s: %(message)s",