summaryrefslogtreecommitdiff
path: root/Omni/Ide
diff options
context:
space:
mode:
Diffstat (limited to 'Omni/Ide')
-rw-r--r--Omni/Ide/README.md143
-rwxr-xr-xOmni/Ide/ailint.sh11
-rwxr-xr-xOmni/Ide/hooks/commit-msg6
-rwxr-xr-xOmni/Ide/hooks/post-checkout1
-rwxr-xr-xOmni/Ide/hooks/post-merge1
-rwxr-xr-xOmni/Ide/hooks/pre-push6
-rwxr-xr-xOmni/Ide/push.sh1
-rwxr-xr-xOmni/Ide/repl.sh7
-rwxr-xr-xOmni/Ide/run.sh6
-rwxr-xr-xOmni/Ide/typecheck.sh37
10 files changed, 215 insertions, 4 deletions
diff --git a/Omni/Ide/README.md b/Omni/Ide/README.md
new file mode 100644
index 0000000..7511090
--- /dev/null
+++ b/Omni/Ide/README.md
@@ -0,0 +1,143 @@
+# Development Tools and Workflow
+
+## Tools
+
+### run.sh
+
+`run.sh` is a convenience wrapper that builds (if needed) and runs a namespace.
+
+Examples:
+```bash
+Omni/Ide/run.sh Omni/Task.hs # Build and run task manager
+Omni/Ide/run.sh Biz/PodcastItLater/Web.py # Build and run web server
+```
+
+This script will:
+1. Check if the binary exists in `_/bin/`
+2. Build it if it doesn't exist (exits on build failure)
+3. Execute the binary with any additional arguments
+
+### lint
+
+Universal lint and formatting tool. Errors if lints fail or code is not formatted properly.
+
+Examples:
+```bash
+lint Omni/Cli.hs # Lint a namespace
+lint --fix **/*.py # Lint and fix all Python files
+```
+
+### repl.sh
+
+Like `nix-shell` but specific to this repo. Analyzes the namespace, pulls dependencies, and starts a shell or repl.
+
+Examples:
+```bash
+repl.sh Omni/Bild.hs # Start Haskell repl with namespace loaded
+repl.sh --bash Omni/Log.py # Start bash shell for namespace
+```
+
+### typecheck.sh
+
+Like `lint` but only runs type checkers. Currently just supports Python with `mypy`, but eventually will support everything that `bild` supports.
+
+Examples:
+```bash
+typecheck.sh Omni/Bild/Example.py # Run the typechecker and report any errors
+```
+
+### Test Commands
+
+Run tests:
+```bash
+bild --test Omni/Task.hs # Build and test a namespace
+```
+
+The convention for all programs in the omnirepo is to run their tests if the first argument is `test`. So for example:
+
+```bash
+# this will build a the latest executable and then run tests
+bild --test Omni/Task.hs
+
+# this will just run the tests from the existing executable
+_/bin/task test
+```
+
+## Git Workflow
+
+### Use git-branchless
+
+This repository uses **git-branchless** for a patch-based workflow instead of traditional branch-based git.
+
+Key concepts:
+- Work with **patches** (commits) directly rather than branches
+- Use **stacking** to organize related changes
+- Leverage **smartlog** to visualize commit history
+
+### Common git-branchless Commands
+
+**View commit graph:**
+```bash
+git smartlog
+```
+
+**Create a new commit:**
+```bash
+# Make your changes
+git add .
+git commit -m "Your commit message"
+```
+
+**Amend the current commit:**
+```bash
+# Make additional changes
+git add .
+git amend
+```
+
+**Move/restack commits:**
+```bash
+git move -s <source> -d <destination>
+git restack
+```
+
+### When to Record Changes in Git
+
+**DO record in git:**
+- Completed features or bug fixes
+- Working code that passes tests and linting
+- Significant milestones in task completion
+
+**DO NOT record in git:**
+- Work in progress (unless specifically requested)
+- Broken or untested code
+- Temporary debugging changes
+
+**NEVER do these git operations without explicit user request:**
+- ❌ `git push` - NEVER push to remote unless explicitly asked
+- ❌ `git pull` - NEVER pull from remote unless explicitly asked
+- ❌ Force pushes or destructive operations
+- ❌ Branch deletion or remote branch operations
+
+**Why:** The user maintains control over when code is shared with collaborators. Always ask before syncing with remote repositories.
+
+### Workflow Best Practices
+
+1. **Make small, focused commits** - Each commit should represent one logical change
+2. **Write descriptive commit messages** - Explain what and why, not just what
+3. **Rebase and clean up history** - Use `git commit --amend` and `git restack` to keep history clean
+4. **Test before committing** - Run `bild --test` and `lint` on affected namespaces
+
+### Required Checks Before Completing Tasks
+
+After completing a task, **always** run these commands for the namespace(s) you modified:
+
+```bash
+# Run tests
+bild --test Omni/YourNamespace.hs
+
+# Run linter
+lint Omni/YourNamespace.hs
+```
+
+**Fix all reported errors** related to your changes before marking the task as complete. This ensures code quality and prevents breaking the build for other contributors.
diff --git a/Omni/Ide/ailint.sh b/Omni/Ide/ailint.sh
new file mode 100755
index 0000000..a107be8
--- /dev/null
+++ b/Omni/Ide/ailint.sh
@@ -0,0 +1,11 @@
+#!/usr/bin/env bash
+set -xu
+target=${1:?}
+instructions=$(mktemp)
+echo "Fix the following lint errors, or silence them with a `# noqa:` comment if they aren't problematic:" >> "$instructions"
+if lint -f "$target" >> "$instructions" 2>&1
+then
+ echo "no bad lints"
+else
+ aider --yes --message-file "$instructions" "$target"
+fi
diff --git a/Omni/Ide/hooks/commit-msg b/Omni/Ide/hooks/commit-msg
index e07d1f4..c6197f9 100755
--- a/Omni/Ide/hooks/commit-msg
+++ b/Omni/Ide/hooks/commit-msg
@@ -1,7 +1,11 @@
#!/usr/bin/env bash
+temp=$(mktemp)
+# strip everything after >8 cut line, then strip comment lines
+sed '/.*>8.*/,$d; /^#/d' "$1" | fmt -w 72 -u > "$temp"
+mv "$temp" "$1"
if ! gitlint --ignore-stdin --staged --msg-filename "$1" run-hook; then
backup="$CODEROOT"/.git/COMMIT_EDITMSG.backup
- cp "$CODEROOT"/.git/COMMIT_EDITMSG "$backup"
+ cp "$1" "$backup"
echo "error: gitlint failed, saved your commit msg as $backup"
exit 1
fi
diff --git a/Omni/Ide/hooks/post-checkout b/Omni/Ide/hooks/post-checkout
index 85541a2..a360517 100755
--- a/Omni/Ide/hooks/post-checkout
+++ b/Omni/Ide/hooks/post-checkout
@@ -14,6 +14,7 @@ elif [[ ${#changed[@]} -gt 0 ]]
then
MakeTags "${changed[@]}"
fi
+
## START BRANCHLESS CONFIG
git branchless hook post-checkout "$@"
diff --git a/Omni/Ide/hooks/post-merge b/Omni/Ide/hooks/post-merge
index fcfd314..bf0e996 100755
--- a/Omni/Ide/hooks/post-merge
+++ b/Omni/Ide/hooks/post-merge
@@ -1,5 +1,6 @@
#!/usr/bin/env bash
"${CODEROOT:?}"/Omni/Ide/hooks/post-checkout 'HEAD@{1}' HEAD
+
## START BRANCHLESS CONFIG
git branchless hook post-merge "$@"
diff --git a/Omni/Ide/hooks/pre-push b/Omni/Ide/hooks/pre-push
index 00110bd..adbf858 100755
--- a/Omni/Ide/hooks/pre-push
+++ b/Omni/Ide/hooks/pre-push
@@ -1,5 +1,11 @@
#!/usr/bin/env bash
set -euo pipefail
+
+# Task manager: Ensure tasks are exported before push
+if [ -d .tasks ]; then
+ task export --flush 2>/dev/null || true
+fi
+
remote="$1"
z40=0000000000000000000000000000000000000000
IFS=" "
diff --git a/Omni/Ide/push.sh b/Omni/Ide/push.sh
index 5c22e07..ce1df3d 100755
--- a/Omni/Ide/push.sh
+++ b/Omni/Ide/push.sh
@@ -19,6 +19,7 @@ ssh "$USER"@"$where" sudo nix-env --profile /nix/var/nix/profiles/system --set "
switch_cmd=(
systemd-run
-E LOCALE_ARCHIVE
+ --setenv=XDG_RUNTIME_DIR=""
--collect
--no-ask-password
--pipe
diff --git a/Omni/Ide/repl.sh b/Omni/Ide/repl.sh
index 3b6a536..6225078 100755
--- a/Omni/Ide/repl.sh
+++ b/Omni/Ide/repl.sh
@@ -10,6 +10,7 @@
###
### Options:
### --bash start bash instead of the target language repl
+### --cmd x run 'x' instead of bash, or the target language repl
help() {
sed -rn 's/^### ?//;T;p' "$0"
}
@@ -23,9 +24,13 @@ fi
if [[ "$1" == "--bash" ]]; then
CMD="bash"
shift
+ elif [[ "$1" == "--cmd" ]]; then
+ shift
+ CMD="$1"
+ shift
fi
targets="${*:?}"
- json=$(bild --plan "${targets[@]}")
+ json=$(bild --plan "${targets[@]}" 2>&1)
mapfile -t langdeps < <(jq --raw-output '.[].langdeps | select(length > 0) | join("\n")' <<< "$json")
mapfile -t sysdeps < <(jq --raw-output '.[].sysdeps | select(length > 0) | join("\n")' <<< "$json")
mapfile -t rundeps < <(jq --raw-output '.[].rundeps | select(length > 0) | join("\n")' <<< "$json")
diff --git a/Omni/Ide/run.sh b/Omni/Ide/run.sh
index e300fcc..e49d8bd 100755
--- a/Omni/Ide/run.sh
+++ b/Omni/Ide/run.sh
@@ -2,6 +2,8 @@
set -eu
target=$1
shift
-out=$(bild --plan "$target" | jq --raw-output ".\"${target}\".out")
-[[ -f "$out" ]] || bild "$target"
+out=$(bild --plan "$target" 2>&1 | tail -1 | jq --raw-output ".\"${target}\".out")
+if [[ ! -f "${CODEROOT:?}/_/bin/$out" ]]; then
+ bild "$target" || exit 1
+fi
exec "${CODEROOT:?}/_/bin/$out" "$@"
diff --git a/Omni/Ide/typecheck.sh b/Omni/Ide/typecheck.sh
new file mode 100755
index 0000000..fe11ef5
--- /dev/null
+++ b/Omni/Ide/typecheck.sh
@@ -0,0 +1,37 @@
+#!/usr/bin/env bash
+###
+### typecheck a given target
+###
+### > typecheck.sh <target..>
+###
+### Uses repl.sh to provision the environment for target, then runs the
+### appropriate typechecker for the given module.
+###
+help() {
+ sed -rn 's/^### ?//;T;p' "$0"
+}
+if [[ $# == 0 ]] || [[ "$1" == "-h" ]]; then
+ help
+ exit 1
+fi
+target="$1"
+
+# Determine file extension
+ext="${target##*.}"
+
+case "$ext" in
+ py)
+ # Python: use mypy via repl.sh environment
+ repl.sh --cmd "python -m mypy $target" "$target"
+ ;;
+ hs)
+ # Haskell: use ghc -fno-code for typechecking without code generation
+ # Use repl.sh to provision the right GHC environment with dependencies
+ repl.sh --cmd "ghc -fno-code -i${CODEROOT:?} $target" "$target"
+ ;;
+ *)
+ echo "Unknown file extension: $ext"
+ echo "Typechecking not supported for this file type"
+ exit 1
+ ;;
+esac