feat: align AI configuration and task trunk concurrency with shared schema
This commit is contained in:
@@ -11,7 +11,7 @@ def git(root, *args):
|
||||
return subprocess.check_output(['git', '-C', str(root), *args], text=True, stderr=subprocess.STDOUT).strip()
|
||||
|
||||
|
||||
def check_checkout(root):
|
||||
def check_checkout(root, updating=False):
|
||||
if (root / 'contracts/local').exists():
|
||||
raise ValueError('contracts/local is a forbidden parallel contract source')
|
||||
entry = git(root, 'ls-files', '--stage', '--', 'contracts/schema').split()
|
||||
@@ -25,7 +25,9 @@ def check_checkout(root):
|
||||
raise ValueError('contract submodule origin must be ' + URL)
|
||||
commit = git(sub, 'rev-parse', 'HEAD')
|
||||
if commit != entry[1]:
|
||||
raise ValueError('contract HEAD does not match the project pin; stage the verified contracts/schema pointer')
|
||||
if not updating:
|
||||
raise ValueError('contract HEAD does not match the project pin; stage the verified contracts/schema pointer')
|
||||
git(sub, 'merge-base', '--is-ancestor', entry[1], commit)
|
||||
if git(sub, 'status', '--porcelain', '--untracked-files=all'):
|
||||
raise ValueError('contract submodule has uncommitted changes; verify and commit them in the shared repository')
|
||||
return commit
|
||||
@@ -39,7 +41,7 @@ def main():
|
||||
checker = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(checker)
|
||||
count = checker.verify_bundle(checker_path.parent)
|
||||
print(f'shared contract {commit}: {count} JSON files; source/bundle hashes and offline references valid')
|
||||
print(f'shared contract {commit}: {count} JSON files; offline references and historical provenance valid')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
+4
-1
@@ -4,6 +4,9 @@ set -eu
|
||||
profile=${COVER_PROFILE:-/tmp/go-sip-coverage.out}
|
||||
business_profile=${COVER_BUSINESS_PROFILE:-/tmp/go-sip-coverage-business.out}
|
||||
|
||||
GOMAXPROCS=${GOMAXPROCS:-2} go test -p 1 -coverpkg=./... -coverprofile="$profile" ./...
|
||||
# Coverage patterns also match local module replacements. Instrument only
|
||||
# this module's explicit package list, not the checked-in third-party SDK.
|
||||
packages=$(go list ./... | paste -sd, -)
|
||||
GOMAXPROCS=${GOMAXPROCS:-2} go test -p 1 -coverpkg="$packages" -coverprofile="$profile" ./...
|
||||
awk 'NR == 1 || index($0, "/gen/") == 0' "$profile" > "$business_profile"
|
||||
go tool cover -func="$business_profile"
|
||||
|
||||
@@ -49,6 +49,22 @@ class ContractCheckoutTest(unittest.TestCase):
|
||||
with self.assertRaisesRegex(ValueError, 'does not match'):
|
||||
checker.check_checkout(self.root)
|
||||
|
||||
def test_update_rechecks_an_unstaged_fast_forward(self):
|
||||
(self.sub / 'test.schema.json').write_text('{"changed": true}\n')
|
||||
self.git(self.sub, 'add', '.')
|
||||
self.git(self.sub, 'commit', '-qm', 'changed')
|
||||
self.assertEqual(checker.check_checkout(self.root, updating=True), self.git(self.sub, 'rev-parse', 'HEAD'))
|
||||
(self.sub / 'untracked.txt').write_text('unexpected\n')
|
||||
with self.assertRaisesRegex(ValueError, 'uncommitted'):
|
||||
checker.check_checkout(self.root, updating=True)
|
||||
|
||||
def test_update_rejects_divergent_contract_history(self):
|
||||
self.git(self.sub, 'checkout', '--orphan', 'unrelated')
|
||||
self.git(self.sub, 'add', '.')
|
||||
self.git(self.sub, 'commit', '-qm', 'unrelated root')
|
||||
with self.assertRaises(subprocess.CalledProcessError):
|
||||
checker.check_checkout(self.root, updating=True)
|
||||
|
||||
def test_dirty_submodule_is_rejected(self):
|
||||
(self.sub / 'untracked.txt').write_text('unexpected\n')
|
||||
with self.assertRaisesRegex(ValueError, 'uncommitted'):
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Coverage must measure application packages, not local replacement modules."""
|
||||
import os
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
|
||||
class CoverageBoundaryTests(unittest.TestCase):
|
||||
def test_explicit_project_packages_and_generated_code_exclusion(self):
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
root = Path(directory)
|
||||
go = root / 'go'
|
||||
go.write_text('''#!/bin/sh
|
||||
set -eu
|
||||
case "$1" in
|
||||
list) printf 'example/app/internal/ai\\nexample/app/gen/agent\\n' ;;
|
||||
test)
|
||||
printf '%s\\n' "$@" > "$COMMANDS"
|
||||
printf 'mode: set\\nexample/app/internal/ai/a.go:1.1,2.2 1 1\\nexample/app/gen/agent/a.go:1.1,2.2 1 0\\n' > "$COVER_PROFILE"
|
||||
;;
|
||||
tool) exit 0 ;;
|
||||
*) exit 1 ;;
|
||||
esac
|
||||
''')
|
||||
go.chmod(0o700)
|
||||
env = dict(os.environ, PATH=str(root) + os.pathsep + os.environ['PATH'],
|
||||
COMMANDS=str(root / 'commands'), COVER_PROFILE=str(root / 'all.out'),
|
||||
COVER_BUSINESS_PROFILE=str(root / 'business.out'))
|
||||
subprocess.run(['sh', str(Path(__file__).with_name('coverage.sh'))], env=env, check=True)
|
||||
args = (root / 'commands').read_text()
|
||||
self.assertIn('-coverpkg=example/app/internal/ai,example/app/gen/agent', args)
|
||||
self.assertNotIn('-coverpkg=./...', args)
|
||||
report = (root / 'business.out').read_text()
|
||||
self.assertIn('/internal/ai/', report)
|
||||
self.assertNotIn('/gen/', report)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -6,7 +6,9 @@ sub=contracts/schema
|
||||
if [[ ! -e "$sub/.git" ]]; then
|
||||
git submodule update --init -- "$sub"
|
||||
fi
|
||||
python3 scripts/check-current-contracts.py
|
||||
# A previously fetched fast-forward may be unstaged after a failed check.
|
||||
# Still reject dirty submodule files, wrong origins and divergent history.
|
||||
python3 -c 'from pathlib import Path; from runpy import run_path; run_path("scripts/check-current-contracts.py")["check_checkout"](Path.cwd(), updating=True)'
|
||||
git -C "$sub" fetch origin main
|
||||
git -C "$sub" merge --ff-only FETCH_HEAD
|
||||
if [[ "$(git -C "$sub" rev-parse HEAD)" != "$(git -C "$sub" rev-parse FETCH_HEAD)" ]]; then
|
||||
|
||||
Reference in New Issue
Block a user