mirror of
https://github.com/Kaelio/ktx.git
synced 2026-06-07 07:55:13 +02:00
chore: upgrade dependencies and tooling (#232)
* chore: upgrade dependencies and tooling * chore: upgrade dependencies and tooling
This commit is contained in:
parent
ed8f523362
commit
d53cdac366
14 changed files with 2737 additions and 2710 deletions
2
.github/workflows/triage-issues.yml
vendored
2
.github/workflows/triage-issues.yml
vendored
|
|
@ -22,7 +22,7 @@ jobs:
|
||||||
github.event.issue.author_association != 'COLLABORATOR'
|
github.event.issue.author_association != 'COLLABORATOR'
|
||||||
steps:
|
steps:
|
||||||
- name: Apply needs-triage label
|
- name: Apply needs-triage label
|
||||||
uses: actions/github-script@v7
|
uses: actions/github-script@v9
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
await github.rest.issues.addLabels({
|
await github.rest.issues.addLabels({
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,12 @@ repos:
|
||||||
- id: check-case-conflict
|
- id: check-case-conflict
|
||||||
- id: mixed-line-ending
|
- id: mixed-line-ending
|
||||||
|
|
||||||
|
- repo: https://github.com/tombi-toml/tombi-pre-commit
|
||||||
|
rev: v1.1.0
|
||||||
|
hooks:
|
||||||
|
- id: tombi-format
|
||||||
|
args: ["--offline"]
|
||||||
|
|
||||||
- repo: https://github.com/asottile/pyupgrade
|
- repo: https://github.com/asottile/pyupgrade
|
||||||
rev: v3.21.2
|
rev: v3.21.2
|
||||||
hooks:
|
hooks:
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@xyflow/react": "^12.10.2",
|
"@xyflow/react": "^12.10.2",
|
||||||
"fumadocs-core": "16.8.10",
|
"fumadocs-core": "16.8.10",
|
||||||
"fumadocs-mdx": "15.0.4",
|
"fumadocs-mdx": "15.0.7",
|
||||||
"fumadocs-ui": "16.8.10",
|
"fumadocs-ui": "16.8.10",
|
||||||
"next": "^16",
|
"next": "^16",
|
||||||
"react": "19.2.6",
|
"react": "19.2.6",
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tailwindcss/postcss": "^4",
|
"@tailwindcss/postcss": "^4",
|
||||||
"@types/node": "^25.7.0",
|
"@types/node": "^25.9.1",
|
||||||
"@types/react": "^19",
|
"@types/react": "^19",
|
||||||
"@types/react-dom": "^19",
|
"@types/react-dom": "^19",
|
||||||
"tailwindcss": "^4",
|
"tailwindcss": "^4",
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
"description": "Workspace root for ktx packages",
|
"description": "Workspace root for ktx packages",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"packageManager": "pnpm@11.1.1",
|
"packageManager": "pnpm@11.4.0",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=22.0.0",
|
"node": ">=22.0.0",
|
||||||
"pnpm": ">=10.20.0"
|
"pnpm": ">=10.20.0"
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
"dead-code:fix": "biome check . --formatter-enabled=false --assist-enabled=false --write && knip --fix --format",
|
"dead-code:fix": "biome check . --formatter-enabled=false --assist-enabled=false --write && knip --fix --format",
|
||||||
"dead-code:knip": "knip --reporter compact",
|
"dead-code:knip": "knip --reporter compact",
|
||||||
"dead-code:knip:production": "knip --production --reporter compact",
|
"dead-code:knip:production": "knip --production --reporter compact",
|
||||||
|
"deps:upgrade": "node scripts/upgrade-dependencies.mjs",
|
||||||
"docs": "kill $(lsof -ti:3000) 2>/dev/null; pnpm --filter ktx-docs run dev",
|
"docs": "kill $(lsof -ti:3000) 2>/dev/null; pnpm --filter ktx-docs run dev",
|
||||||
"ktx": "node scripts/run-ktx.mjs",
|
"ktx": "node scripts/run-ktx.mjs",
|
||||||
"link:dev": "node scripts/link-dev-cli.mjs",
|
"link:dev": "node scripts/link-dev-cli.mjs",
|
||||||
|
|
@ -58,11 +59,11 @@
|
||||||
"@semantic-release/github": "^12.0.8",
|
"@semantic-release/github": "^12.0.8",
|
||||||
"@semantic-release/npm": "^13.1.5",
|
"@semantic-release/npm": "^13.1.5",
|
||||||
"@semantic-release/release-notes-generator": "^14.1.1",
|
"@semantic-release/release-notes-generator": "^14.1.1",
|
||||||
"@types/node": "^25.7.0",
|
"@types/node": "^25.9.1",
|
||||||
"better-sqlite3": "^12.10.0",
|
"better-sqlite3": "^12.10.0",
|
||||||
"conventional-changelog-conventionalcommits": "^9.3.1",
|
"conventional-changelog-conventionalcommits": "^9.3.1",
|
||||||
"knip": "^6.12.2",
|
"knip": "^6.14.1",
|
||||||
"pg": "^8.20.0",
|
"pg": "^8.21.0",
|
||||||
"semantic-release": "^25.0.3",
|
"semantic-release": "^25.0.3",
|
||||||
"typescript": "^6.0.3",
|
"typescript": "^6.0.3",
|
||||||
"yaml": "^2.9.0"
|
"yaml": "^2.9.0"
|
||||||
|
|
|
||||||
|
|
@ -43,36 +43,36 @@
|
||||||
"search:pglite-sl-prototype": "node ../../scripts/pglite-sl-search-prototype.mjs"
|
"search:pglite-sl-prototype": "node ../../scripts/pglite-sl-search-prototype.mjs"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ai-sdk/anthropic": "3.0.77",
|
"@ai-sdk/anthropic": "3.0.78",
|
||||||
"@ai-sdk/devtools": "0.0.17",
|
"@ai-sdk/devtools": "0.0.18",
|
||||||
"@ai-sdk/google-vertex": "^4.0.128",
|
"@ai-sdk/google-vertex": "^4.0.134",
|
||||||
"@anthropic-ai/claude-agent-sdk": "0.3.142",
|
"@anthropic-ai/claude-agent-sdk": "0.3.146",
|
||||||
"@clack/prompts": "1.4.0",
|
"@clack/prompts": "1.4.0",
|
||||||
"@clickhouse/client": "^1.18.4",
|
"@clickhouse/client": "^1.18.5",
|
||||||
"@commander-js/extra-typings": "14.0.0",
|
"@commander-js/extra-typings": "14.0.0",
|
||||||
"@google-cloud/bigquery": "^8.3.1",
|
"@google-cloud/bigquery": "^8.3.1",
|
||||||
"@looker/sdk": "^26.8.0",
|
"@looker/sdk": "^26.8.0",
|
||||||
"@looker/sdk-node": "^26.8.0",
|
"@looker/sdk-node": "^26.8.0",
|
||||||
"@looker/sdk-rtl": "^21.6.5",
|
"@looker/sdk-rtl": "^21.6.5",
|
||||||
"@modelcontextprotocol/sdk": "^1.29.0",
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
||||||
"@notionhq/client": "^5.21.0",
|
"@notionhq/client": "^5.22.0",
|
||||||
"ai": "^6.0.180",
|
"ai": "^6.0.188",
|
||||||
"better-sqlite3": "^12.10.0",
|
"better-sqlite3": "^12.10.0",
|
||||||
"commander": "14.0.3",
|
"commander": "14.0.3",
|
||||||
"fflate": "^0.8.2",
|
"fflate": "^0.8.3",
|
||||||
"handlebars": "^4.7.9",
|
"handlebars": "^4.7.9",
|
||||||
"ink": "^7.0.2",
|
"ink": "^7.0.3",
|
||||||
"lookml-parser": "7.1.0",
|
"lookml-parser": "7.1.0",
|
||||||
"minimatch": "^10.2.5",
|
"minimatch": "^10.2.5",
|
||||||
"mssql": "^12.5.2",
|
"mssql": "^12.5.4",
|
||||||
"mysql2": "^3.22.3",
|
"mysql2": "^3.22.3",
|
||||||
"openai": "^6.37.0",
|
"openai": "^6.38.0",
|
||||||
"p-limit": "^7.3.0",
|
"p-limit": "^7.3.0",
|
||||||
"pg": "^8.20.0",
|
"pg": "^8.21.0",
|
||||||
"posthog-node": "^5.0.0",
|
"posthog-node": "^5.34.9",
|
||||||
"react": "^19.2.6",
|
"react": "^19.2.6",
|
||||||
"simple-git": "3.36.0",
|
"simple-git": "3.36.0",
|
||||||
"snowflake-sdk": "^2.4.1",
|
"snowflake-sdk": "^2.4.2",
|
||||||
"yaml": "^2.9.0",
|
"yaml": "^2.9.0",
|
||||||
"zod": "^4.4.3"
|
"zod": "^4.4.3"
|
||||||
},
|
},
|
||||||
|
|
@ -81,14 +81,14 @@
|
||||||
"@electric-sql/pglite-socket": "^0.1.5",
|
"@electric-sql/pglite-socket": "^0.1.5",
|
||||||
"@types/better-sqlite3": "^7.6.13",
|
"@types/better-sqlite3": "^7.6.13",
|
||||||
"@types/mssql": "^12.3.0",
|
"@types/mssql": "^12.3.0",
|
||||||
"@types/node": "^25.7.0",
|
"@types/node": "^25.9.1",
|
||||||
"@types/pg": "^8.20.0",
|
"@types/pg": "^8.20.0",
|
||||||
"@types/react": "^19.2.14",
|
"@types/react": "^19.2.15",
|
||||||
"@vitest/coverage-v8": "^4.1.6",
|
"@vitest/coverage-v8": "^4.1.7",
|
||||||
"ajv": "8.20.0",
|
"ajv": "8.20.0",
|
||||||
"ink-testing-library": "^4.0.0",
|
"ink-testing-library": "^4.0.0",
|
||||||
"typescript": "^6.0.3",
|
"typescript": "^6.0.3",
|
||||||
"vitest": "^4.1.6"
|
"vitest": "^4.1.7"
|
||||||
},
|
},
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|
|
||||||
3021
pnpm-lock.yaml
generated
3021
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load diff
|
|
@ -23,3 +23,4 @@ allowBuilds:
|
||||||
better-sqlite3: true
|
better-sqlite3: true
|
||||||
esbuild: true
|
esbuild: true
|
||||||
sharp: true
|
sharp: true
|
||||||
|
minimumReleaseAge: 10080
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,10 @@ Issues = "https://github.com/kaelio/ktx/issues"
|
||||||
|
|
||||||
[dependency-groups]
|
[dependency-groups]
|
||||||
dev = [
|
dev = [
|
||||||
"pre-commit>=4.6.0",
|
"pre-commit>=4.6.0",
|
||||||
"pytest>=9.0.2",
|
"pytest>=9.0.2",
|
||||||
"pytest-cov>=7.1.0",
|
"pytest-cov>=7.1.0",
|
||||||
"ruff>=0.8.4",
|
"ruff>=0.8.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
[tool.uv]
|
[tool.uv]
|
||||||
|
|
@ -32,14 +32,14 @@ torch = { index = "pytorch-cpu" }
|
||||||
|
|
||||||
[tool.uv.workspace]
|
[tool.uv.workspace]
|
||||||
members = [
|
members = [
|
||||||
"python/ktx-sl",
|
"python/ktx-sl",
|
||||||
"python/ktx-daemon",
|
"python/ktx-daemon",
|
||||||
]
|
]
|
||||||
|
|
||||||
[tool.pytest.ini_options]
|
[tool.pytest.ini_options]
|
||||||
addopts = ["--import-mode=importlib"]
|
addopts = ["--import-mode=importlib"]
|
||||||
pythonpath = ["python/ktx-sl/tests"]
|
pythonpath = ["python/ktx-sl/tests"]
|
||||||
testpaths = [
|
testpaths = [
|
||||||
"python/ktx-sl/tests",
|
"python/ktx-sl/tests",
|
||||||
"python/ktx-daemon/tests",
|
"python/ktx-daemon/tests",
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -6,18 +6,18 @@ readme = "README.md"
|
||||||
requires-python = ">=3.13"
|
requires-python = ">=3.13"
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fastapi>=0.115.0",
|
"fastapi>=0.136.3",
|
||||||
"ktx-sl",
|
"ktx-sl",
|
||||||
"lkml>=1.3.7",
|
"lkml>=1.3.7",
|
||||||
"numpy>=2.2.6",
|
"numpy>=2.4.6",
|
||||||
"orjson>=3.11.4",
|
"orjson>=3.11.9",
|
||||||
"pandas>=2.2.3",
|
"pandas>=3.0.3",
|
||||||
"posthog>=7.0.0",
|
"posthog>=7.16.1",
|
||||||
"psycopg[binary]>=3.2.0",
|
"psycopg[binary]>=3.3.4",
|
||||||
"pydantic>=2.9.0",
|
"pydantic>=2.13.4",
|
||||||
"requests>=2.32.0",
|
"requests>=2.34.2",
|
||||||
"sqlglot>=26",
|
"sqlglot>=30",
|
||||||
"uvicorn[standard]>=0.32.0",
|
"uvicorn[standard]>=0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[project.scripts]
|
[project.scripts]
|
||||||
|
|
@ -25,8 +25,8 @@ ktx-daemon = "ktx_daemon.__main__:main"
|
||||||
|
|
||||||
[project.optional-dependencies]
|
[project.optional-dependencies]
|
||||||
local-embeddings = [
|
local-embeddings = [
|
||||||
"sentence-transformers>=5.1.1",
|
"sentence-transformers>=5.1.1",
|
||||||
"torch>=2.2.0",
|
"torch>=2.2.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[project.urls]
|
[project.urls]
|
||||||
|
|
@ -43,8 +43,8 @@ packages = ["src/ktx_daemon"]
|
||||||
|
|
||||||
[dependency-groups]
|
[dependency-groups]
|
||||||
dev = [
|
dev = [
|
||||||
"httpx>=0.28.1",
|
"httpx>=0.28.1",
|
||||||
"pytest>=9.0.2",
|
"pytest>=9.0.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[tool.uv.sources]
|
[tool.uv.sources]
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,9 @@ readme = "README.md"
|
||||||
requires-python = ">=3.13"
|
requires-python = ">=3.13"
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"sqlglot>=26",
|
"sqlglot>=30",
|
||||||
"pydantic>=2",
|
"pydantic>=2",
|
||||||
"pyyaml>=6",
|
"pyyaml>=6",
|
||||||
]
|
]
|
||||||
|
|
||||||
[project.urls]
|
[project.urls]
|
||||||
|
|
@ -18,13 +18,13 @@ Issues = "https://github.com/kaelio/ktx/issues"
|
||||||
|
|
||||||
[project.optional-dependencies]
|
[project.optional-dependencies]
|
||||||
dev = [
|
dev = [
|
||||||
"pytest>=8",
|
"pytest>=8",
|
||||||
"pytest-cov",
|
"pytest-cov",
|
||||||
"ruff",
|
"ruff",
|
||||||
"pre-commit",
|
"pre-commit",
|
||||||
]
|
]
|
||||||
tpch = [
|
tpch = [
|
||||||
"duckdb>=1.0",
|
"duckdb>=1.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[tool.pytest.ini_options]
|
[tool.pytest.ini_options]
|
||||||
|
|
@ -40,9 +40,9 @@ branch = true
|
||||||
show_missing = true
|
show_missing = true
|
||||||
skip_empty = true
|
skip_empty = true
|
||||||
exclude_lines = [
|
exclude_lines = [
|
||||||
"pragma: no cover",
|
"pragma: no cover",
|
||||||
"if __name__ == .__main__.",
|
"if __name__ == .__main__.",
|
||||||
"if TYPE_CHECKING:",
|
"if TYPE_CHECKING:",
|
||||||
]
|
]
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
|
|
@ -54,6 +54,6 @@ packages = ["semantic_layer"]
|
||||||
|
|
||||||
[dependency-groups]
|
[dependency-groups]
|
||||||
dev = [
|
dev = [
|
||||||
"pytest>=9.0.2",
|
"pytest>=9.0.2",
|
||||||
"pytest-cov>=7.1.0",
|
"pytest-cov>=7.1.0",
|
||||||
]
|
]
|
||||||
|
|
|
||||||
111
scripts/upgrade-dependencies.mjs
Normal file
111
scripts/upgrade-dependencies.mjs
Normal file
|
|
@ -0,0 +1,111 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
import { execFile as execFileCallback } from 'node:child_process';
|
||||||
|
import { readFile as fsReadFile } from 'node:fs/promises';
|
||||||
|
import { dirname, resolve } from 'node:path';
|
||||||
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
||||||
|
import { promisify } from 'node:util';
|
||||||
|
|
||||||
|
const execFileAsync = promisify(execFileCallback);
|
||||||
|
const npmCheckUpdatesRejectArgs = ['--reject', 'fumadocs-core,fumadocs-ui'];
|
||||||
|
|
||||||
|
function ktxRootDir() {
|
||||||
|
return resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
||||||
|
}
|
||||||
|
|
||||||
|
function failureText(error) {
|
||||||
|
const stdout = typeof error?.stdout === 'string' ? error.stdout.trim() : '';
|
||||||
|
const stderr = typeof error?.stderr === 'string' ? error.stderr.trim() : '';
|
||||||
|
const message = error instanceof Error ? error.message.trim() : String(error);
|
||||||
|
return [stderr, stdout, message].filter((line) => line.length > 0).join('\n') || 'Command failed';
|
||||||
|
}
|
||||||
|
|
||||||
|
function commandText(command, args) {
|
||||||
|
return [command, ...args].join(' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
function pythonDependencyUpdatePhases() {
|
||||||
|
const manifests = ['pyproject.toml', 'python/ktx-sl/pyproject.toml', 'python/ktx-daemon/pyproject.toml'];
|
||||||
|
return manifests.map((manifest) => ({
|
||||||
|
name: `Python dependency constraints: ${manifest}`,
|
||||||
|
command: 'uvx',
|
||||||
|
args: ['dependency-check-updates', '--manifest', manifest, '-u'],
|
||||||
|
retry: commandText('uvx', ['dependency-check-updates', '--manifest', manifest, '-u']),
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
async function pnpmMinimumReleaseAgeCooldown(rootDir, readFile) {
|
||||||
|
let workspaceConfig;
|
||||||
|
try {
|
||||||
|
workspaceConfig = await readFile(resolve(rootDir, 'pnpm-workspace.yaml'), 'utf8');
|
||||||
|
} catch (error) {
|
||||||
|
if (error?.code === 'ENOENT') {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
const match = workspaceConfig.match(/^\s*minimumReleaseAge:\s*(\d+)\s*$/m);
|
||||||
|
if (!match) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return ['--cooldown', `${match[1]}m`];
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function runDependencyUpgrade(options = {}) {
|
||||||
|
const rootDir = options.rootDir ?? ktxRootDir();
|
||||||
|
const execFile = options.execFile ?? execFileAsync;
|
||||||
|
const readFile = options.readFile ?? fsReadFile;
|
||||||
|
const log = options.log ?? ((line) => process.stdout.write(`${line}\n`));
|
||||||
|
const npmCheckUpdatesCooldownArgs = await pnpmMinimumReleaseAgeCooldown(rootDir, readFile);
|
||||||
|
const phases = [
|
||||||
|
{
|
||||||
|
name: 'TypeScript dependency constraints',
|
||||||
|
command: 'pnpm',
|
||||||
|
args: ['dlx', 'npm-check-updates', '-u', '--deep', ...npmCheckUpdatesRejectArgs, ...npmCheckUpdatesCooldownArgs],
|
||||||
|
retry: commandText('pnpm', [
|
||||||
|
'dlx',
|
||||||
|
'npm-check-updates',
|
||||||
|
'-u',
|
||||||
|
'--deep',
|
||||||
|
...npmCheckUpdatesRejectArgs,
|
||||||
|
...npmCheckUpdatesCooldownArgs,
|
||||||
|
]),
|
||||||
|
},
|
||||||
|
...pythonDependencyUpdatePhases(),
|
||||||
|
{
|
||||||
|
name: 'TypeScript lockfile',
|
||||||
|
command: 'pnpm',
|
||||||
|
args: ['install'],
|
||||||
|
retry: 'pnpm install',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Python lockfile',
|
||||||
|
command: 'uv',
|
||||||
|
args: ['lock', '--upgrade'],
|
||||||
|
retry: 'uv lock --upgrade',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const phase of phases) {
|
||||||
|
log(`RUN ${phase.name}: ${commandText(phase.command, phase.args)}`);
|
||||||
|
try {
|
||||||
|
await execFile(phase.command, phase.args, { cwd: rootDir, maxBuffer: 1024 * 1024 * 64 });
|
||||||
|
log(`PASS ${phase.name}`);
|
||||||
|
} catch (error) {
|
||||||
|
log(`FAIL ${phase.name}: ${failureText(error)}`);
|
||||||
|
log(`Retry: ${phase.retry}`);
|
||||||
|
return { ok: false, failedPhase: phase };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log('Dependency manifests and lockfiles were updated. Run `pnpm run check` before committing.');
|
||||||
|
return { ok: true };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (import.meta.url === pathToFileURL(process.argv[1]).href) {
|
||||||
|
const result = await runDependencyUpgrade();
|
||||||
|
if (!result.ok) {
|
||||||
|
process.exitCode = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
123
scripts/upgrade-dependencies.test.mjs
Normal file
123
scripts/upgrade-dependencies.test.mjs
Normal file
|
|
@ -0,0 +1,123 @@
|
||||||
|
import assert from 'node:assert/strict';
|
||||||
|
import { readFile } from 'node:fs/promises';
|
||||||
|
import { test } from 'node:test';
|
||||||
|
import { runDependencyUpgrade } from './upgrade-dependencies.mjs';
|
||||||
|
|
||||||
|
test('runDependencyUpgrade updates TypeScript and Python manifests before regenerating lockfiles', async () => {
|
||||||
|
const calls = [];
|
||||||
|
const logs = [];
|
||||||
|
|
||||||
|
const result = await runDependencyUpgrade({
|
||||||
|
rootDir: '/workspace/ktx',
|
||||||
|
readFile: async (path) => {
|
||||||
|
assert.equal(path, '/workspace/ktx/pnpm-workspace.yaml');
|
||||||
|
return 'packages: []\nminimumReleaseAge: 10080\n';
|
||||||
|
},
|
||||||
|
execFile: async (command, args, options) => {
|
||||||
|
calls.push({ command, args, cwd: options.cwd });
|
||||||
|
return { stdout: '', stderr: '' };
|
||||||
|
},
|
||||||
|
log: (line) => logs.push(line),
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.equal(result.ok, true);
|
||||||
|
assert.deepEqual(
|
||||||
|
calls.map((call) => [call.command, call.args]),
|
||||||
|
[
|
||||||
|
[
|
||||||
|
'pnpm',
|
||||||
|
[
|
||||||
|
'dlx',
|
||||||
|
'npm-check-updates',
|
||||||
|
'-u',
|
||||||
|
'--deep',
|
||||||
|
'--reject',
|
||||||
|
'fumadocs-core,fumadocs-ui',
|
||||||
|
'--cooldown',
|
||||||
|
'10080m',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
['uvx', ['dependency-check-updates', '--manifest', 'pyproject.toml', '-u']],
|
||||||
|
['uvx', ['dependency-check-updates', '--manifest', 'python/ktx-sl/pyproject.toml', '-u']],
|
||||||
|
['uvx', ['dependency-check-updates', '--manifest', 'python/ktx-daemon/pyproject.toml', '-u']],
|
||||||
|
['pnpm', ['install']],
|
||||||
|
['uv', ['lock', '--upgrade']],
|
||||||
|
],
|
||||||
|
);
|
||||||
|
assert.equal(calls.every((call) => call.cwd === '/workspace/ktx'), true);
|
||||||
|
assert.equal(logs.some((line) => line.includes('PASS Python dependency constraints')), true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('runDependencyUpgrade stops at the failed phase and prints a retry command', async () => {
|
||||||
|
const calls = [];
|
||||||
|
const logs = [];
|
||||||
|
|
||||||
|
const result = await runDependencyUpgrade({
|
||||||
|
rootDir: '/workspace/ktx',
|
||||||
|
readFile: async () => 'packages: []\n',
|
||||||
|
execFile: async (command, args) => {
|
||||||
|
calls.push({ command, args });
|
||||||
|
if (command === 'uvx' && args.includes('python/ktx-sl/pyproject.toml')) {
|
||||||
|
const error = new Error('dependency-check-updates failed');
|
||||||
|
error.stdout = 'checking Python dependencies';
|
||||||
|
error.stderr = 'could not read pyproject.toml';
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
return { stdout: '', stderr: '' };
|
||||||
|
},
|
||||||
|
log: (line) => logs.push(line),
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.equal(result.ok, false);
|
||||||
|
assert.equal(result.failedPhase.name, 'Python dependency constraints: python/ktx-sl/pyproject.toml');
|
||||||
|
assert.equal(result.failedPhase.retry, 'uvx dependency-check-updates --manifest python/ktx-sl/pyproject.toml -u');
|
||||||
|
assert.deepEqual(
|
||||||
|
calls.map((call) => [call.command, call.args]),
|
||||||
|
[
|
||||||
|
['pnpm', ['dlx', 'npm-check-updates', '-u', '--deep', '--reject', 'fumadocs-core,fumadocs-ui']],
|
||||||
|
['uvx', ['dependency-check-updates', '--manifest', 'pyproject.toml', '-u']],
|
||||||
|
['uvx', ['dependency-check-updates', '--manifest', 'python/ktx-sl/pyproject.toml', '-u']],
|
||||||
|
],
|
||||||
|
);
|
||||||
|
assert.equal(logs.some((line) => line.includes('FAIL Python dependency constraints')), true);
|
||||||
|
assert.equal(logs.some((line) => line.includes('could not read pyproject.toml')), true);
|
||||||
|
assert.equal(logs.some((line) => line.includes('checking Python dependencies')), true);
|
||||||
|
assert.equal(
|
||||||
|
logs.some((line) => line.includes('Retry: uvx dependency-check-updates --manifest python/ktx-sl/pyproject.toml -u')),
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('runDependencyUpgrade ignores missing pnpm minimum release age config', async () => {
|
||||||
|
const calls = [];
|
||||||
|
|
||||||
|
const result = await runDependencyUpgrade({
|
||||||
|
rootDir: '/workspace/ktx',
|
||||||
|
readFile: async () => {
|
||||||
|
throw Object.assign(new Error('missing'), { code: 'ENOENT' });
|
||||||
|
},
|
||||||
|
execFile: async (command, args) => {
|
||||||
|
calls.push({ command, args });
|
||||||
|
return { stdout: '', stderr: '' };
|
||||||
|
},
|
||||||
|
log: () => undefined,
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.equal(result.ok, true);
|
||||||
|
assert.deepEqual(calls[0], {
|
||||||
|
command: 'pnpm',
|
||||||
|
args: ['dlx', 'npm-check-updates', '-u', '--deep', '--reject', 'fumadocs-core,fumadocs-ui'],
|
||||||
|
});
|
||||||
|
assert.equal(
|
||||||
|
calls
|
||||||
|
.filter((call) => call.command === 'uvx')
|
||||||
|
.every((call) => call.args.includes('--manifest') && !call.args.includes('-d')),
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('package scripts expose the full dependency upgrade command', async () => {
|
||||||
|
const packageJson = JSON.parse(await readFile(new URL('../package.json', import.meta.url), 'utf8'));
|
||||||
|
|
||||||
|
assert.equal(packageJson.scripts['deps:upgrade'], 'node scripts/upgrade-dependencies.mjs');
|
||||||
|
});
|
||||||
5
tombi.toml
Normal file
5
tombi.toml
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
[[schemas]]
|
||||||
|
path = "tombi://www.schemastore.org/pyproject.json"
|
||||||
|
include = ["**/pyproject.toml"]
|
||||||
|
format.rules.array-values-order.enabled = false
|
||||||
|
format.rules.table-keys-order.enabled = false
|
||||||
Loading…
Add table
Add a link
Reference in a new issue