@grunnverk/kodrdriv 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +12 -0
- package/.cursor/rules/no-local-dependencies.md +6 -0
- package/.gitignore~ +23 -0
- package/.kodrdriv-example-branch-targeting.yaml +71 -0
- package/BUG_TREE_PUBLISH_CONFIG_DIR.md +79 -0
- package/LICENSE +190 -0
- package/README.md +218 -0
- package/dist/application.js +228 -0
- package/dist/application.js.map +1 -0
- package/dist/arguments.js +1307 -0
- package/dist/arguments.js.map +1 -0
- package/dist/constants.js +255 -0
- package/dist/constants.js.map +1 -0
- package/dist/logging.js +176 -0
- package/dist/logging.js.map +1 -0
- package/dist/main.js +24 -0
- package/dist/main.js.map +1 -0
- package/dist/mcp/prompts/check_development.md +169 -0
- package/dist/mcp/prompts/dependency_update.md +62 -0
- package/dist/mcp/prompts/fix_and_commit.md +53 -0
- package/dist/mcp/prompts/publish.md +100 -0
- package/dist/mcp/prompts/tree_fix_and_commit.md +102 -0
- package/dist/mcp/prompts/tree_publish.md +118 -0
- package/dist/mcp-server.js +15601 -0
- package/dist/mcp-server.js.map +7 -0
- package/dist/types.js +303 -0
- package/dist/types.js.map +1 -0
- package/guide/ai-system.md +522 -0
- package/guide/architecture.md +349 -0
- package/guide/commands.md +383 -0
- package/guide/configuration.md +516 -0
- package/guide/debugging.md +587 -0
- package/guide/development.md +632 -0
- package/guide/index.md +224 -0
- package/guide/integration.md +510 -0
- package/guide/monorepo.md +533 -0
- package/guide/quickstart.md +249 -0
- package/guide/testing.md +463 -0
- package/guide/tree-operations.md +621 -0
- package/guide/usage.md +578 -0
- package/input/250509-kodrdriv-library-rules.m4a +0 -0
- package/package.json +105 -0
- package/packages/components/package.json +7 -0
- package/packages/tools/package.json +7 -0
- package/packages/utils/package.json +7 -0
- package/processed/250705-kodrdriv-confirm-editor-for-commit-and-release.m4a +0 -0
- package/processed/250705-kodrdriv-confirm-flag-release.m4a +0 -0
- package/processed/250705-kodrdriv-context-for-review.m4a +0 -0
- package/processed/250705-kodrdriv-feedback-on-publish-pipeline.m4a +0 -0
- package/processed/250705-kodrdriv-intelligent-eslint-style.m4a +0 -0
- package/processed/250705-kodrdriv-make-review-less-strict.m4a +0 -0
- package/processed/250705-kodrdriv-multilevel-transcription.m4a +0 -0
- package/processed/250705-kodrdriv-opinionated-review.m4a +0 -0
- package/processed/250705-kodrdriv-publish-next-version.m4a +0 -0
- package/processed/250705-kodrdriv-release-branches-and-milestones.m4a +0 -0
- package/processed/250705-kodrdriv-scope-check-fix-or-ignore.m4a +0 -0
- package/processed/250705-kodrdriv-scope-checker.m4a +0 -0
- package/processed/250705-kodrdriv-specify-a-release-note-for-publish.m4a +0 -0
- package/scripts/build-mcp.js +111 -0
- package/scripts/pre-commit-hook.sh +52 -0
- package/scripts/test-get-version-tool.js +102 -0
- package/scripts/test-mcp-compliance.js +254 -0
- package/scripts/update-test-log-assertions.js +73 -0
- package/temp-dist/arguments.js +817 -0
- package/temp-dist/constants.js +202 -0
- package/temp-dist/logging.js +130 -0
- package/temp-dist/types.js +112 -0
- package/temp-dist/util/stdin.js +132 -0
- package/temp-dist/util/storage.js +149 -0
- package/temp-dist/util/validation.js +110 -0
- package/test-external-unlink/package.json +16 -0
- package/test-externals/package.json +8 -0
- package/test-increment.js +0 -0
- package/test-multiline/cli/package.json +8 -0
- package/test-multiline/core/package.json +5 -0
- package/test-multiline/mobile/package.json +8 -0
- package/test-multiline/web/package.json +8 -0
- package/test-project/package-lock.json +21 -0
- package/test-project/package.json +1 -0
- package/test-review-flow.sh +15 -0
- package/test-sort-files/alpha.md +3 -0
- package/test-sort-files/middle.txt +3 -0
- package/test-sort-files/zebra.txt +3 -0
- package/test_output.txt +161 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
// eslint-disable-next-line no-restricted-imports
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import { glob } from 'glob';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import crypto from 'crypto';
|
|
6
|
+
export const create = (params) => {
|
|
7
|
+
// eslint-disable-next-line no-console
|
|
8
|
+
const log = params.log || console.log;
|
|
9
|
+
const exists = async (path) => {
|
|
10
|
+
try {
|
|
11
|
+
await fs.promises.stat(path);
|
|
12
|
+
return true;
|
|
13
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
const isDirectory = async (path) => {
|
|
20
|
+
const stats = await fs.promises.stat(path);
|
|
21
|
+
if (!stats.isDirectory()) {
|
|
22
|
+
// Log at debug level since this is expected when scanning directories
|
|
23
|
+
// that contain both files and directories
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
return true;
|
|
27
|
+
};
|
|
28
|
+
const isFile = async (path) => {
|
|
29
|
+
const stats = await fs.promises.stat(path);
|
|
30
|
+
if (!stats.isFile()) {
|
|
31
|
+
// Log removed since this is expected when checking file types
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
return true;
|
|
35
|
+
};
|
|
36
|
+
const isReadable = async (path) => {
|
|
37
|
+
try {
|
|
38
|
+
await fs.promises.access(path, fs.constants.R_OK);
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
log(`${path} is not readable: %s %s`, error.message, error.stack);
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
return true;
|
|
45
|
+
};
|
|
46
|
+
const isWritable = async (path) => {
|
|
47
|
+
try {
|
|
48
|
+
await fs.promises.access(path, fs.constants.W_OK);
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
log(`${path} is not writable: %s %s`, error.message, error.stack);
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
return true;
|
|
55
|
+
};
|
|
56
|
+
const isFileReadable = async (path) => {
|
|
57
|
+
return await exists(path) && await isFile(path) && await isReadable(path);
|
|
58
|
+
};
|
|
59
|
+
const isDirectoryWritable = async (path) => {
|
|
60
|
+
return await exists(path) && await isDirectory(path) && await isWritable(path);
|
|
61
|
+
};
|
|
62
|
+
const isDirectoryReadable = async (path) => {
|
|
63
|
+
return await exists(path) && await isDirectory(path) && await isReadable(path);
|
|
64
|
+
};
|
|
65
|
+
const createDirectory = async (path) => {
|
|
66
|
+
try {
|
|
67
|
+
await fs.promises.mkdir(path, { recursive: true });
|
|
68
|
+
}
|
|
69
|
+
catch (mkdirError) {
|
|
70
|
+
throw new Error(`Failed to create output directory ${path}: ${mkdirError.message} ${mkdirError.stack}`);
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
const ensureDirectory = async (path) => {
|
|
74
|
+
if (!(await exists(path))) {
|
|
75
|
+
await createDirectory(path);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
const removeDirectory = async (path) => {
|
|
79
|
+
try {
|
|
80
|
+
if (await exists(path)) {
|
|
81
|
+
await fs.promises.rm(path, { recursive: true, force: true });
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
catch (rmError) {
|
|
85
|
+
throw new Error(`Failed to remove directory ${path}: ${rmError.message} ${rmError.stack}`);
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
const readFile = async (path, encoding) => {
|
|
89
|
+
return await fs.promises.readFile(path, { encoding: encoding });
|
|
90
|
+
};
|
|
91
|
+
const writeFile = async (path, data, encoding) => {
|
|
92
|
+
await fs.promises.writeFile(path, data, { encoding: encoding });
|
|
93
|
+
};
|
|
94
|
+
const rename = async (oldPath, newPath) => {
|
|
95
|
+
await fs.promises.rename(oldPath, newPath);
|
|
96
|
+
};
|
|
97
|
+
const deleteFile = async (path) => {
|
|
98
|
+
try {
|
|
99
|
+
if (await exists(path)) {
|
|
100
|
+
await fs.promises.unlink(path);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
catch (deleteError) {
|
|
104
|
+
throw new Error(`Failed to delete file ${path}: ${deleteError.message} ${deleteError.stack}`);
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
const forEachFileIn = async (directory, callback, options = { pattern: '*.*' }) => {
|
|
108
|
+
try {
|
|
109
|
+
const files = await glob(options.pattern, { cwd: directory, nodir: true });
|
|
110
|
+
for (const file of files) {
|
|
111
|
+
await callback(path.join(directory, file));
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
catch (err) {
|
|
115
|
+
throw new Error(`Failed to glob pattern ${options.pattern} in ${directory}: ${err.message}`);
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
const readStream = async (path) => {
|
|
119
|
+
return fs.createReadStream(path);
|
|
120
|
+
};
|
|
121
|
+
const hashFile = async (path, length) => {
|
|
122
|
+
const file = await readFile(path, 'utf8');
|
|
123
|
+
return crypto.createHash('sha256').update(file).digest('hex').slice(0, length);
|
|
124
|
+
};
|
|
125
|
+
const listFiles = async (directory) => {
|
|
126
|
+
return await fs.promises.readdir(directory);
|
|
127
|
+
};
|
|
128
|
+
return {
|
|
129
|
+
exists,
|
|
130
|
+
isDirectory,
|
|
131
|
+
isFile,
|
|
132
|
+
isReadable,
|
|
133
|
+
isWritable,
|
|
134
|
+
isFileReadable,
|
|
135
|
+
isDirectoryWritable,
|
|
136
|
+
isDirectoryReadable,
|
|
137
|
+
createDirectory,
|
|
138
|
+
ensureDirectory,
|
|
139
|
+
readFile,
|
|
140
|
+
readStream,
|
|
141
|
+
writeFile,
|
|
142
|
+
rename,
|
|
143
|
+
deleteFile,
|
|
144
|
+
forEachFileIn,
|
|
145
|
+
hashFile,
|
|
146
|
+
listFiles,
|
|
147
|
+
removeDirectory,
|
|
148
|
+
};
|
|
149
|
+
};
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime validation utilities for safe type handling
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Validates and safely casts data to ReleaseSummary type
|
|
6
|
+
*/
|
|
7
|
+
export const validateReleaseSummary = (data) => {
|
|
8
|
+
if (!data || typeof data !== 'object') {
|
|
9
|
+
throw new Error('Invalid release summary: not an object');
|
|
10
|
+
}
|
|
11
|
+
if (typeof data.title !== 'string') {
|
|
12
|
+
throw new Error('Invalid release summary: title must be a string');
|
|
13
|
+
}
|
|
14
|
+
if (typeof data.body !== 'string') {
|
|
15
|
+
throw new Error('Invalid release summary: body must be a string');
|
|
16
|
+
}
|
|
17
|
+
return data;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Validates and safely casts data to LinkBackup type
|
|
21
|
+
*/
|
|
22
|
+
export const validateLinkBackup = (data) => {
|
|
23
|
+
if (!data || typeof data !== 'object') {
|
|
24
|
+
throw new Error('Invalid link backup: not an object');
|
|
25
|
+
}
|
|
26
|
+
// Validate each backup entry
|
|
27
|
+
for (const [key, value] of Object.entries(data)) {
|
|
28
|
+
if (!value || typeof value !== 'object') {
|
|
29
|
+
throw new Error(`Invalid link backup entry for ${key}: not an object`);
|
|
30
|
+
}
|
|
31
|
+
const entry = value;
|
|
32
|
+
if (typeof entry.originalVersion !== 'string') {
|
|
33
|
+
throw new Error(`Invalid link backup entry for ${key}: originalVersion must be a string`);
|
|
34
|
+
}
|
|
35
|
+
if (typeof entry.dependencyType !== 'string') {
|
|
36
|
+
throw new Error(`Invalid link backup entry for ${key}: dependencyType must be a string`);
|
|
37
|
+
}
|
|
38
|
+
if (typeof entry.relativePath !== 'string') {
|
|
39
|
+
throw new Error(`Invalid link backup entry for ${key}: relativePath must be a string`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return data;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Validates transcription result has required text property
|
|
46
|
+
*/
|
|
47
|
+
export const validateTranscriptionResult = (data) => {
|
|
48
|
+
if (!data || typeof data !== 'object') {
|
|
49
|
+
throw new Error('Invalid transcription result: not an object');
|
|
50
|
+
}
|
|
51
|
+
if (typeof data.text !== 'string') {
|
|
52
|
+
throw new Error('Invalid transcription result: text property must be a string');
|
|
53
|
+
}
|
|
54
|
+
return data;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Safely parses JSON with error handling
|
|
58
|
+
*/
|
|
59
|
+
export const safeJsonParse = (jsonString, context) => {
|
|
60
|
+
try {
|
|
61
|
+
const parsed = JSON.parse(jsonString);
|
|
62
|
+
if (parsed === null || parsed === undefined) {
|
|
63
|
+
throw new Error('Parsed JSON is null or undefined');
|
|
64
|
+
}
|
|
65
|
+
return parsed;
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
const contextStr = context ? ` (${context})` : '';
|
|
69
|
+
throw new Error(`Failed to parse JSON${contextStr}: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Validates that a value is a non-empty string
|
|
74
|
+
*/
|
|
75
|
+
export const validateString = (value, fieldName) => {
|
|
76
|
+
if (typeof value !== 'string') {
|
|
77
|
+
throw new Error(`${fieldName} must be a string, got ${typeof value}`);
|
|
78
|
+
}
|
|
79
|
+
if (value.trim() === '') {
|
|
80
|
+
throw new Error(`${fieldName} cannot be empty`);
|
|
81
|
+
}
|
|
82
|
+
return value;
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* Validates that a value exists and has a specific property
|
|
86
|
+
*/
|
|
87
|
+
export const validateHasProperty = (obj, property, context) => {
|
|
88
|
+
if (!obj || typeof obj !== 'object') {
|
|
89
|
+
const contextStr = context ? ` in ${context}` : '';
|
|
90
|
+
throw new Error(`Object is null or not an object${contextStr}`);
|
|
91
|
+
}
|
|
92
|
+
if (!(property in obj)) {
|
|
93
|
+
const contextStr = context ? ` in ${context}` : '';
|
|
94
|
+
throw new Error(`Missing required property '${property}'${contextStr}`);
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* Validates package.json structure has basic required fields
|
|
99
|
+
*/
|
|
100
|
+
export const validatePackageJson = (data, context, requireName = true) => {
|
|
101
|
+
if (!data || typeof data !== 'object') {
|
|
102
|
+
const contextStr = context ? ` (${context})` : '';
|
|
103
|
+
throw new Error(`Invalid package.json${contextStr}: not an object`);
|
|
104
|
+
}
|
|
105
|
+
if (requireName && typeof data.name !== 'string') {
|
|
106
|
+
const contextStr = context ? ` (${context})` : '';
|
|
107
|
+
throw new Error(`Invalid package.json${contextStr}: name must be a string`);
|
|
108
|
+
}
|
|
109
|
+
return data;
|
|
110
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@test/external-unlink-test",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Test package for external unlink patterns",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"dependencies": {
|
|
7
|
+
"@somelib/core": "^1.0.0",
|
|
8
|
+
"@somelib/utils": "^1.0.0",
|
|
9
|
+
"lodash": "^4.17.21",
|
|
10
|
+
"express": "^4.18.2"
|
|
11
|
+
},
|
|
12
|
+
"devDependencies": {
|
|
13
|
+
"@somelib/dev": "^1.0.0",
|
|
14
|
+
"jest": "^29.0.0"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "test-project",
|
|
3
|
+
"lockfileVersion": 3,
|
|
4
|
+
"requires": true,
|
|
5
|
+
"packages": {
|
|
6
|
+
"": {
|
|
7
|
+
"name": "test-project",
|
|
8
|
+
"dependencies": {
|
|
9
|
+
"@myorg/utils": "file:../packages/utils"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"../packages/utils": {
|
|
13
|
+
"name": "@myorg/utils",
|
|
14
|
+
"version": "1.2.3"
|
|
15
|
+
},
|
|
16
|
+
"node_modules/@myorg/utils": {
|
|
17
|
+
"resolved": "../packages/utils",
|
|
18
|
+
"link": true
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"name": "test-project", "dependencies": {"@myorg/utils": "file:../packages/utils"}}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
echo "Testing the new two-phase review flow..."
|
|
4
|
+
echo "This will test the file selection phase and then the analysis phase"
|
|
5
|
+
|
|
6
|
+
# Test with a single file in the test-project directory
|
|
7
|
+
echo "Test review note content" > test-project/test-review.md
|
|
8
|
+
|
|
9
|
+
echo "Running review command in test-project directory..."
|
|
10
|
+
echo "You should see:"
|
|
11
|
+
echo "1. File selection phase with c/s/a options"
|
|
12
|
+
echo "2. Analysis phase after files are selected"
|
|
13
|
+
|
|
14
|
+
cd test-project
|
|
15
|
+
../dist/main.js review --directory .
|
package/test_output.txt
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
|
|
2
|
+
> @grunnverk/kodrdriv@1.2.3-dev.0 test
|
|
3
|
+
> vitest run --coverage tests/commands/tree.test.ts
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
RUN v3.2.4 kodrdriv
|
|
7
|
+
Coverage enabled with v8
|
|
8
|
+
|
|
9
|
+
❯ tests/commands/tree.test.ts (60 tests | 6 failed) 57ms
|
|
10
|
+
✓ tree > execute > should handle empty directory with no package.json files 3ms
|
|
11
|
+
✓ tree > execute > should scan and build dependency graph for simple packages 1ms
|
|
12
|
+
✓ tree > execute > should handle circular dependencies 1ms
|
|
13
|
+
✓ tree > execute > should exclude packages based on patterns 1ms
|
|
14
|
+
✓ tree > execute > should start from specified package 1ms
|
|
15
|
+
✓ tree > execute > should throw error for invalid startFrom package 0ms
|
|
16
|
+
✓ tree > execute > should stop at specified package 0ms
|
|
17
|
+
✓ tree > execute > should stop at specified package with multiple dependencies 1ms
|
|
18
|
+
✓ tree > execute > should combine startFrom and stopAt options 0ms
|
|
19
|
+
✓ tree > execute > should throw error for invalid stopAt package 0ms
|
|
20
|
+
✓ tree > execute > should execute command in dry run mode 1ms
|
|
21
|
+
✓ tree > execute > should execute command in packages 1ms
|
|
22
|
+
✓ tree > execute > should handle command execution failure and provide recovery command 1ms
|
|
23
|
+
✓ tree > execute > should handle package.json without name field 1ms
|
|
24
|
+
✓ tree > execute > should handle invalid JSON in package.json 1ms
|
|
25
|
+
✓ tree > execute > should handle file system errors during scanning 0ms
|
|
26
|
+
✓ tree > execute > should use custom directories from config 0ms
|
|
27
|
+
✓ tree > execute > should return build order without executing command when no cmd provided 1ms
|
|
28
|
+
✓ tree > execute > should collect all dependency types 1ms
|
|
29
|
+
✓ tree > error formatting and handling > should format command errors with stderr and stdout 1ms
|
|
30
|
+
✓ tree > error formatting and handling > should format simple errors without stderr/stdout 1ms
|
|
31
|
+
✓ tree > error formatting and handling > should restore working directory after command failure 1ms
|
|
32
|
+
✓ tree > error formatting and handling > should handle packages with no version field 1ms
|
|
33
|
+
✓ tree > complex dependency scenarios > should handle deep dependency chains 1ms
|
|
34
|
+
✓ tree > complex dependency scenarios > should handle diamond dependency pattern 1ms
|
|
35
|
+
✓ tree > complex dependency scenarios > should handle multiple independent packages 1ms
|
|
36
|
+
✓ tree > complex dependency scenarios > should handle mixed dependency types 1ms
|
|
37
|
+
✓ tree > inter-project dependency updates for tree publish > should handle dry run for inter-project dependency updates 1ms
|
|
38
|
+
✓ tree > continue functionality and execution context > should handle missing execution context gracefully 1ms
|
|
39
|
+
× tree > continue functionality and execution context > should save execution context for publish commands 6ms
|
|
40
|
+
→ Failed to analyze workspace: Command failed in package package-a
|
|
41
|
+
× tree > continue functionality and execution context > should cleanup context on successful completion 1ms
|
|
42
|
+
→ Failed to analyze workspace: Command failed in package package-a
|
|
43
|
+
✓ tree > built-in command execution > should execute commit command across packages 1ms
|
|
44
|
+
✓ tree > built-in command execution > should execute link command with package argument 1ms
|
|
45
|
+
✓ tree > built-in command execution > should execute unlink command with clean-node-modules option 1ms
|
|
46
|
+
× tree > built-in command execution > should propagate global options to built-in commands 2ms
|
|
47
|
+
→ expected "spy" to be called at least once
|
|
48
|
+
✓ tree > built-in command execution > should handle link status subcommand 1ms
|
|
49
|
+
✓ tree > built-in command execution > should handle unlink status subcommand 1ms
|
|
50
|
+
✓ tree > built-in command execution > should throw error for unsupported built-in command 1ms
|
|
51
|
+
× tree > inter-project dependency updates > should update inter-project dependencies before publish 1ms
|
|
52
|
+
→ Failed to analyze workspace: Command failed in package package-a
|
|
53
|
+
× tree > inter-project dependency updates > should commit dependency updates before publish 1ms
|
|
54
|
+
→ Failed to analyze workspace: Command failed in package package-a
|
|
55
|
+
✓ tree > error handling edge cases > should handle working directory restoration failure 2ms
|
|
56
|
+
× tree > error handling edge cases > should handle storage errors during context operations 1ms
|
|
57
|
+
→ Failed to analyze workspace: Command failed in package package-a
|
|
58
|
+
✓ tree > error handling edge cases > should handle invalid execution context data 1ms
|
|
59
|
+
✓ tree > multiple directory scenarios > should handle empty directories gracefully 1ms
|
|
60
|
+
✓ tree > multiple directory scenarios > should handle mixed directory scenarios 1ms
|
|
61
|
+
✓ tree > exclusion pattern edge cases > should handle complex glob patterns 1ms
|
|
62
|
+
✓ tree > exclusion pattern edge cases > should handle exclusion patterns with special characters 1ms
|
|
63
|
+
✓ tree > package logger functionality > should create package-specific loggers with correct prefixes 1ms
|
|
64
|
+
✓ tree > package logger functionality > should handle dry run logging correctly 1ms
|
|
65
|
+
✓ tree > branches command advanced features > should handle packages with consumers and link problems 1ms
|
|
66
|
+
✓ tree > branches command advanced features > should handle ANSI color support detection 1ms
|
|
67
|
+
✓ tree > verbose and debug logging modes > should provide detailed logging in verbose mode 1ms
|
|
68
|
+
✓ tree > additional tree functionality > should handle exclusion patterns correctly 1ms
|
|
69
|
+
✓ tree > additional tree functionality > should handle multiple directories scanning 1ms
|
|
70
|
+
✓ tree > additional tree functionality > should show appropriate logging levels for command execution 1ms
|
|
71
|
+
✓ tree > branches command > should display branch status table for all packages 1ms
|
|
72
|
+
✓ tree > branches command > should handle git errors gracefully in branches command 1ms
|
|
73
|
+
✓ tree > branches command > should format table columns correctly with varying lengths 1ms
|
|
74
|
+
✓ tree > branches command > should not execute other commands when branches is specified 1ms
|
|
75
|
+
✓ tree > branches command > should display asterisk for packages with linked dependencies 1ms
|
|
76
|
+
|
|
77
|
+
⎯⎯⎯⎯⎯⎯⎯ Failed Tests 6 ⎯⎯⎯⎯⎯⎯⎯
|
|
78
|
+
|
|
79
|
+
FAIL tests/commands/tree.test.ts > tree > continue functionality and execution context > should save execution context for publish commands
|
|
80
|
+
Error: Failed to analyze workspace: Command failed in package package-a
|
|
81
|
+
❯ Module.execute src/commands/tree.ts:1648:15
|
|
82
|
+
1646| const errorMessage = `Failed to analyze workspace: ${error.mes…
|
|
83
|
+
1647| logger.error(errorMessage);
|
|
84
|
+
1648| throw new Error(errorMessage);
|
|
85
|
+
| ^
|
|
86
|
+
1649| } finally {
|
|
87
|
+
1650| // Clean up mutex resources to prevent memory leaks
|
|
88
|
+
❯ tests/commands/tree.test.ts:968:13
|
|
89
|
+
|
|
90
|
+
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/6]⎯
|
|
91
|
+
|
|
92
|
+
FAIL tests/commands/tree.test.ts > tree > continue functionality and execution context > should cleanup context on successful completion
|
|
93
|
+
Error: Failed to analyze workspace: Command failed in package package-a
|
|
94
|
+
❯ Module.execute src/commands/tree.ts:1648:15
|
|
95
|
+
1646| const errorMessage = `Failed to analyze workspace: ${error.mes…
|
|
96
|
+
1647| logger.error(errorMessage);
|
|
97
|
+
1648| throw new Error(errorMessage);
|
|
98
|
+
| ^
|
|
99
|
+
1649| } finally {
|
|
100
|
+
1650| // Clean up mutex resources to prevent memory leaks
|
|
101
|
+
❯ tests/commands/tree.test.ts:993:13
|
|
102
|
+
|
|
103
|
+
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/6]⎯
|
|
104
|
+
|
|
105
|
+
FAIL tests/commands/tree.test.ts > tree > built-in command execution > should propagate global options to built-in commands
|
|
106
|
+
AssertionError: expected "spy" to be called at least once
|
|
107
|
+
❯ tests/commands/tree.test.ts:1105:37
|
|
108
|
+
1103|
|
|
109
|
+
1104| // Verify the command was executed (basic check)
|
|
110
|
+
1105| expect(mockExecPromise).toHaveBeenCalled();
|
|
111
|
+
| ^
|
|
112
|
+
1106| });
|
|
113
|
+
1107|
|
|
114
|
+
|
|
115
|
+
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/6]⎯
|
|
116
|
+
|
|
117
|
+
FAIL tests/commands/tree.test.ts > tree > inter-project dependency updates > should update inter-project dependencies before publish
|
|
118
|
+
Error: Failed to analyze workspace: Command failed in package package-a
|
|
119
|
+
❯ Module.execute src/commands/tree.ts:1648:15
|
|
120
|
+
1646| const errorMessage = `Failed to analyze workspace: ${error.mes…
|
|
121
|
+
1647| logger.error(errorMessage);
|
|
122
|
+
1648| throw new Error(errorMessage);
|
|
123
|
+
| ^
|
|
124
|
+
1649| } finally {
|
|
125
|
+
1650| // Clean up mutex resources to prevent memory leaks
|
|
126
|
+
❯ tests/commands/tree.test.ts:1186:13
|
|
127
|
+
|
|
128
|
+
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[4/6]⎯
|
|
129
|
+
|
|
130
|
+
FAIL tests/commands/tree.test.ts > tree > inter-project dependency updates > should commit dependency updates before publish
|
|
131
|
+
Error: Failed to analyze workspace: Command failed in package package-a
|
|
132
|
+
❯ Module.execute src/commands/tree.ts:1648:15
|
|
133
|
+
1646| const errorMessage = `Failed to analyze workspace: ${error.mes…
|
|
134
|
+
1647| logger.error(errorMessage);
|
|
135
|
+
1648| throw new Error(errorMessage);
|
|
136
|
+
| ^
|
|
137
|
+
1649| } finally {
|
|
138
|
+
1650| // Clean up mutex resources to prevent memory leaks
|
|
139
|
+
❯ tests/commands/tree.test.ts:1206:13
|
|
140
|
+
|
|
141
|
+
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[5/6]⎯
|
|
142
|
+
|
|
143
|
+
FAIL tests/commands/tree.test.ts > tree > error handling edge cases > should handle storage errors during context operations
|
|
144
|
+
Error: Failed to analyze workspace: Command failed in package package-a
|
|
145
|
+
❯ Module.execute src/commands/tree.ts:1648:15
|
|
146
|
+
1646| const errorMessage = `Failed to analyze workspace: ${error.mes…
|
|
147
|
+
1647| logger.error(errorMessage);
|
|
148
|
+
1648| throw new Error(errorMessage);
|
|
149
|
+
| ^
|
|
150
|
+
1649| } finally {
|
|
151
|
+
1650| // Clean up mutex resources to prevent memory leaks
|
|
152
|
+
❯ tests/commands/tree.test.ts:1253:13
|
|
153
|
+
|
|
154
|
+
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[6/6]⎯
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
Test Files 1 failed (1)
|
|
158
|
+
Tests 6 failed | 54 passed (60)
|
|
159
|
+
Start at 10:00:29
|
|
160
|
+
Duration 500ms (transform 80ms, setup 0ms, collect 97ms, tests 57ms, environment 0ms, prepare 35ms)
|
|
161
|
+
|