mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-07-04 12:43:12 +02:00
refactor(linux_configuration): move remaining dirs + scripts/ to meta/
- Move fresh-install/ → scripts/single_use/fresh-install/ - Move hosts/ → scripts/periodic_background/hosts/ - Move i3-configuration/ → scripts/periodic_background/i3-configuration/ - Delete linux_configuration/LaTeX/, nix-poc/, report/ (dead dirs) - Move repo-root scripts/ → meta/scripts/ - Update root .pre-commit-config.yaml: scripts/ → meta/scripts/ (9 entries) - Update run.sh ARTIFACT_INIT_SCRIPT to meta/scripts/ - Update fresh-install/main.sh: hosts/install.sh + i3-configuration/install.sh paths - Update check_python_location.sh: add meta/scripts/ to exception list - Fix midnight flakiness in test_recent_workout_returns_true: use timezone-aware local noon instead of now-1h to avoid SQL date() boundary issues
This commit is contained in:
parent
42a66a1419
commit
db6276b3ff
@ -1 +0,0 @@
|
||||
meta/.pre-commit-config.yaml
|
||||
416
.pre-commit-config.yaml
Normal file
416
.pre-commit-config.yaml
Normal file
@ -0,0 +1,416 @@
|
||||
# ==============================================================================
|
||||
# Pre-commit Configuration - Multi-language Linting & Formatting
|
||||
# ==============================================================================
|
||||
# Install: pre-commit install && pre-commit install --hook-type pre-push
|
||||
# Fast lint: pre-commit run --all-files (linters only, ~10 s)
|
||||
# Full suite: pre-commit run --all-files --hook-stage pre-push (+ tests)
|
||||
# Update hooks: pre-commit autoupdate
|
||||
# ==============================================================================
|
||||
|
||||
# Global settings
|
||||
default_language_version:
|
||||
python: python3
|
||||
|
||||
# By default every hook runs ONLY at commit-time. Pre-push runs only the
|
||||
# hooks that explicitly opt in via `stages: [pre-push]` (currently
|
||||
# pytest-coverage + prettier). This keeps `git push` cheap; commit-time
|
||||
# already enforces the full lint suite.
|
||||
default_stages: [pre-commit]
|
||||
|
||||
# Fail fast on first error (set to false to see all errors)
|
||||
fail_fast: false
|
||||
|
||||
# Configuration
|
||||
ci:
|
||||
autofix_commit_msg: "style: auto-fix by pre-commit hooks"
|
||||
autoupdate_commit_msg: "chore: update pre-commit hooks"
|
||||
|
||||
repos:
|
||||
# ===========================================================================
|
||||
# GENERAL HOOKS - File formatting and validation
|
||||
# ===========================================================================
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.6.0
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
args: [--markdown-linebreak-ext=md]
|
||||
- id: end-of-file-fixer
|
||||
- id: check-yaml
|
||||
args: [--unsafe]
|
||||
- id: check-json
|
||||
# Exclude JSONC files (VS Code configs, TypeScript configs)
|
||||
exclude: ^(\.vscode/|.*/\.vscode/|.*tsconfig.*\.json)
|
||||
- id: check-toml
|
||||
- id: check-xml
|
||||
- id: check-added-large-files
|
||||
args: [--maxkb=2000]
|
||||
- id: check-merge-conflict
|
||||
- id: check-case-conflict
|
||||
- id: check-symlinks
|
||||
- id: check-executables-have-shebangs
|
||||
- id: check-shebang-scripts-are-executable
|
||||
- id: detect-private-key
|
||||
- id: debug-statements
|
||||
- id: name-tests-test
|
||||
args: [--pytest-test-first]
|
||||
- id: check-ast
|
||||
- id: check-builtin-literals
|
||||
- id: check-docstring-first
|
||||
- id: fix-byte-order-marker
|
||||
- id: mixed-line-ending
|
||||
args: [--fix=lf]
|
||||
- id: requirements-txt-fixer
|
||||
|
||||
# ===========================================================================
|
||||
# BINARY BLOCKER - Prevent binary/image files from being committed
|
||||
# ===========================================================================
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: no-binaries
|
||||
name: Block binary/image files
|
||||
entry: meta/scripts/check_no_binaries.sh
|
||||
language: script
|
||||
always_run: false
|
||||
- id: ai-evidence-contract
|
||||
name: Require AI evidence artifacts for code changes
|
||||
entry: meta/scripts/check_ai_evidence.sh
|
||||
language: script
|
||||
pass_filenames: false
|
||||
always_run: true
|
||||
- id: ai-multifile-contract
|
||||
name: Require workflow contract for multi-file code changes
|
||||
entry: meta/scripts/check_agent_contract.sh
|
||||
language: script
|
||||
pass_filenames: false
|
||||
always_run: true
|
||||
- id: append-only-sessions
|
||||
name: Enforce append-only session logs
|
||||
entry: meta/scripts/check_append_only_sessions.sh
|
||||
language: script
|
||||
pass_filenames: false
|
||||
always_run: true
|
||||
|
||||
# ===========================================================================
|
||||
# POLLING SCRIPT LINTER - Detect fork-storm anti-patterns in shell scripts
|
||||
# ===========================================================================
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: no-polling-antipatterns
|
||||
name: Block polling script anti-patterns
|
||||
entry: meta/scripts/check_polling_antipatterns.sh
|
||||
language: script
|
||||
types: [shell]
|
||||
require_serial: true
|
||||
exclude: ^(\.git/|phone_focus_mode/lib/tests/|tests/)
|
||||
|
||||
# ===========================================================================
|
||||
# NOQA BLOCKER - Zero tolerance for noqa/type:ignore suppression comments
|
||||
# ===========================================================================
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: no-noqa
|
||||
name: Block noqa comments
|
||||
entry: '(?i)#\s*(noqa|type:\s*ignore)'
|
||||
language: pygrep
|
||||
types: [python]
|
||||
- id: no-ruff-noqa
|
||||
name: Block ruff noqa file-level comments
|
||||
entry: '(?i)#\s*ruff:\s*noqa'
|
||||
language: pygrep
|
||||
types: [python]
|
||||
|
||||
# ===========================================================================
|
||||
# RUFF - Fast Python linter and formatter (replaces black, isort, flake8, etc.)
|
||||
# ===========================================================================
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.15.2
|
||||
hooks:
|
||||
# Linter - run first to catch issues
|
||||
- id: ruff
|
||||
args:
|
||||
- --fix
|
||||
- --unsafe-fixes
|
||||
- --exit-non-zero-on-fix
|
||||
- --show-fixes
|
||||
types_or: [python, pyi]
|
||||
# Formatter - run after linting
|
||||
- id: ruff-format
|
||||
types_or: [python, pyi]
|
||||
|
||||
# ===========================================================================
|
||||
# MYPY - Static type checking (per-commit on changed files only)
|
||||
# Was on pre-push, but force-push diffs caused full-repo scans + OOM. On
|
||||
# pre-commit it sees only the file(s) currently staged → near-instant.
|
||||
# ===========================================================================
|
||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||
rev: v1.13.0
|
||||
hooks:
|
||||
- id: mypy
|
||||
stages: [pre-commit]
|
||||
args:
|
||||
- --ignore-missing-imports
|
||||
- --no-error-summary
|
||||
- --disable-error-code=no-untyped-def
|
||||
- --disable-error-code=no-untyped-call
|
||||
- --disable-error-code=var-annotated
|
||||
- --disable-error-code=no-any-unimported
|
||||
- --disable-error-code=type-arg
|
||||
- --disable-error-code=no-any-return
|
||||
- --disable-error-code=misc
|
||||
- --disable-error-code=unused-ignore
|
||||
- --disable-error-code=unreachable
|
||||
- --disable-error-code=assignment
|
||||
- --disable-error-code=no-redef
|
||||
- --disable-error-code=attr-defined
|
||||
- --disable-error-code=arg-type
|
||||
- --disable-error-code=union-attr
|
||||
- --disable-error-code=call-overload
|
||||
- --disable-error-code=return-value
|
||||
- --disable-error-code=redundant-cast
|
||||
- --disable-error-code=empty-body
|
||||
- --disable-error-code=list-item
|
||||
exclude: >-
|
||||
(?x)^(
|
||||
Bash/.*|
|
||||
\.venv/.*|
|
||||
linux_configuration/scripts/single_use/misc/testsAndMisc-bash/tools/.*
|
||||
)$
|
||||
additional_dependencies:
|
||||
- types-requests
|
||||
- types-PyYAML
|
||||
- types-python-dateutil
|
||||
|
||||
# ===========================================================================
|
||||
# PYLINT - Comprehensive Python linter (per-commit on changed files only)
|
||||
# Was on pre-push, but force-push diffs caused full-repo scans + OOM.
|
||||
# ===========================================================================
|
||||
- repo: https://github.com/pylint-dev/pylint
|
||||
rev: v3.3.2
|
||||
hooks:
|
||||
- id: pylint
|
||||
stages: [pre-commit]
|
||||
args:
|
||||
- --rcfile=pyproject.toml
|
||||
- --fail-under=8.0
|
||||
- --jobs=0
|
||||
additional_dependencies:
|
||||
- pytest
|
||||
- python-chess
|
||||
- requests
|
||||
- pygame
|
||||
exclude: ^(Bash/|\.venv/)
|
||||
|
||||
# ===========================================================================
|
||||
# BANDIT - Security linter (per-commit on changed files only)
|
||||
# Was on pre-push, but force-push diffs caused full-repo scans + OOM.
|
||||
# ===========================================================================
|
||||
- repo: https://github.com/PyCQA/bandit
|
||||
rev: 1.7.10
|
||||
hooks:
|
||||
- id: bandit
|
||||
stages: [pre-commit]
|
||||
args:
|
||||
- -c
|
||||
- pyproject.toml
|
||||
- --severity-level=high
|
||||
- --confidence-level=medium
|
||||
- --skip=B113
|
||||
additional_dependencies: ["bandit[toml]"]
|
||||
exclude: ^(Bash/|\.venv/|tests/|.*test.*\.py$)
|
||||
|
||||
# ===========================================================================
|
||||
# PYTEST + COVERAGE - Run tests and enforce 100% code coverage
|
||||
# Only tests for subpackages with changed files are run (see script).
|
||||
# Uses pytest-xdist (-n auto) to parallelize across all CPUs.
|
||||
# ===========================================================================
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: pytest-coverage
|
||||
name: pytest with coverage enforcement
|
||||
entry: python meta/scripts/pytest_changed_packages.py
|
||||
language: system
|
||||
types: [python]
|
||||
pass_filenames: true
|
||||
stages: [pre-commit]
|
||||
|
||||
# ===========================================================================
|
||||
# VULTURE - Dead code detection (disabled - doesn't work well with pre-commit)
|
||||
# ===========================================================================
|
||||
# - repo: https://github.com/jendrikseipp/vulture
|
||||
# rev: v2.13
|
||||
# hooks:
|
||||
# - id: vulture
|
||||
# args:
|
||||
# - --min-confidence=80
|
||||
# - --exclude=.venv,Bash,__pycache__
|
||||
# exclude: ^(Bash/|\.venv/)
|
||||
|
||||
# ===========================================================================
|
||||
# PYUPGRADE - Upgrade Python syntax (disabled - incompatible with Python 3.14)
|
||||
# ===========================================================================
|
||||
# - repo: https://github.com/asottile/pyupgrade
|
||||
# rev: v3.19.0
|
||||
# hooks:
|
||||
# - id: pyupgrade
|
||||
# args:
|
||||
# - --py310-plus
|
||||
|
||||
# ===========================================================================
|
||||
# CODESPELL - Spell checking in code (expanded ignore list for non-English)
|
||||
# ===========================================================================
|
||||
- repo: https://github.com/codespell-project/codespell
|
||||
rev: v2.3.0
|
||||
hooks:
|
||||
- id: codespell
|
||||
args:
|
||||
- --skip=*.json,*.lock,*.min.js,*.min.css,.git,__pycache__,.venv,*.txt
|
||||
- --ignore-words-list=als,ans,ect,nd,som,sur,te,nam,numer,lew,sie,wil,postion,clen,ther,folow,derrive,ony,tje,noe,theses,crate,doubleclick,wile,tabel,pary,blok,bloc,proces,serwer,parametr,adres,hart,dout,metod,tekst,synonim,grup,mosty,lokal,skalar,milion,nowe,tre,hel,alph
|
||||
exclude: ^(Bash/ffmpeg-build/|LaTeX/|.*\.geojson$)
|
||||
|
||||
# ===========================================================================
|
||||
# DOCFORMATTER - Format docstrings (disabled - causes recursion errors)
|
||||
# ===========================================================================
|
||||
# - repo: local
|
||||
# hooks:
|
||||
# - id: docformatter
|
||||
# name: docformatter
|
||||
# entry: docformatter
|
||||
# language: system
|
||||
# types: [python]
|
||||
# args:
|
||||
# - --in-place
|
||||
# - --wrap-summaries=88
|
||||
# - --wrap-descriptions=88
|
||||
|
||||
# ===========================================================================
|
||||
# INTERROGATE - Docstring coverage (disabled - causes recursion on large files)
|
||||
# ===========================================================================
|
||||
# - repo: https://github.com/econchick/interrogate
|
||||
# rev: 1.7.0
|
||||
# hooks:
|
||||
# - id: interrogate
|
||||
# args:
|
||||
# - --fail-under=0
|
||||
# - --verbose
|
||||
# - --ignore-init-method
|
||||
# - --ignore-init-module
|
||||
# - --ignore-magic
|
||||
# - --ignore-private
|
||||
# - --ignore-semiprivate
|
||||
# - --exclude=Bash,.venv,__pycache__
|
||||
# pass_filenames: false
|
||||
|
||||
# ===========================================================================
|
||||
# AUTOFLAKE - Remove unused imports/variables
|
||||
# Disabled: fully redundant with ruff (F401, F841, F811) + --fix
|
||||
# ===========================================================================
|
||||
# - repo: https://github.com/PyCQA/autoflake
|
||||
# rev: v2.3.1
|
||||
# hooks:
|
||||
# - id: autoflake
|
||||
# args:
|
||||
# - --in-place
|
||||
# - --remove-all-unused-imports
|
||||
# - --remove-unused-variables
|
||||
# - --remove-duplicate-keys
|
||||
# - --expand-star-imports
|
||||
|
||||
# ===========================================================================
|
||||
# SAFETY - Check for security vulnerabilities in dependencies
|
||||
# ===========================================================================
|
||||
# Note: Safety requires API key for full functionality, disabled by default
|
||||
# - repo: https://github.com/Lucas-C/pre-commit-hooks-safety
|
||||
# rev: v1.3.2
|
||||
# hooks:
|
||||
# - id: python-safety-dependencies-check
|
||||
# files: requirements.*\.txt$
|
||||
|
||||
# ===========================================================================
|
||||
# PYRIGHT - Microsoft's type checker (very strict, optional)
|
||||
# ===========================================================================
|
||||
# Uncomment to enable - can be slow and very strict
|
||||
# - repo: https://github.com/RobertCraiworthy/pyright-action
|
||||
# rev: v1.1.350
|
||||
# hooks:
|
||||
# - id: pyright
|
||||
|
||||
# ===========================================================================
|
||||
# CHECK JSON/YAML/TOML formatting (runs on push only — slow Node.js startup)
|
||||
# ===========================================================================
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: prettier
|
||||
name: prettier (capped scope)
|
||||
# Wrapper runs prettier inside its own systemd-run scope so its
|
||||
# memory budget is independent of the outer pre-push cgroup that
|
||||
# has already accumulated page cache from pytest/mypy/pylint.
|
||||
entry: meta/scripts/run_prettier_capped.sh
|
||||
language: system
|
||||
types_or: [yaml, json, markdown]
|
||||
exclude: >-
|
||||
(?x)^(
|
||||
Bash/.*|
|
||||
\.venv/.*|
|
||||
third_party/.*|
|
||||
\.github/skills/.*|
|
||||
docs/superpowers/(plans|specs)/.*|
|
||||
linux_configuration/report/.*|
|
||||
.*\.lock
|
||||
)$
|
||||
stages: [pre-push]
|
||||
|
||||
# ===========================================================================
|
||||
# SHELLCHECK - Shell script linting
|
||||
# Wrapper batches files to avoid OOM on large repos.
|
||||
# ===========================================================================
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: shellcheck
|
||||
name: shellcheck
|
||||
entry: bash -c 'printf "%s\0" "$@" | xargs -0 -n 40 shellcheck --severity=warning' --
|
||||
language: system
|
||||
types: [shell]
|
||||
|
||||
# ===========================================================================
|
||||
# CHECK PYTHON LOCATION - All Python files must be under python_pkg/
|
||||
# ===========================================================================
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: check-python-location
|
||||
name: check Python files are under python_pkg/
|
||||
entry: meta/scripts/check_python_location.sh
|
||||
language: script
|
||||
types: [python]
|
||||
|
||||
# ===========================================================================
|
||||
# REMOVE EMPTY DIRECTORIES - Clean up empty folders in the repo
|
||||
# ===========================================================================
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: remove-empty-dirs
|
||||
name: remove empty directories
|
||||
entry: find . -type d -empty -not -path './.git/*' -delete -print
|
||||
language: system
|
||||
pass_filenames: false
|
||||
always_run: true
|
||||
|
||||
# ===========================================================================
|
||||
# SECRET PATTERNS - Block commits containing sensitive data
|
||||
# ===========================================================================
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: check-no-secrets
|
||||
name: check for leaked secrets
|
||||
entry: meta/scripts/check_no_secrets.sh
|
||||
language: script
|
||||
exclude: ^(\.secret-patterns|\.pre-commit-config\.yaml|.*\.geojson)$
|
||||
|
||||
# ===========================================================================
|
||||
# COMMITIZEN - Conventional commits (optional)
|
||||
# ===========================================================================
|
||||
# - repo: https://github.com/commitizen-tools/commitizen
|
||||
# rev: v3.13.0
|
||||
# hooks:
|
||||
# - id: commitizen
|
||||
# - id: commitizen-branch
|
||||
# stages: [push]
|
||||
19
docs/superpowers/contracts/linux-config-cleanup-2026-05.json
Normal file
19
docs/superpowers/contracts/linux-config-cleanup-2026-05.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"title": "linux_configuration cleanup: move remaining dirs, delete dead dirs, move scripts/ to meta/",
|
||||
"objective": "Complete the linux_configuration reorganization by moving fresh-install, hosts, and i3-configuration into their semantic subdirectories under scripts/, deleting the dead LaTeX/nix-poc/report directories, moving the repo-level scripts/ to meta/scripts/, and updating all references in pre-commit configs and run.sh.",
|
||||
"acceptance_criteria": [
|
||||
"fresh-install/ is under scripts/single_use/",
|
||||
"hosts/ is under scripts/periodic_background/",
|
||||
"i3-configuration/ is under scripts/periodic_background/",
|
||||
"LaTeX/, nix-poc/, report/ are deleted from linux_configuration/",
|
||||
"scripts/ is moved to meta/scripts/",
|
||||
"Root .pre-commit-config.yaml uses meta/scripts/ paths",
|
||||
"run.sh ARTIFACT_INIT_SCRIPT points to meta/scripts/",
|
||||
"All pre-commit hooks pass"
|
||||
],
|
||||
"out_of_scope": [
|
||||
"Changes to script functionality",
|
||||
"Changes to other python_pkg packages"
|
||||
],
|
||||
"verifier": "pre-commit run --all-files"
|
||||
}
|
||||
30
docs/superpowers/evidence/linux-config-cleanup-2026-05.json
Normal file
30
docs/superpowers/evidence/linux-config-cleanup-2026-05.json
Normal file
@ -0,0 +1,30 @@
|
||||
{
|
||||
"intent": "Finish reorganizing linux_configuration/ and move repo-level scripts/ to meta/scripts/.",
|
||||
"scope": [
|
||||
"linux_configuration/fresh-install/ → scripts/single_use/fresh-install/",
|
||||
"linux_configuration/hosts/ → scripts/periodic_background/hosts/",
|
||||
"linux_configuration/i3-configuration/ → scripts/periodic_background/i3-configuration/",
|
||||
"linux_configuration/LaTeX/, nix-poc/, report/ deleted",
|
||||
"scripts/ moved to meta/scripts/",
|
||||
".pre-commit-config.yaml entry paths updated to meta/scripts/",
|
||||
"run.sh ARTIFACT_INIT_SCRIPT updated to meta/scripts/",
|
||||
"fresh-install/main.sh internal references updated",
|
||||
"check_python_location.sh exception list updated for meta/scripts/",
|
||||
"Fix midnight boundary bug in test_recent_workout_returns_true"
|
||||
],
|
||||
"changes": [
|
||||
"git mv for all directory moves; git rm -r for deletions",
|
||||
"sed bulk-replace scripts/ → meta/scripts/ in .pre-commit-config.yaml (9 entries)",
|
||||
"meta/.pre-commit-config.yaml unchanged (scripts/ resolves correctly from meta/)",
|
||||
"Timezone-aware datetime fix in test to avoid midnight flakiness"
|
||||
],
|
||||
"verification": [
|
||||
{
|
||||
"command": "pre-commit run",
|
||||
"result": "pass",
|
||||
"evidence": "All hooks passed including ruff, mypy, pylint, bandit, pytest 100% coverage, shellcheck"
|
||||
}
|
||||
],
|
||||
"risks": ["Symlink .pre-commit-config.yaml replaced by regular file (intentional divergence)"],
|
||||
"rollback": ["git revert HEAD", "Verify pre-commit run passes after revert"]
|
||||
}
|
||||
308
linux_configuration/LaTeX/.gitignore
vendored
308
linux_configuration/LaTeX/.gitignore
vendored
@ -1,308 +0,0 @@
|
||||
## Core latex/pdflatex auxiliary files:
|
||||
*.aux
|
||||
*.lof
|
||||
*.log
|
||||
*.lot
|
||||
*.fls
|
||||
*.out
|
||||
*.toc
|
||||
*.fmt
|
||||
*.fot
|
||||
*.cb
|
||||
*.cb2
|
||||
.*.lb
|
||||
|
||||
## Intermediate documents:
|
||||
*.dvi
|
||||
*.xdv
|
||||
*-converted-to.*
|
||||
# these rules might exclude image files for figures etc.
|
||||
# *.ps
|
||||
# *.eps
|
||||
# *.pdf
|
||||
|
||||
## Generated if empty string is given at "Please type another file name for output:"
|
||||
.pdf
|
||||
|
||||
## Bibliography auxiliary files (bibtex/biblatex/biber):
|
||||
*.bbl
|
||||
*.bbl-SAVE-ERROR
|
||||
*.bcf
|
||||
*.blg
|
||||
*-blx.aux
|
||||
*-blx.bib
|
||||
*.run.xml
|
||||
|
||||
## Build tool auxiliary files:
|
||||
*.fdb_latexmk
|
||||
*.synctex
|
||||
*.synctex(busy)
|
||||
*.synctex.gz
|
||||
*.synctex.gz(busy)
|
||||
*.pdfsync
|
||||
*.rubbercache
|
||||
rubber.cache
|
||||
|
||||
## Build tool directories for auxiliary files
|
||||
# latexrun
|
||||
latex.out/
|
||||
|
||||
## Auxiliary and intermediate files from other packages:
|
||||
# algorithms
|
||||
*.alg
|
||||
*.loa
|
||||
|
||||
# achemso
|
||||
acs-*.bib
|
||||
|
||||
# amsthm
|
||||
*.thm
|
||||
|
||||
# beamer
|
||||
*.nav
|
||||
*.pre
|
||||
*.snm
|
||||
*.vrb
|
||||
|
||||
# changes
|
||||
*.soc
|
||||
|
||||
# comment
|
||||
*.cut
|
||||
|
||||
# cprotect
|
||||
*.cpt
|
||||
|
||||
# elsarticle (documentclass of Elsevier journals)
|
||||
*.spl
|
||||
|
||||
# endnotes
|
||||
*.ent
|
||||
|
||||
# fixme
|
||||
*.lox
|
||||
|
||||
# feynmf/feynmp
|
||||
*.mf
|
||||
*.mp
|
||||
*.t[1-9]
|
||||
*.t[1-9][0-9]
|
||||
*.tfm
|
||||
|
||||
#(r)(e)ledmac/(r)(e)ledpar
|
||||
*.end
|
||||
*.?end
|
||||
*.[1-9]
|
||||
*.[1-9][0-9]
|
||||
*.[1-9][0-9][0-9]
|
||||
*.[1-9]R
|
||||
*.[1-9][0-9]R
|
||||
*.[1-9][0-9][0-9]R
|
||||
*.eledsec[1-9]
|
||||
*.eledsec[1-9]R
|
||||
*.eledsec[1-9][0-9]
|
||||
*.eledsec[1-9][0-9]R
|
||||
*.eledsec[1-9][0-9][0-9]
|
||||
*.eledsec[1-9][0-9][0-9]R
|
||||
|
||||
# glossaries
|
||||
*.acn
|
||||
*.acr
|
||||
*.glg
|
||||
*.glo
|
||||
*.gls
|
||||
*.glsdefs
|
||||
*.lzo
|
||||
*.lzs
|
||||
*.slg
|
||||
*.slo
|
||||
*.sls
|
||||
|
||||
# uncomment this for glossaries-extra (will ignore makeindex's style files!)
|
||||
# *.ist
|
||||
|
||||
# gnuplot
|
||||
*.gnuplot
|
||||
*.table
|
||||
|
||||
# gnuplottex
|
||||
*-gnuplottex-*
|
||||
|
||||
# gregoriotex
|
||||
*.gaux
|
||||
*.glog
|
||||
*.gtex
|
||||
|
||||
# htlatex
|
||||
*.4ct
|
||||
*.4tc
|
||||
*.idv
|
||||
*.lg
|
||||
*.trc
|
||||
*.xref
|
||||
|
||||
# hypdoc
|
||||
*.hd
|
||||
|
||||
# hyperref
|
||||
*.brf
|
||||
|
||||
# knitr
|
||||
*-concordance.tex
|
||||
# TODO Uncomment the next line if you use knitr and want to ignore its generated tikz files
|
||||
# *.tikz
|
||||
*-tikzDictionary
|
||||
|
||||
# listings
|
||||
*.lol
|
||||
|
||||
# luatexja-ruby
|
||||
*.ltjruby
|
||||
|
||||
# makeidx
|
||||
*.idx
|
||||
*.ilg
|
||||
*.ind
|
||||
|
||||
# minitoc
|
||||
*.maf
|
||||
*.mlf
|
||||
*.mlt
|
||||
*.mtc[0-9]*
|
||||
*.slf[0-9]*
|
||||
*.slt[0-9]*
|
||||
*.stc[0-9]*
|
||||
|
||||
# minted
|
||||
_minted*
|
||||
*.pyg
|
||||
|
||||
# morewrites
|
||||
*.mw
|
||||
|
||||
# newpax
|
||||
*.newpax
|
||||
|
||||
# nomencl
|
||||
*.nlg
|
||||
*.nlo
|
||||
*.nls
|
||||
|
||||
# pax
|
||||
*.pax
|
||||
|
||||
# pdfpcnotes
|
||||
*.pdfpc
|
||||
|
||||
# sagetex
|
||||
*.sagetex.sage
|
||||
*.sagetex.py
|
||||
*.sagetex.scmd
|
||||
|
||||
# scrwfile
|
||||
*.wrt
|
||||
|
||||
# svg
|
||||
svg-inkscape/
|
||||
|
||||
# sympy
|
||||
*.sout
|
||||
*.sympy
|
||||
sympy-plots-for-*.tex/
|
||||
|
||||
# pdfcomment
|
||||
*.upa
|
||||
*.upb
|
||||
|
||||
# pythontex
|
||||
*.pytxcode
|
||||
pythontex-files-*/
|
||||
|
||||
# tcolorbox
|
||||
*.listing
|
||||
|
||||
# thmtools
|
||||
*.loe
|
||||
|
||||
# TikZ & PGF
|
||||
*.dpth
|
||||
*.md5
|
||||
*.auxlock
|
||||
|
||||
# titletoc
|
||||
*.ptc
|
||||
|
||||
# todonotes
|
||||
*.tdo
|
||||
|
||||
# vhistory
|
||||
*.hst
|
||||
*.ver
|
||||
|
||||
# easy-todo
|
||||
*.lod
|
||||
|
||||
# xcolor
|
||||
*.xcp
|
||||
|
||||
# xmpincl
|
||||
*.xmpi
|
||||
|
||||
# xindy
|
||||
*.xdy
|
||||
|
||||
# xypic precompiled matrices and outlines
|
||||
*.xyc
|
||||
*.xyd
|
||||
|
||||
# endfloat
|
||||
*.ttt
|
||||
*.fff
|
||||
|
||||
# Latexian
|
||||
TSWLatexianTemp*
|
||||
|
||||
## Editors:
|
||||
# WinEdt
|
||||
*.bak
|
||||
*.sav
|
||||
|
||||
# Texpad
|
||||
.texpadtmp
|
||||
|
||||
# LyX
|
||||
*.lyx~
|
||||
|
||||
# Kile
|
||||
*.backup
|
||||
|
||||
# gummi
|
||||
.*.swp
|
||||
|
||||
# KBibTeX
|
||||
*~[0-9]*
|
||||
|
||||
# TeXnicCenter
|
||||
*.tps
|
||||
|
||||
# auto folder when using emacs and auctex
|
||||
./auto/*
|
||||
*.el
|
||||
|
||||
# expex forward references with \gathertags
|
||||
*-tags.tex
|
||||
|
||||
# standalone packages
|
||||
*.sta
|
||||
|
||||
# Makeindex log files
|
||||
*.lpz
|
||||
|
||||
# xwatermark package
|
||||
*.xwm
|
||||
|
||||
# REVTeX puts footnotes in the bibliography by default, unless the nofootinbib
|
||||
# option is specified. Footnotes are the stored in a file with suffix Notes.bib.
|
||||
# Uncomment the next line to have this generated file ignored.
|
||||
#*Notes.bib
|
||||
*.pdf
|
||||
@ -1,44 +0,0 @@
|
||||
\documentclass{article}
|
||||
\usepackage{background}
|
||||
\usepackage{lipsum}
|
||||
\usepackage[margin=6pt]{geometry} % Remove all margins
|
||||
\pagestyle{empty} % Disable page numbering
|
||||
|
||||
\newlength\mylen
|
||||
\setlength\mylen{\dimexpr\paperwidth/40\relax}
|
||||
|
||||
\SetBgScale{1}
|
||||
\SetBgAngle{0}
|
||||
\SetBgColor{blue!30}
|
||||
\SetBgContents{\tikz{\draw[step=\mylen] (-.5\paperwidth,-.5\paperheight) grid (.5\paperwidth,.5\paperheight);}}
|
||||
|
||||
\begin{document}
|
||||
Co oznaczają następujące terminy: lokalizacja, lateralizacja, odsłuch monauralny, binauralny, diotyczny i dychotyczny? \\
|
||||
Lokalizacja to zdolność określenia położenia źródła dźwięku w przestrzeni. Lateralizacja odnosi się do percepcji dźwięku jako dochodzącego bardziej z jednej strony, co pozwala na rozróżnienie kierunku źródła dźwięku. Odsłuch monauralny polega na słuchaniu dźwięku jednym uchem, natomiast binauralny to słuchanie obydwoma uszami z wykorzystaniem różnic między nimi do lepszej percepcji przestrzennej. Odsłuch diotyczny to sytuacja, w której identyczny sygnał dźwiękowy jest prezentowany jednocześnie do obu uszu. Dychotyczny odsłuch oznacza, że różne sygnały dźwiękowe są jednocześnie prezentowane do każdego z uszu, co pozwala badać, jak mózg przetwarza konkurencyjne informacje słuchowe. \\
|
||||
Na czym polega „eksternalizacja” obrazu słuchowego? \\
|
||||
Eksternalizacja obrazu słuchowego polega na takim przetwarzaniu i prezentacji dźwięku, aby słuchacz odbierał go jako pochodzący z zewnętrznej przestrzeni, a nie z wnętrza swojej głowy. W praktyce oznacza to, że dźwięki są postrzegane jako znajdujące się wokół słuchacza, co zwiększa realizm i immersję doświadczenia słuchowego. Proces ten wykorzystuje wskazówki przestrzenne, takie jak różnice międzyuszowe czasu (ITD), różnice poziomu (ILD) oraz funkcje przenoszenia związane z głową (HRTF). Dzięki temu możliwe jest odtworzenie wrażeń przestrzennych podczas słuchania przez słuchawki lub systemy dźwięku przestrzennego. Eksternalizacja jest kluczowa w aplikacjach takich jak dźwięk binauralny, wirtualna rzeczywistość czy gry komputerowe, gdzie ważne jest precyzyjne umiejscowienie źródeł dźwięku w przestrzeni. \\
|
||||
Co to jest międzyuszna różnica czasu i międzyuszna różnica natężenia? \\
|
||||
Międzyuszna różnica czasu (ITD) i międzyuszna różnica natężenia (ILD) to dwa kluczowe mechanizmy, dzięki którym układ słuchowy lokalizuje źródła dźwięku w przestrzeni. **ITD** odnosi się do niewielkich różnic w czasie, w jakim dźwięk dociera do każdego ucha; gdy dźwięk pochodzi z jednej strony, dociera do bliższego ucha nieco wcześniej niż do dalszego, a mózg wykorzystuje te różnice do określenia kierunku dźwięku. **ILD** dotyczy różnic w natężeniu dźwięku docierającego do każdego ucha; głowa działa jako bariera akustyczna, powodując, że dźwięk jest głośniejszy w uchu bliższym źródła, zwłaszcza dla dźwięków o wysokiej częstotliwości, a mózg wykorzystuje te różnice natężenia do lokalizacji dźwięku. Wspólnie, ITD i ILD umożliwiają precyzyjną lokalizację dźwięków w płaszczyźnie poziomej, co jest kluczowe dla orientacji i interpretacji środowiska akustycznego. \\
|
||||
Jakiego rzędu międzyuszna różnica czasu powoduje przesunięcie obrazu słuchowego całkowicie w jedną stronę (tak, że dźwięk odbierany jest z boku)? \\
|
||||
Aby dźwięk był odbierany jako dochodzący całkowicie z boku, międzyuszna różnica czasu (ITD) musi osiągnąć swoją maksymalną wartość. Dla ludzi maksymalna ITD wynosi około **0,6 milisekundy** (600 mikrosekund). Taka różnica czasu występuje, gdy źródło dźwięku znajduje się bezpośrednio po jednej stronie głowy, pod kątem 90 stopni względem linii środkowej twarzy. Jest to czas potrzebny falom dźwiękowym na przebycie odległości między jednym uchem a drugim. \\
|
||||
**Odpowiedź:** Około 0,6 milisekundy międzyusznej różnicy czasu powoduje przesunięcie obrazu słuchowego całkowicie w jedną stronę. \\
|
||||
Jakiego rzędu międzyuszna różnica natężenia powoduje przesunięcie obrazu słuchowego całkowicie na jedną stronę (tak, że dźwięk odbierany jest z boku)? \\
|
||||
A difference in intensity of approximately **10 decibels (dB)** between the ears can cause the auditory image to shift completely to one side, making the sound appear to come from that direction. This occurs because our auditory system uses interaural intensity differences (IIDs) to localize sounds, especially at higher frequencies where these differences are more noticeable. Even smaller intensity differences can influence perceived direction, but around 10 dB is typically needed to fully lateralize the sound. This means that a sound louder by about 10 dB in one ear compared to the other will be perceived as coming entirely from that side. \\
|
||||
**Answer:** Około 10 dB różnicy natężenia między uszami całkowicie przesuwa obraz słuchowy na jedną stronę. \\
|
||||
W jakich zakresach częstotliwości o lokalizacji decyduje międzyuszna różnica czasu lub międzyuszna różnica natężenia. Co powoduje taki przebieg tych zależności? \\
|
||||
Międzyuszna różnica czasu (ITD) decyduje o lokalizacji dźwięku w **niskich częstotliwościach**, od około **20 Hz do 1500 Hz**. Międzyuszna różnica natężenia (IID lub ILD) jest kluczowa w **wysokich częstotliwościach**, powyżej około **1500 Hz**, szczególnie powyżej **3000 Hz**. Przy niskich częstotliwościach długie fale dźwiękowe omijają głowę bez znaczącego tłumienia, więc różnice natężenia są niewielkie, ale różnice czasu są zauważalne i wykorzystywane przez mózg do lokalizacji. Przy wysokich częstotliwościach krótkie fale są tłumione przez głowę, tworząc cień akustyczny, co powoduje znaczące różnice natężenia między uszami, podczas gdy różnice czasu są trudniejsze do zinterpretowania ze względu na szybką zmianę fazy. Dlatego w niskich częstotliwościach lokalizację determinuje ITD, a w wysokich częstotliwościach IID, co wynika z fizycznych właściwości fal dźwiękowych i interakcji z głową. \\
|
||||
Co to jest tzw. stożek niepewności? \\
|
||||
Stożek niepewności to termin używany w różnych dziedzinach, takich jak meteorologia i zarządzanie projektami, aby opisać zakres niepewności związany z prognozami lub szacunkami. W meteorologii reprezentuje na mapie przewidywaną trasę centrum huraganu lub cyklonu, gdzie szerokość stożka odzwierciedla rosnącą niepewność w miarę upływu czasu. W zarządzaniu projektami stożek niepewności ilustruje, że na początku projektu szacunki dotyczące kosztów, harmonogramu czy zakresu są mniej dokładne, a niepewność maleje w miarę postępu prac. Koncepcja ta pomaga w planowaniu i zarządzaniu ryzykiem, uwzględniając, że precyzja prognoz zwiększa się wraz z dostępem do większej ilości informacji. Stożek niepewności wizualizuje zatem redukcję niepewności w czasie, co pozwala na lepsze podejmowanie decyzji. \\
|
||||
Ile (ogólnie) wynoszą kątowe progi różnicowe przesunięcia źródła dźwięku w płaszczyźnie poziomej? \\
|
||||
Ogólnie kątowe progi różnicowe przesunięcia źródła dźwięku w płaszczyźnie poziomej wynoszą około **1 stopnia** dla dźwięków dochodzących z przodu (azymut 0 stopni). Jest to tzw. **minimalny słyszalny kąt** (ang. *Minimum Audible Angle*, MAA). Wartość ta może się zmieniać w zależności od częstotliwości dźwięku, natężenia, akustyki pomieszczenia i indywidualnych cech słuchu. Dla dźwięków dochodzących z innych kierunków zdolność do wykrywania różnic kątowych może być mniejsza, a progi różnicowe mogą wzrosnąć do kilku stopni. \\
|
||||
Co to jest zjawisko dominacji (pierwszeństwa)? \\
|
||||
Zjawisko dominacji, znane również jako efekt pierwszeństwa, polega na tym, że pierwszy bodziec lub informacja, którą odbieramy, ma większy wpływ na naszą percepcję lub decyzje niż kolejne bodźce. W akustyce oznacza to, że gdy dwa dźwięki o podobnej treści docierają do nas z niewielkim odstępem czasowym, nasz mózg preferuje pierwszy z nich przy określaniu lokalizacji źródła dźwięku. W psychologii poznawczej efekt pierwszeństwa odnosi się do tendencji do lepszego zapamiętywania lub przywiązywania większej wagi do informacji prezentowanych na początku listy lub sekwencji. To zjawisko wpływa na sposób przetwarzania informacji i może mieć znaczenie w kontekście uczenia się, komunikacji czy marketingu. Ogólnie rzecz biorąc, zjawisko dominacji podkreśla wpływ pierwszych doświadczeń lub informacji na naszą percepcję i reakcje. \\
|
||||
W jakim zakresie opóźnień sygnału występuje zjawisko dominacji? \\
|
||||
Zjawisko dominacji, znane również jako efekt precedencji, występuje w akustyce, gdy dwa identyczne sygnały dźwiękowe docierają do słuchacza z niewielkim opóźnieniem czasowym. Jeśli opóźnienie między nimi wynosi od około 1 ms do około 30 ms, słuchacz lokalizuje dźwięk w kierunku pierwszego sygnału. W tym zakresie drugi sygnał nie jest odbierany jako oddzielny dźwięk czy echo, lecz wpływa na percepcję kierunku dźwięku, wzmacniając wrażenie pochodzenia z pierwszego źródła. Po przekroczeniu tej granicy czasowej drugi sygnał zaczyna być postrzegany jako oddzielny dźwięk lub echo. \\
|
||||
**Odpowiedź:** Zjawisko dominacji występuje przy opóźnieniach sygnału od około 1 ms do około 30 ms. \\
|
||||
Na czym polega odmaskowanie dwuuszne (BMLD)? \\
|
||||
**Odmaskowanie dwuuszne (BMLD - *Binaural Masking Level Difference*) polega na poprawie zdolności wykrywania sygnału dźwiękowego w szumie dzięki różnicom między sygnałami docierającymi do obu uszu.** W sytuacji, gdy sygnał i szum są identyczne w obu uszach, próg wykrywania sygnału jest wyższy. **Wprowadzenie różnic fazowych lub natężeniowych między sygnałami w uszach obniża ten próg, co ułatwia wykrycie sygnału w obecności szumu.** Zjawisko to wynika z centralnego przetwarzania w mózgu, który analizuje różnice między sygnałami z lewego i prawego ucha. **Odmaskowanie dwuuszne jest kluczowe dla lokalizacji dźwięku i poprawy rozumienia mowy w hałaśliwym otoczeniu.** \\
|
||||
Podać typowe wartości odmaskowania dwuusznego. \\
|
||||
Typowe wartości odmaskowania dwuusznego (MLD) to różnice w progu słyszenia sygnału w obecności szumu przy korzystaniu ze słuchu obuusznego. MLD jest największe dla niskich częstotliwości, osiągając około **15 dB** dla 500 Hz. Dla średnich częstotliwości, takich jak 1000 Hz, MLD wynosi około **10 dB**. W przypadku wyższych częstotliwości, powyżej 1500 Hz, MLD maleje do wartości często poniżej **5 dB**. Te wartości pokazują, że słuch obuuszny znacząco poprawia wykrywanie sygnałów w szumie na niskich i średnich częstotliwościach.
|
||||
|
||||
\end{document}
|
||||
@ -1,21 +0,0 @@
|
||||
\documentclass[a4paper]{article}
|
||||
\usepackage{background}
|
||||
\usepackage{lipsum}
|
||||
\pagestyle{empty} % Disable page numbering
|
||||
|
||||
\newlength\mylen
|
||||
\setlength\mylen{\dimexpr\paperwidth/40\relax}
|
||||
|
||||
\SetBgScale{1}
|
||||
\SetBgAngle{0}
|
||||
\SetBgColor{blue!30}
|
||||
\SetBgContents{\tikz{\draw[step=\mylen] (-.5\paperwidth,-.5\paperheight) grid (.5\paperwidth,.5\paperheight);}}
|
||||
|
||||
\begin{document}
|
||||
\newpage
|
||||
|
||||
\ % The empty page
|
||||
|
||||
\newpage
|
||||
|
||||
\end{document}
|
||||
@ -1,28 +0,0 @@
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
imports = [
|
||||
./modules/arch-parity-poc.nix
|
||||
];
|
||||
|
||||
linuxConfigPoc = {
|
||||
enable = true;
|
||||
mainUser = "kuhy";
|
||||
|
||||
# Turn this on when you intentionally want to run the original imperative
|
||||
# shell installers during activation (hosts install + guard setup, etc.).
|
||||
# Keep it off by default for safe evaluation and incremental migration.
|
||||
enableImperativeBootstrap = false;
|
||||
};
|
||||
|
||||
# Minimal baseline the host config still needs while this remains a POC.
|
||||
networking.hostName = "arch-parity-poc";
|
||||
time.timeZone = "Europe/Warsaw";
|
||||
|
||||
# Convenience tools for verification/debugging during migration.
|
||||
environment.systemPackages = with pkgs; [
|
||||
git
|
||||
jq
|
||||
];
|
||||
|
||||
system.stateVersion = "25.05";
|
||||
}
|
||||
@ -1,24 +0,0 @@
|
||||
{
|
||||
description = "NixOS proof-of-concept for linux_configuration parity";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
home-manager = {
|
||||
url = "github:nix-community/home-manager";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
|
||||
outputs = { nixpkgs, home-manager, ... }:
|
||||
let
|
||||
system = "x86_64-linux";
|
||||
in {
|
||||
nixosConfigurations.arch-parity-poc = nixpkgs.lib.nixosSystem {
|
||||
inherit system;
|
||||
modules = [
|
||||
home-manager.nixosModules.home-manager
|
||||
./configuration.nix
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
{ ... }:
|
||||
{
|
||||
imports = [
|
||||
./arch-parity/options.nix
|
||||
./arch-parity/packages.nix
|
||||
./arch-parity/report.nix
|
||||
./arch-parity/desktop.nix
|
||||
./arch-parity/system-maintenance.nix
|
||||
./arch-parity/hosts-guards.nix
|
||||
./arch-parity/bootstrap.nix
|
||||
];
|
||||
}
|
||||
@ -1,17 +0,0 @@
|
||||
{ config, lib, ... }:
|
||||
let
|
||||
cfg = config.linuxConfigPoc;
|
||||
repo = toString cfg.repoPath;
|
||||
in {
|
||||
config = lib.mkIf (cfg.enable && cfg.enableImperativeBootstrap) {
|
||||
system.activationScripts.linuxConfigImperativeBootstrap = {
|
||||
text = ''
|
||||
echo "[linuxConfigPoc] Running imperative bootstrap scripts"
|
||||
bash ${repo}/hosts/install.sh || true
|
||||
bash ${repo}/hosts/guard/setup_hosts_guard.sh || true
|
||||
bash ${repo}/scripts/periodic_background/setup_periodic_system.sh || true
|
||||
'';
|
||||
deps = [ "users" "groups" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
@ -1,20 +0,0 @@
|
||||
{ config, lib, ... }:
|
||||
let
|
||||
cfg = config.linuxConfigPoc;
|
||||
in {
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.xserver.enable = true;
|
||||
services.xserver.windowManager.i3.enable = true;
|
||||
services.xserver.displayManager.startx.enable = true;
|
||||
|
||||
# Mirror i3 + i3blocks config deployment using Home Manager.
|
||||
home-manager.useGlobalPkgs = true;
|
||||
home-manager.useUserPackages = true;
|
||||
home-manager.users.${cfg.mainUser} = {
|
||||
xdg.configFile."i3/config".source = "${cfg.repoPath}/i3-configuration/i3/config";
|
||||
xdg.configFile."i3blocks/config".source = "${cfg.repoPath}/i3-configuration/i3blocks/config";
|
||||
xdg.configFile."i3blocks".recursive = true;
|
||||
xdg.configFile."i3blocks".source = "${cfg.repoPath}/i3-configuration/i3blocks";
|
||||
};
|
||||
};
|
||||
}
|
||||
@ -1,92 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
cfg = config.linuxConfigPoc;
|
||||
repo = toString cfg.repoPath;
|
||||
commonScriptPath = with pkgs; [
|
||||
bash
|
||||
coreutils
|
||||
findutils
|
||||
gawk
|
||||
gnugrep
|
||||
gnused
|
||||
util-linux
|
||||
];
|
||||
|
||||
customHostsEntries = pkgs.runCommand "linux-config-custom-hosts" { } ''
|
||||
sed -n '/^# Custom blocking entries$/,/^EOF$/p' ${cfg.repoPath}/hosts/install.sh \
|
||||
| sed '$d' > "$out"
|
||||
'';
|
||||
in {
|
||||
config = lib.mkIf cfg.enable {
|
||||
networking.extraHosts = builtins.readFile customHostsEntries;
|
||||
|
||||
# Protect hosts lookup ordering against bypasses.
|
||||
system.nssDatabases.hosts = [ "files" "myhostname" "dns" ];
|
||||
|
||||
systemd.services.hosts-guard = {
|
||||
description = "Enforce canonical /etc/hosts contents";
|
||||
after = [ "local-fs.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecStart = "${repo}/hosts/guard/enforce-hosts.sh";
|
||||
Nice = "10";
|
||||
IOSchedulingClass = "idle";
|
||||
};
|
||||
path = commonScriptPath;
|
||||
};
|
||||
|
||||
systemd.paths.hosts-guard = {
|
||||
description = "Watch /etc/hosts and trigger enforcement";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
pathConfig = {
|
||||
PathChanged = [ "/etc/hosts" ];
|
||||
Unit = "hosts-guard.service";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.nsswitch-guard = {
|
||||
description = "Enforce canonical /etc/nsswitch.conf (prevents hosts bypass)";
|
||||
after = [ "local-fs.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecStart = "${repo}/hosts/guard/enforce-nsswitch.sh";
|
||||
Nice = "10";
|
||||
IOSchedulingClass = "idle";
|
||||
};
|
||||
path = commonScriptPath;
|
||||
};
|
||||
|
||||
systemd.paths.nsswitch-guard = {
|
||||
description = "Watch /etc/nsswitch.conf for tampering";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
pathConfig = {
|
||||
PathChanged = [ "/etc/nsswitch.conf" ];
|
||||
Unit = "nsswitch-guard.service";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.resolved-guard = {
|
||||
description = "Enforce canonical /etc/systemd/resolved.conf (prevents hosts bypass)";
|
||||
after = [ "local-fs.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecStart = "${repo}/hosts/guard/enforce-resolved.sh";
|
||||
Nice = "10";
|
||||
IOSchedulingClass = "idle";
|
||||
};
|
||||
path = commonScriptPath;
|
||||
};
|
||||
|
||||
systemd.paths.resolved-guard = {
|
||||
description = "Watch /etc/systemd/resolved.conf for tampering";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
pathConfig = {
|
||||
PathChanged = [ "/etc/systemd/resolved.conf" "/etc/systemd/resolved.conf.d" ];
|
||||
Unit = "resolved-guard.service";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@ -1,117 +0,0 @@
|
||||
{ lib, ... }:
|
||||
{
|
||||
options.linuxConfigPoc = {
|
||||
enable = lib.mkEnableOption "Arch linux_configuration parity proof-of-concept";
|
||||
|
||||
repoPath = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = ../../..;
|
||||
description = "Path to the linux_configuration repository root.";
|
||||
};
|
||||
|
||||
mainUser = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "kuhy";
|
||||
description = "Primary desktop username for user-scoped config (i3/i3blocks).";
|
||||
};
|
||||
|
||||
enableImperativeBootstrap = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Run original shell installers at activation (hosts + guard + periodic setup).";
|
||||
};
|
||||
|
||||
enableResolutionReport = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Generate a package resolution report grouped by migration category.";
|
||||
};
|
||||
|
||||
resolutionReportEtcPath = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "linux-config-poc/package-resolution-report.txt";
|
||||
description = "Path under /etc where the package resolution report is materialized.";
|
||||
};
|
||||
|
||||
enableResolutionReportJson = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Generate a machine-readable JSON package resolution report.";
|
||||
};
|
||||
|
||||
resolutionReportJsonEtcPath = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "linux-config-poc/package-resolution-report.json";
|
||||
description = "Path under /etc where the JSON package resolution report is materialized.";
|
||||
};
|
||||
|
||||
packageMap = lib.mkOption {
|
||||
type = lib.types.attrsOf lib.types.str;
|
||||
default = {
|
||||
# Fonts / desktop
|
||||
"ttf-dejavu" = "dejavu_fonts";
|
||||
"noto-fonts" = "noto-fonts";
|
||||
"ttf-font-awesome" = "font-awesome";
|
||||
"adobe-source-sans-pro-fonts" = "source-sans";
|
||||
"ttf-liberation" = "liberation_ttf";
|
||||
|
||||
# Toolchain / language ecosystems
|
||||
"go-tools" = "gotools";
|
||||
"cargo" = "cargo";
|
||||
"rust" = "rustc";
|
||||
"nodejs" = "nodejs";
|
||||
"npm" = "nodejs";
|
||||
"yarn" = "yarn";
|
||||
"node-gyp" = "nodePackages.node-gyp";
|
||||
"lua52" = "lua5_2";
|
||||
|
||||
# Python package translations
|
||||
"python-nose" = "python3Packages.nose";
|
||||
"python-pyproject-metadata" = "python3Packages.pyproject-metadata";
|
||||
"meson-python" = "python3Packages.meson-python";
|
||||
"python-numpy" = "python3Packages.numpy";
|
||||
"python-markdown" = "python3Packages.markdown";
|
||||
"python-pyparsing" = "python3Packages.pyparsing";
|
||||
"python-pyqt5" = "python3Packages.pyqt5";
|
||||
"python-pefile" = "python3Packages.pefile";
|
||||
"python-booleanoperations" = "python3Packages.booleanoperations";
|
||||
"python-brotli" = "python3Packages.brotli";
|
||||
"python-defcon" = "python3Packages.defcon";
|
||||
"python-fontmath" = "python3Packages.fontmath";
|
||||
"python-fontpens" = "python3Packages.fontpens";
|
||||
"python-fonttools" = "python3Packages.fonttools";
|
||||
"python-fs" = "python3Packages.fs";
|
||||
"python-tqdm" = "python3Packages.tqdm";
|
||||
"python-unicodedata2" = "python3Packages.unicodedata2";
|
||||
"python-zopfli" = "python3Packages.zopfli";
|
||||
"python-pyaml" = "python3Packages.pyyaml";
|
||||
|
||||
# Java / Perl
|
||||
"java-hamcrest" = "hamcrest";
|
||||
"perl-font-ttf" = "perlPackages.FontTTF";
|
||||
"perl-sort-versions" = "perlPackages.SortVersions";
|
||||
|
||||
# Multimedia / desktop mismatches
|
||||
"pavucontrol-qt" = "pavucontrol";
|
||||
"qt5-wayland" = "qt5.qtwayland";
|
||||
"qt6-tools" = "qt6.full";
|
||||
"qt6-shadertools" = "qt6.qtshadertools";
|
||||
"ffmpeg" = "ffmpeg-full";
|
||||
"pyside6" = "python3Packages.pyside6";
|
||||
|
||||
# TeX stack consolidation
|
||||
"texlive-plaingeneric" = "texliveFull";
|
||||
"texlive-latexextra" = "texliveFull";
|
||||
"texlive-bibtexextra" = "texliveFull";
|
||||
"texlive-pictures" = "texliveFull";
|
||||
"texlive-fontsextra" = "texliveFull";
|
||||
"texlive-formatsextra" = "texliveFull";
|
||||
"texlive-pstricks" = "texliveFull";
|
||||
"texlive-games" = "texliveFull";
|
||||
"texlive-humanities" = "texliveFull";
|
||||
"texlive-science" = "texliveFull";
|
||||
};
|
||||
description = "Mapping from Arch package names to nixpkgs attributes.";
|
||||
};
|
||||
};
|
||||
}
|
||||
@ -1,55 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
cfg = config.linuxConfigPoc;
|
||||
|
||||
readList = file:
|
||||
let
|
||||
lines = lib.splitString "\n" (builtins.readFile file);
|
||||
trimmed = map lib.strings.trim lines;
|
||||
in
|
||||
builtins.filter (line: line != "" && !(lib.hasPrefix "#" line)) trimmed;
|
||||
|
||||
pacmanPackageFile = "${toString cfg.repoPath}/fresh-install/pacman_packages.txt";
|
||||
aurPackageFile = "${toString cfg.repoPath}/fresh-install/aur_packages.txt";
|
||||
|
||||
pacmanNamesRaw = readList pacmanPackageFile;
|
||||
aurLinesRaw = readList aurPackageFile;
|
||||
aurNames = map (line: builtins.head (lib.splitString " " line)) aurLinesRaw;
|
||||
|
||||
mappedPacmanNames = map
|
||||
(name: if builtins.hasAttr name cfg.packageMap then builtins.getAttr name cfg.packageMap else name)
|
||||
pacmanNamesRaw;
|
||||
|
||||
resolvePackage = name: lib.attrByPath (lib.splitString "." name) null pkgs;
|
||||
|
||||
resolvedPacmanPkgs = builtins.filter (pkg: pkg != null) (map resolvePackage mappedPacmanNames);
|
||||
missingPacmanPkgs = builtins.filter (name: (resolvePackage name) == null) mappedPacmanNames;
|
||||
in {
|
||||
config = lib.mkIf cfg.enable {
|
||||
warnings = [
|
||||
"linuxConfigPoc: ${toString (builtins.length resolvedPacmanPkgs)} pacman packages resolved to nixpkgs attrs."
|
||||
"linuxConfigPoc: ${toString (builtins.length missingPacmanPkgs)} pacman packages still need mapping/overlays."
|
||||
"linuxConfigPoc: ${toString (builtins.length aurNames)} AUR packages detected and not yet represented as Nix derivations."
|
||||
"linuxConfigPoc: pacman-wrapper policy/challenges remain imperative scripts; full Nix-native equivalent requires dedicated policy module."
|
||||
];
|
||||
|
||||
environment.systemPackages =
|
||||
lib.unique (
|
||||
(with pkgs; [
|
||||
acpi
|
||||
bc
|
||||
dex
|
||||
i3blocks
|
||||
i3lock
|
||||
i3status
|
||||
iw
|
||||
jq
|
||||
networkmanagerapplet
|
||||
pavucontrol
|
||||
terminator
|
||||
xss-lock
|
||||
])
|
||||
++ resolvedPacmanPkgs
|
||||
);
|
||||
};
|
||||
}
|
||||
@ -1,169 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
cfg = config.linuxConfigPoc;
|
||||
|
||||
readList = file:
|
||||
let
|
||||
lines = lib.splitString "\n" (builtins.readFile file);
|
||||
trimmed = map lib.strings.trim lines;
|
||||
in
|
||||
builtins.filter (line: line != "" && !(lib.hasPrefix "#" line)) trimmed;
|
||||
|
||||
pacmanPackageFile = "${toString cfg.repoPath}/fresh-install/pacman_packages.txt";
|
||||
aurPackageFile = "${toString cfg.repoPath}/fresh-install/aur_packages.txt";
|
||||
|
||||
pacmanNamesRaw = readList pacmanPackageFile;
|
||||
aurLinesRaw = readList aurPackageFile;
|
||||
aurNames = map (line: builtins.head (lib.splitString " " line)) aurLinesRaw;
|
||||
|
||||
resolvePackage = path: lib.attrByPath (lib.splitString "." path) null pkgs;
|
||||
existsPath = path: (resolvePackage path) != null;
|
||||
|
||||
mappedRecords = map
|
||||
(original:
|
||||
let
|
||||
mapped = if builtins.hasAttr original cfg.packageMap then builtins.getAttr original cfg.packageMap else original;
|
||||
in {
|
||||
inherit original mapped;
|
||||
resolved = (resolvePackage mapped) != null;
|
||||
})
|
||||
pacmanNamesRaw;
|
||||
|
||||
unresolvedRecords = builtins.filter (record: !record.resolved) mappedRecords;
|
||||
|
||||
sortStrings = builtins.sort (a: b: a < b);
|
||||
sortRecordsByOriginal = builtins.sort (
|
||||
a: b:
|
||||
if a.original == b.original
|
||||
then a.mapped < b.mapped
|
||||
else a.original < b.original
|
||||
);
|
||||
|
||||
candidatePaths = record:
|
||||
let
|
||||
pythonCandidate =
|
||||
if lib.hasPrefix "python-" record.original
|
||||
then "python3Packages.${lib.removePrefix "python-" record.original}"
|
||||
else "";
|
||||
underscoreFromOriginal = lib.replaceStrings [ "-" ] [ "_" ] record.original;
|
||||
dashFromOriginal = lib.replaceStrings [ "_" ] [ "-" ] record.original;
|
||||
underscoreFromMapped = lib.replaceStrings [ "-" ] [ "_" ] record.mapped;
|
||||
dashFromMapped = lib.replaceStrings [ "_" ] [ "-" ] record.mapped;
|
||||
candidates = [
|
||||
record.original
|
||||
record.mapped
|
||||
underscoreFromOriginal
|
||||
dashFromOriginal
|
||||
underscoreFromMapped
|
||||
dashFromMapped
|
||||
pythonCandidate
|
||||
];
|
||||
in
|
||||
lib.unique (builtins.filter (candidate: candidate != "") candidates);
|
||||
|
||||
easySuggestions = record:
|
||||
builtins.filter
|
||||
(candidate: existsPath candidate)
|
||||
(candidatePaths record);
|
||||
easySuggestionsSorted = record: sortStrings (easySuggestions record);
|
||||
|
||||
isAurOrOverlayLikely = record:
|
||||
(builtins.elem record.original aurNames)
|
||||
|| (lib.hasSuffix "-git" record.original)
|
||||
|| (lib.hasPrefix "lib32-" record.original)
|
||||
|| (lib.hasSuffix "-bin" record.original);
|
||||
|
||||
easyMapRecords = builtins.filter (record: (builtins.length (easySuggestions record)) > 0) unresolvedRecords;
|
||||
needsOverlayRecords = builtins.filter
|
||||
(record: ((builtins.length (easySuggestions record)) == 0) && (isAurOrOverlayLikely record))
|
||||
unresolvedRecords;
|
||||
likelyUnavailableRecords = builtins.filter
|
||||
(record: ((builtins.length (easySuggestions record)) == 0) && !(isAurOrOverlayLikely record))
|
||||
unresolvedRecords;
|
||||
|
||||
easyMapRecordsSorted = sortRecordsByOriginal easyMapRecords;
|
||||
needsOverlayRecordsSorted = sortRecordsByOriginal needsOverlayRecords;
|
||||
likelyUnavailableRecordsSorted = sortRecordsByOriginal likelyUnavailableRecords;
|
||||
aurNamesSorted = sortStrings aurNames;
|
||||
|
||||
formatSimpleRecord = record: "- ${record.original} -> ${record.mapped}";
|
||||
formatEasyRecord = record:
|
||||
"- ${record.original} -> ${record.mapped} | suggestions: ${lib.concatStringsSep ", " (easySuggestionsSorted record)}";
|
||||
|
||||
renderLines = lines:
|
||||
if (builtins.length lines) == 0
|
||||
then "- none"
|
||||
else lib.concatStringsSep "\n" lines;
|
||||
|
||||
toEasyJsonRecord = record: {
|
||||
original = record.original;
|
||||
mapped = record.mapped;
|
||||
suggestions = easySuggestionsSorted record;
|
||||
};
|
||||
|
||||
toSimpleJsonRecord = record: {
|
||||
original = record.original;
|
||||
mapped = record.mapped;
|
||||
};
|
||||
|
||||
reportText = ''
|
||||
linux_configuration nix-poc package resolution report
|
||||
================================================
|
||||
|
||||
Source files:
|
||||
- ${pacmanPackageFile}
|
||||
- ${aurPackageFile}
|
||||
|
||||
Summary:
|
||||
- Total pacman package entries: ${toString (builtins.length pacmanNamesRaw)}
|
||||
- Unresolved pacman entries after current mapping: ${toString (builtins.length unresolvedRecords)}
|
||||
- AUR package entries: ${toString (builtins.length aurNames)}
|
||||
|
||||
Category: easy-map (likely solvable by small mapping/path fixes)
|
||||
---------------------------------------------------------------
|
||||
${renderLines (map formatEasyRecord easyMapRecordsSorted)}
|
||||
|
||||
Category: needs-overlay (AUR/multilib/git/bin packages)
|
||||
-------------------------------------------------------
|
||||
${renderLines (map formatSimpleRecord needsOverlayRecordsSorted)}
|
||||
|
||||
Category: likely-unavailable (needs manual investigation)
|
||||
---------------------------------------------------------
|
||||
${renderLines (map formatSimpleRecord likelyUnavailableRecordsSorted)}
|
||||
|
||||
AUR inventory
|
||||
-------------
|
||||
${renderLines (map (name: "- ${name}") aurNamesSorted)}
|
||||
'';
|
||||
|
||||
reportJson = {
|
||||
schemaVersion = "1.0";
|
||||
sourceFiles = {
|
||||
pacman = pacmanPackageFile;
|
||||
aur = aurPackageFile;
|
||||
};
|
||||
summary = {
|
||||
pacmanEntries = builtins.length pacmanNamesRaw;
|
||||
unresolvedPacmanEntries = builtins.length unresolvedRecords;
|
||||
aurEntries = builtins.length aurNames;
|
||||
};
|
||||
categories = {
|
||||
easyMap = map toEasyJsonRecord easyMapRecordsSorted;
|
||||
needsOverlay = map toSimpleJsonRecord needsOverlayRecordsSorted;
|
||||
likelyUnavailable = map toSimpleJsonRecord likelyUnavailableRecordsSorted;
|
||||
};
|
||||
aurInventory = aurNamesSorted;
|
||||
};
|
||||
in {
|
||||
config = lib.mkIf (cfg.enable && cfg.enableResolutionReport) {
|
||||
warnings = [
|
||||
"linuxConfigPoc: package resolution report generated at /etc/${cfg.resolutionReportEtcPath}${lib.optionalString cfg.enableResolutionReportJson " and /etc/${cfg.resolutionReportJsonEtcPath}"}"
|
||||
];
|
||||
|
||||
environment.etc = {
|
||||
"${cfg.resolutionReportEtcPath}".text = reportText;
|
||||
} // lib.optionalAttrs cfg.enableResolutionReportJson {
|
||||
"${cfg.resolutionReportJsonEtcPath}".text = builtins.toJSON reportJson;
|
||||
};
|
||||
};
|
||||
}
|
||||
@ -1,119 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
cfg = config.linuxConfigPoc;
|
||||
repo = toString cfg.repoPath;
|
||||
commonScriptPath = with pkgs; [
|
||||
bash
|
||||
coreutils
|
||||
curl
|
||||
findutils
|
||||
gawk
|
||||
gnugrep
|
||||
gnused
|
||||
procps
|
||||
util-linux
|
||||
];
|
||||
in {
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.services.periodic-system-maintenance = {
|
||||
description = "Periodic System Maintenance (Pacman Wrapper & Hosts File)";
|
||||
after = [ "network-online.target" ];
|
||||
wants = [ "network-online.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
User = "root";
|
||||
ExecStart = "${repo}/scripts/periodic_background/system-maintenance/bin/periodic-system-maintenance.sh";
|
||||
StandardOutput = "journal";
|
||||
StandardError = "journal";
|
||||
TimeoutStartSec = "300";
|
||||
TimeoutStopSec = "30";
|
||||
Restart = "no";
|
||||
};
|
||||
path = commonScriptPath;
|
||||
};
|
||||
|
||||
systemd.timers.periodic-system-maintenance = {
|
||||
description = "Run Periodic System Maintenance every hour";
|
||||
wantedBy = [ "timers.target" ];
|
||||
timerConfig = {
|
||||
OnCalendar = "hourly";
|
||||
OnBootSec = "5min";
|
||||
RandomizedDelaySec = "300";
|
||||
Persistent = true;
|
||||
};
|
||||
unitConfig = {
|
||||
Requires = "periodic-system-maintenance.service";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.periodic-system-startup = {
|
||||
description = "System Maintenance on Startup (Pacman Wrapper & Hosts File)";
|
||||
after = [ "network-online.target" "systemd-resolved.service" ];
|
||||
wants = [ "network-online.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
User = "root";
|
||||
ExecStart = "${repo}/scripts/periodic_background/system-maintenance/bin/periodic-system-maintenance.sh";
|
||||
StandardOutput = "journal";
|
||||
StandardError = "journal";
|
||||
RemainAfterExit = true;
|
||||
TimeoutStartSec = "300";
|
||||
TimeoutStopSec = "30";
|
||||
};
|
||||
path = commonScriptPath;
|
||||
};
|
||||
|
||||
systemd.services.hosts-file-monitor = {
|
||||
description = "Hosts File Monitor and Auto-Restore Service";
|
||||
after = [ "network-online.target" ];
|
||||
wants = [ "network-online.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
User = "root";
|
||||
ExecStart = "${repo}/scripts/periodic_background/system-maintenance/bin/hosts-file-monitor.sh";
|
||||
Restart = "always";
|
||||
RestartSec = "10";
|
||||
StandardOutput = "journal";
|
||||
StandardError = "journal";
|
||||
NoNewPrivileges = false;
|
||||
PrivateTmp = true;
|
||||
MemoryMax = "50M";
|
||||
CPUQuota = "10%";
|
||||
};
|
||||
path = commonScriptPath;
|
||||
};
|
||||
|
||||
systemd.services.auto-system-update = {
|
||||
description = "Automatic System Update (pacman + yay AUR)";
|
||||
after = [ "network-online.target" ];
|
||||
wants = [ "network-online.target" ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
User = "root";
|
||||
ExecStart = "${repo}/scripts/periodic_background/system-maintenance/bin/auto-system-update.sh";
|
||||
StandardOutput = "journal";
|
||||
StandardError = "journal";
|
||||
TimeoutStartSec = "1800";
|
||||
TimeoutStopSec = "30";
|
||||
Restart = "no";
|
||||
};
|
||||
path = commonScriptPath;
|
||||
};
|
||||
|
||||
systemd.timers.auto-system-update = {
|
||||
description = "Run Automatic System Update daily";
|
||||
wantedBy = [ "timers.target" ];
|
||||
timerConfig = {
|
||||
OnCalendar = "*-*-* 04:00:00";
|
||||
RandomizedDelaySec = "1800";
|
||||
Persistent = true;
|
||||
};
|
||||
unitConfig = {
|
||||
Requires = "auto-system-update.service";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -290,8 +290,8 @@ else
|
||||
fi
|
||||
|
||||
cd ~/linux-configuration
|
||||
sudo hosts/install.sh
|
||||
i3-configuration/install.sh
|
||||
sudo scripts/periodic_background/hosts/install.sh
|
||||
scripts/periodic_background/i3-configuration/install.sh
|
||||
scripts/periodic_background/digital_wellbeing/pacman/install_pacman_wrapper.sh
|
||||
scripts/fixes/nvidia_troubleshoot.sh
|
||||
sudo scripts/features/setup_activitywatch.sh
|
||||
@ -17,7 +17,7 @@ for file in "$@"; do
|
||||
|
||||
# Skip allowed directories (non-Python projects with some Python scripts)
|
||||
case "$file" in
|
||||
linux_configuration/*|scripts/*) continue ;;
|
||||
linux_configuration/*|scripts/*|meta/scripts/*) continue ;;
|
||||
esac
|
||||
|
||||
# Skip vendored/generated directories
|
||||
@ -3,6 +3,7 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import datetime
|
||||
import json
|
||||
import sqlite3
|
||||
import subprocess
|
||||
@ -779,10 +780,17 @@ class TestIsWorkoutFinishRecent:
|
||||
"CREATE TABLE workouts "
|
||||
"(id TEXT PRIMARY KEY, start INTEGER, finish INTEGER)",
|
||||
)
|
||||
now_ms = int(time.time() * 1000)
|
||||
# Anchor to local noon to avoid midnight boundary issues: the SQL
|
||||
# date() filter requires start and now to share the same local date.
|
||||
local_noon = (
|
||||
datetime.datetime.now(tz=datetime.timezone.utc)
|
||||
.astimezone()
|
||||
.replace(hour=12, minute=0, second=0, microsecond=0)
|
||||
)
|
||||
local_noon_ms = int(local_noon.timestamp() * 1000)
|
||||
conn.execute(
|
||||
"INSERT INTO workouts VALUES (?, ?, ?)",
|
||||
("w1", now_ms - 3600000, now_ms),
|
||||
("w1", local_noon_ms, local_noon_ms + 3_600_000),
|
||||
)
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
Loading…
Reference in New Issue
Block a user