@camaradesuk/git-worktree-tools 1.6.0 → 1.7.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/README.md +307 -418
- package/dist/cli/cleanpr.test.js +2 -0
- package/dist/cli/cleanpr.test.js.map +1 -1
- package/dist/cli/newpr.js +48 -11
- package/dist/cli/newpr.js.map +1 -1
- package/dist/cli/newpr.test.js +33 -15
- package/dist/cli/newpr.test.js.map +1 -1
- package/dist/cli/wt/clean.d.ts +1 -0
- package/dist/cli/wt/clean.d.ts.map +1 -1
- package/dist/cli/wt/clean.js +11 -1
- package/dist/cli/wt/clean.js.map +1 -1
- package/dist/cli/wt/config.d.ts +1 -1
- package/dist/cli/wt/config.d.ts.map +1 -1
- package/dist/cli/wt/config.js +148 -13
- package/dist/cli/wt/config.js.map +1 -1
- package/dist/cli/wt/config.test.d.ts +5 -0
- package/dist/cli/wt/config.test.d.ts.map +1 -0
- package/dist/cli/wt/config.test.js +260 -0
- package/dist/cli/wt/config.test.js.map +1 -0
- package/dist/cli/wt/entry.test.js +11 -8
- package/dist/cli/wt/entry.test.js.map +1 -1
- package/dist/cli/wt/init.d.ts +14 -0
- package/dist/cli/wt/init.d.ts.map +1 -0
- package/dist/cli/wt/init.js +209 -0
- package/dist/cli/wt/init.js.map +1 -0
- package/dist/cli/wt/init.test.d.ts +5 -0
- package/dist/cli/wt/init.test.d.ts.map +1 -0
- package/dist/cli/wt/init.test.js +165 -0
- package/dist/cli/wt/init.test.js.map +1 -0
- package/dist/cli/wt/init.unit.test.d.ts +5 -0
- package/dist/cli/wt/init.unit.test.d.ts.map +1 -0
- package/dist/cli/wt/init.unit.test.js +432 -0
- package/dist/cli/wt/init.unit.test.js.map +1 -0
- package/dist/cli/wt/interactive-menu.d.ts +41 -0
- package/dist/cli/wt/interactive-menu.d.ts.map +1 -0
- package/dist/cli/wt/interactive-menu.js +639 -0
- package/dist/cli/wt/interactive-menu.js.map +1 -0
- package/dist/cli/wt/interactive-menu.test.d.ts +10 -0
- package/dist/cli/wt/interactive-menu.test.d.ts.map +1 -0
- package/dist/cli/wt/interactive-menu.test.js +711 -0
- package/dist/cli/wt/interactive-menu.test.js.map +1 -0
- package/dist/cli/wt/link.d.ts +9 -0
- package/dist/cli/wt/link.d.ts.map +1 -1
- package/dist/cli/wt/link.js +27 -0
- package/dist/cli/wt/link.js.map +1 -1
- package/dist/cli/wt/list.d.ts +2 -2
- package/dist/cli/wt/list.d.ts.map +1 -1
- package/dist/cli/wt/list.js +17 -17
- package/dist/cli/wt/list.js.map +1 -1
- package/dist/cli/wt/new.d.ts +7 -1
- package/dist/cli/wt/new.d.ts.map +1 -1
- package/dist/cli/wt/new.js +58 -6
- package/dist/cli/wt/new.js.map +1 -1
- package/dist/cli/wt/wt.test.js +159 -16
- package/dist/cli/wt/wt.test.js.map +1 -1
- package/dist/cli/wt.d.ts +2 -1
- package/dist/cli/wt.d.ts.map +1 -1
- package/dist/cli/wt.js +98 -3
- package/dist/cli/wt.js.map +1 -1
- package/dist/cli/wt.unit.test.d.ts +7 -0
- package/dist/cli/wt.unit.test.d.ts.map +1 -0
- package/dist/cli/wt.unit.test.js +182 -0
- package/dist/cli/wt.unit.test.js.map +1 -0
- package/dist/cli/wtconfig.js +18 -4
- package/dist/cli/wtconfig.js.map +1 -1
- package/dist/cli/wtconfig.test.js +18 -16
- package/dist/cli/wtconfig.test.js.map +1 -1
- package/dist/e2e/newpr/scenarios.e2e.test.js +7 -7
- package/dist/e2e/newpr/scenarios.e2e.test.js.map +1 -1
- package/dist/e2e/wt/wt.e2e.test.d.ts +9 -0
- package/dist/e2e/wt/wt.e2e.test.d.ts.map +1 -0
- package/dist/e2e/wt/wt.e2e.test.js +384 -0
- package/dist/e2e/wt/wt.e2e.test.js.map +1 -0
- package/dist/lib/ai/base-provider.d.ts +22 -0
- package/dist/lib/ai/base-provider.d.ts.map +1 -1
- package/dist/lib/ai/base-provider.js +180 -99
- package/dist/lib/ai/base-provider.js.map +1 -1
- package/dist/lib/ai/base-provider.test.js +13 -14
- package/dist/lib/ai/base-provider.test.js.map +1 -1
- package/dist/lib/ai/cli-provider.d.ts +11 -7
- package/dist/lib/ai/cli-provider.d.ts.map +1 -1
- package/dist/lib/ai/cli-provider.js +19 -49
- package/dist/lib/ai/cli-provider.js.map +1 -1
- package/dist/lib/ai/cli-provider.test.js +47 -49
- package/dist/lib/ai/cli-provider.test.js.map +1 -1
- package/dist/lib/ai/index.d.ts +2 -1
- package/dist/lib/ai/index.d.ts.map +1 -1
- package/dist/lib/ai/index.js +2 -0
- package/dist/lib/ai/index.js.map +1 -1
- package/dist/lib/ai/provider-manager.js +2 -2
- package/dist/lib/ai/provider-manager.js.map +1 -1
- package/dist/lib/ai/repo-docs.d.ts +43 -0
- package/dist/lib/ai/repo-docs.d.ts.map +1 -0
- package/dist/lib/ai/repo-docs.js +274 -0
- package/dist/lib/ai/repo-docs.js.map +1 -0
- package/dist/lib/ai/repo-docs.test.d.ts +5 -0
- package/dist/lib/ai/repo-docs.test.d.ts.map +1 -0
- package/dist/lib/ai/repo-docs.test.js +357 -0
- package/dist/lib/ai/repo-docs.test.js.map +1 -0
- package/dist/lib/ai/types.d.ts +18 -2
- package/dist/lib/ai/types.d.ts.map +1 -1
- package/dist/lib/ai/types.js.map +1 -1
- package/dist/lib/config-editor.d.ts +21 -0
- package/dist/lib/config-editor.d.ts.map +1 -0
- package/dist/lib/config-editor.js +729 -0
- package/dist/lib/config-editor.js.map +1 -0
- package/dist/lib/config-editor.test.d.ts +11 -0
- package/dist/lib/config-editor.test.d.ts.map +1 -0
- package/dist/lib/config-editor.test.js +526 -0
- package/dist/lib/config-editor.test.js.map +1 -0
- package/dist/lib/config-validation.d.ts +28 -0
- package/dist/lib/config-validation.d.ts.map +1 -0
- package/dist/lib/config-validation.js +534 -0
- package/dist/lib/config-validation.js.map +1 -0
- package/dist/lib/config-validation.test.d.ts +5 -0
- package/dist/lib/config-validation.test.d.ts.map +1 -0
- package/dist/lib/config-validation.test.js +398 -0
- package/dist/lib/config-validation.test.js.map +1 -0
- package/dist/lib/config.d.ts +115 -6
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +251 -55
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/config.test.js +2 -1
- package/dist/lib/config.test.js.map +1 -1
- package/dist/lib/constants.d.ts +50 -1
- package/dist/lib/constants.d.ts.map +1 -1
- package/dist/lib/constants.js +67 -1
- package/dist/lib/constants.js.map +1 -1
- package/dist/lib/constants.test.d.ts +5 -0
- package/dist/lib/constants.test.d.ts.map +1 -0
- package/dist/lib/constants.test.js +121 -0
- package/dist/lib/constants.test.js.map +1 -0
- package/dist/lib/git.d.ts +12 -0
- package/dist/lib/git.d.ts.map +1 -1
- package/dist/lib/git.js +26 -0
- package/dist/lib/git.js.map +1 -1
- package/dist/lib/global-check.d.ts +38 -0
- package/dist/lib/global-check.d.ts.map +1 -0
- package/dist/lib/global-check.js +135 -0
- package/dist/lib/global-check.js.map +1 -0
- package/dist/lib/global-check.test.d.ts +5 -0
- package/dist/lib/global-check.test.d.ts.map +1 -0
- package/dist/lib/global-check.test.js +153 -0
- package/dist/lib/global-check.test.js.map +1 -0
- package/dist/lib/global-config.d.ts +102 -0
- package/dist/lib/global-config.d.ts.map +1 -0
- package/dist/lib/global-config.js +234 -0
- package/dist/lib/global-config.js.map +1 -0
- package/dist/lib/global-config.test.d.ts +5 -0
- package/dist/lib/global-config.test.d.ts.map +1 -0
- package/dist/lib/global-config.test.js +282 -0
- package/dist/lib/global-config.test.js.map +1 -0
- package/dist/lib/logger.d.ts +175 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +475 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/logger.test.d.ts +5 -0
- package/dist/lib/logger.test.d.ts.map +1 -0
- package/dist/lib/logger.test.js +292 -0
- package/dist/lib/logger.test.js.map +1 -0
- package/dist/lib/lswt/action-executors.test.js +2 -0
- package/dist/lib/lswt/action-executors.test.js.map +1 -1
- package/dist/lib/newpr/args.d.ts.map +1 -1
- package/dist/lib/newpr/args.js +9 -2
- package/dist/lib/newpr/args.js.map +1 -1
- package/dist/lib/newpr/args.test.js +1 -1
- package/dist/lib/newpr/args.test.js.map +1 -1
- package/dist/lib/newpr/types.d.ts +2 -0
- package/dist/lib/newpr/types.d.ts.map +1 -1
- package/dist/lib/prompts.d.ts +6 -0
- package/dist/lib/prompts.d.ts.map +1 -1
- package/dist/lib/prompts.js +31 -9
- package/dist/lib/prompts.js.map +1 -1
- package/dist/lib/prompts.test.js +72 -1
- package/dist/lib/prompts.test.js.map +1 -1
- package/dist/lib/schema.test.d.ts +10 -0
- package/dist/lib/schema.test.d.ts.map +1 -0
- package/dist/lib/schema.test.js +309 -0
- package/dist/lib/schema.test.js.map +1 -0
- package/dist/lib/wtconfig/environment.d.ts.map +1 -1
- package/dist/lib/wtconfig/environment.js +6 -4
- package/dist/lib/wtconfig/environment.js.map +1 -1
- package/dist/lib/wtconfig/environment.test.js +2 -7
- package/dist/lib/wtconfig/environment.test.js.map +1 -1
- package/dist/lib/wtconfig/types.d.ts +3 -1
- package/dist/lib/wtconfig/types.d.ts.map +1 -1
- package/dist/lib/wtlink/manage-manifest.test.js +145 -7
- package/dist/lib/wtlink/manage-manifest.test.js.map +1 -1
- package/package.json +2 -1
- package/schemas/worktreerc.schema.json +416 -0
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for global-config.ts
|
|
3
|
+
*/
|
|
4
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
5
|
+
import fs from 'fs';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import os from 'os';
|
|
8
|
+
import { getGlobalConfigPath, findRepoConfigFile, findLocalConfigFile, getConfigPaths, loadConfigFile, createLocalConfig, ensureLocalConfigInGitignore, initializeLocalConfig, getSchemaUrl, localConfigExists, repoConfigExists, getConfigSummary, } from './global-config.js';
|
|
9
|
+
import { CONFIG_FILE_NAMES, LOCAL_CONFIG_FILE_NAMES } from './constants.js';
|
|
10
|
+
// Mock logger to avoid console output
|
|
11
|
+
vi.mock('./logger.js', () => ({
|
|
12
|
+
logger: {
|
|
13
|
+
debug: vi.fn(),
|
|
14
|
+
info: vi.fn(),
|
|
15
|
+
warn: vi.fn(),
|
|
16
|
+
error: vi.fn(),
|
|
17
|
+
},
|
|
18
|
+
}));
|
|
19
|
+
describe('global-config', () => {
|
|
20
|
+
let tempDir;
|
|
21
|
+
let repoDir;
|
|
22
|
+
beforeEach(() => {
|
|
23
|
+
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'global-config-test-'));
|
|
24
|
+
repoDir = path.join(tempDir, 'repo');
|
|
25
|
+
fs.mkdirSync(repoDir);
|
|
26
|
+
});
|
|
27
|
+
afterEach(() => {
|
|
28
|
+
if (tempDir && fs.existsSync(tempDir)) {
|
|
29
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
describe('getGlobalConfigPath', () => {
|
|
33
|
+
it('returns a path containing config.json', () => {
|
|
34
|
+
const configPath = getGlobalConfigPath();
|
|
35
|
+
expect(configPath).toContain('config.json');
|
|
36
|
+
});
|
|
37
|
+
it('returns path in appropriate config directory', () => {
|
|
38
|
+
const configPath = getGlobalConfigPath();
|
|
39
|
+
// Should be in XDG or home directory location
|
|
40
|
+
expect(configPath).toMatch(/git-worktree-tools/);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
describe('findRepoConfigFile', () => {
|
|
44
|
+
it('finds .worktreerc when it exists', () => {
|
|
45
|
+
const configPath = path.join(repoDir, '.worktreerc');
|
|
46
|
+
fs.writeFileSync(configPath, '{}');
|
|
47
|
+
const found = findRepoConfigFile(repoDir);
|
|
48
|
+
expect(found).toBe(configPath);
|
|
49
|
+
});
|
|
50
|
+
it('finds .worktreerc.json when it exists', () => {
|
|
51
|
+
const configPath = path.join(repoDir, '.worktreerc.json');
|
|
52
|
+
fs.writeFileSync(configPath, '{}');
|
|
53
|
+
const found = findRepoConfigFile(repoDir);
|
|
54
|
+
expect(found).toBe(configPath);
|
|
55
|
+
});
|
|
56
|
+
it('prefers .worktreerc over .worktreerc.json', () => {
|
|
57
|
+
fs.writeFileSync(path.join(repoDir, '.worktreerc'), '{}');
|
|
58
|
+
fs.writeFileSync(path.join(repoDir, '.worktreerc.json'), '{}');
|
|
59
|
+
const found = findRepoConfigFile(repoDir);
|
|
60
|
+
expect(found).toBe(path.join(repoDir, CONFIG_FILE_NAMES[0]));
|
|
61
|
+
});
|
|
62
|
+
it('returns null when no config exists', () => {
|
|
63
|
+
const found = findRepoConfigFile(repoDir);
|
|
64
|
+
expect(found).toBeNull();
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
describe('findLocalConfigFile', () => {
|
|
68
|
+
it('finds .worktreerc.local when it exists', () => {
|
|
69
|
+
const configPath = path.join(repoDir, '.worktreerc.local');
|
|
70
|
+
fs.writeFileSync(configPath, '{}');
|
|
71
|
+
const found = findLocalConfigFile(repoDir);
|
|
72
|
+
expect(found).toBe(configPath);
|
|
73
|
+
});
|
|
74
|
+
it('finds .worktreerc.local.json when it exists', () => {
|
|
75
|
+
const configPath = path.join(repoDir, '.worktreerc.local.json');
|
|
76
|
+
fs.writeFileSync(configPath, '{}');
|
|
77
|
+
const found = findLocalConfigFile(repoDir);
|
|
78
|
+
expect(found).toBe(configPath);
|
|
79
|
+
});
|
|
80
|
+
it('returns null when no local config exists', () => {
|
|
81
|
+
const found = findLocalConfigFile(repoDir);
|
|
82
|
+
expect(found).toBeNull();
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
describe('getConfigPaths', () => {
|
|
86
|
+
it('returns global config path', () => {
|
|
87
|
+
const paths = getConfigPaths();
|
|
88
|
+
expect(paths.global).toBeDefined();
|
|
89
|
+
expect(paths.global.level).toBe('global');
|
|
90
|
+
});
|
|
91
|
+
it('returns null repo/local when no repoRoot provided', () => {
|
|
92
|
+
const paths = getConfigPaths();
|
|
93
|
+
expect(paths.repo).toBeNull();
|
|
94
|
+
expect(paths.local).toBeNull();
|
|
95
|
+
});
|
|
96
|
+
it('returns repo config path when repoRoot provided', () => {
|
|
97
|
+
const paths = getConfigPaths(repoDir);
|
|
98
|
+
expect(paths.repo).toBeDefined();
|
|
99
|
+
expect(paths.repo?.level).toBe('repo');
|
|
100
|
+
});
|
|
101
|
+
it('returns local config path when repoRoot provided', () => {
|
|
102
|
+
const paths = getConfigPaths(repoDir);
|
|
103
|
+
expect(paths.local).toBeDefined();
|
|
104
|
+
expect(paths.local?.level).toBe('local');
|
|
105
|
+
});
|
|
106
|
+
it('marks existing files as exists: true', () => {
|
|
107
|
+
fs.writeFileSync(path.join(repoDir, '.worktreerc'), '{}');
|
|
108
|
+
fs.writeFileSync(path.join(repoDir, '.worktreerc.local'), '{}');
|
|
109
|
+
const paths = getConfigPaths(repoDir);
|
|
110
|
+
expect(paths.repo?.exists).toBe(true);
|
|
111
|
+
expect(paths.local?.exists).toBe(true);
|
|
112
|
+
});
|
|
113
|
+
it('marks non-existing files as exists: false', () => {
|
|
114
|
+
const paths = getConfigPaths(repoDir);
|
|
115
|
+
expect(paths.repo?.exists).toBe(false);
|
|
116
|
+
expect(paths.local?.exists).toBe(false);
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
describe('loadConfigFile', () => {
|
|
120
|
+
it('loads valid JSON config', () => {
|
|
121
|
+
const configPath = path.join(repoDir, 'config.json');
|
|
122
|
+
fs.writeFileSync(configPath, JSON.stringify({ baseBranch: 'develop' }));
|
|
123
|
+
const config = loadConfigFile(configPath);
|
|
124
|
+
expect(config).toEqual({ baseBranch: 'develop' });
|
|
125
|
+
});
|
|
126
|
+
it('returns null for non-existent file', () => {
|
|
127
|
+
const config = loadConfigFile('/non/existent/file.json');
|
|
128
|
+
expect(config).toBeNull();
|
|
129
|
+
});
|
|
130
|
+
it('returns null for invalid JSON', () => {
|
|
131
|
+
const configPath = path.join(repoDir, 'invalid.json');
|
|
132
|
+
fs.writeFileSync(configPath, 'not valid json');
|
|
133
|
+
const config = loadConfigFile(configPath);
|
|
134
|
+
expect(config).toBeNull();
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
describe('saveGlobalConfig', () => {
|
|
138
|
+
it('creates config directory if needed', () => {
|
|
139
|
+
const customConfigDir = path.join(tempDir, 'custom-config');
|
|
140
|
+
const customConfigPath = path.join(customConfigDir, 'config.json');
|
|
141
|
+
// Mock getGlobalConfigPath
|
|
142
|
+
vi.doMock('./constants.js', async (importOriginal) => {
|
|
143
|
+
const original = await importOriginal();
|
|
144
|
+
return {
|
|
145
|
+
...original,
|
|
146
|
+
getGlobalConfigDir: () => customConfigDir,
|
|
147
|
+
};
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
it('includes $schema in saved config', () => {
|
|
151
|
+
const testConfigPath = path.join(repoDir, 'test-config.json');
|
|
152
|
+
// Create a simple test by checking what would be saved
|
|
153
|
+
const config = { baseBranch: 'main' };
|
|
154
|
+
const configWithSchema = {
|
|
155
|
+
$schema: getSchemaUrl(),
|
|
156
|
+
...config,
|
|
157
|
+
};
|
|
158
|
+
expect(configWithSchema.$schema).toContain('unpkg.com');
|
|
159
|
+
expect(configWithSchema.$schema).toContain('worktreerc.schema.json');
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
describe('createLocalConfig', () => {
|
|
163
|
+
it('creates local config file', () => {
|
|
164
|
+
const configPath = createLocalConfig(repoDir);
|
|
165
|
+
expect(fs.existsSync(configPath)).toBe(true);
|
|
166
|
+
});
|
|
167
|
+
it('creates config with provided values', () => {
|
|
168
|
+
const configPath = createLocalConfig(repoDir, { baseBranch: 'develop' });
|
|
169
|
+
const content = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
170
|
+
expect(content.baseBranch).toBe('develop');
|
|
171
|
+
});
|
|
172
|
+
it('includes $schema in created config', () => {
|
|
173
|
+
const configPath = createLocalConfig(repoDir);
|
|
174
|
+
const content = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
175
|
+
expect(content.$schema).toContain('unpkg.com');
|
|
176
|
+
});
|
|
177
|
+
it('creates .worktreerc.local file', () => {
|
|
178
|
+
const configPath = createLocalConfig(repoDir);
|
|
179
|
+
expect(path.basename(configPath)).toBe(LOCAL_CONFIG_FILE_NAMES[0]);
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
describe('ensureLocalConfigInGitignore', () => {
|
|
183
|
+
it('creates .gitignore if it does not exist', () => {
|
|
184
|
+
const gitignorePath = path.join(repoDir, '.gitignore');
|
|
185
|
+
expect(fs.existsSync(gitignorePath)).toBe(false);
|
|
186
|
+
ensureLocalConfigInGitignore(repoDir);
|
|
187
|
+
expect(fs.existsSync(gitignorePath)).toBe(true);
|
|
188
|
+
});
|
|
189
|
+
it('adds local config patterns to .gitignore', () => {
|
|
190
|
+
const gitignorePath = path.join(repoDir, '.gitignore');
|
|
191
|
+
ensureLocalConfigInGitignore(repoDir);
|
|
192
|
+
const content = fs.readFileSync(gitignorePath, 'utf8');
|
|
193
|
+
expect(content).toContain('.worktreerc.local');
|
|
194
|
+
});
|
|
195
|
+
it('does not duplicate patterns if already present', () => {
|
|
196
|
+
const gitignorePath = path.join(repoDir, '.gitignore');
|
|
197
|
+
// Include both local config patterns
|
|
198
|
+
fs.writeFileSync(gitignorePath, '.worktreerc.local\n.worktreerc.local.json\n');
|
|
199
|
+
const updated = ensureLocalConfigInGitignore(repoDir);
|
|
200
|
+
expect(updated).toBe(false);
|
|
201
|
+
const content = fs.readFileSync(gitignorePath, 'utf8');
|
|
202
|
+
const matches = content.match(/\.worktreerc\.local/g) || [];
|
|
203
|
+
expect(matches.length).toBe(2); // Both patterns present once
|
|
204
|
+
});
|
|
205
|
+
it('preserves existing .gitignore content', () => {
|
|
206
|
+
const gitignorePath = path.join(repoDir, '.gitignore');
|
|
207
|
+
fs.writeFileSync(gitignorePath, 'node_modules/\n*.log\n');
|
|
208
|
+
ensureLocalConfigInGitignore(repoDir);
|
|
209
|
+
const content = fs.readFileSync(gitignorePath, 'utf8');
|
|
210
|
+
expect(content).toContain('node_modules/');
|
|
211
|
+
expect(content).toContain('*.log');
|
|
212
|
+
});
|
|
213
|
+
it('returns true when patterns are added', () => {
|
|
214
|
+
const updated = ensureLocalConfigInGitignore(repoDir);
|
|
215
|
+
expect(updated).toBe(true);
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
describe('initializeLocalConfig', () => {
|
|
219
|
+
it('creates config and updates gitignore', () => {
|
|
220
|
+
const result = initializeLocalConfig(repoDir);
|
|
221
|
+
expect(fs.existsSync(result.configPath)).toBe(true);
|
|
222
|
+
expect(result.gitignoreUpdated).toBe(true);
|
|
223
|
+
});
|
|
224
|
+
it('passes initial config to createLocalConfig', () => {
|
|
225
|
+
const result = initializeLocalConfig(repoDir, {
|
|
226
|
+
logging: { level: 'debug' },
|
|
227
|
+
});
|
|
228
|
+
const content = JSON.parse(fs.readFileSync(result.configPath, 'utf8'));
|
|
229
|
+
expect(content.logging.level).toBe('debug');
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
describe('getSchemaUrl', () => {
|
|
233
|
+
it('returns unpkg URL', () => {
|
|
234
|
+
const url = getSchemaUrl();
|
|
235
|
+
expect(url).toContain('unpkg.com');
|
|
236
|
+
expect(url).toContain('@camaradesuk/git-worktree-tools');
|
|
237
|
+
expect(url).toContain('worktreerc.schema.json');
|
|
238
|
+
});
|
|
239
|
+
});
|
|
240
|
+
describe('existence checks', () => {
|
|
241
|
+
describe('localConfigExists', () => {
|
|
242
|
+
it('returns true when local config exists', () => {
|
|
243
|
+
fs.writeFileSync(path.join(repoDir, '.worktreerc.local'), '{}');
|
|
244
|
+
expect(localConfigExists(repoDir)).toBe(true);
|
|
245
|
+
});
|
|
246
|
+
it('returns false when local config does not exist', () => {
|
|
247
|
+
expect(localConfigExists(repoDir)).toBe(false);
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
describe('repoConfigExists', () => {
|
|
251
|
+
it('returns true when repo config exists', () => {
|
|
252
|
+
fs.writeFileSync(path.join(repoDir, '.worktreerc'), '{}');
|
|
253
|
+
expect(repoConfigExists(repoDir)).toBe(true);
|
|
254
|
+
});
|
|
255
|
+
it('returns false when repo config does not exist', () => {
|
|
256
|
+
expect(repoConfigExists(repoDir)).toBe(false);
|
|
257
|
+
});
|
|
258
|
+
});
|
|
259
|
+
});
|
|
260
|
+
describe('getConfigSummary', () => {
|
|
261
|
+
it('returns summary without repoRoot', () => {
|
|
262
|
+
const summary = getConfigSummary();
|
|
263
|
+
expect(summary).toHaveProperty('global');
|
|
264
|
+
expect(summary).toHaveProperty('repo');
|
|
265
|
+
expect(summary).toHaveProperty('local');
|
|
266
|
+
expect(summary).toHaveProperty('paths');
|
|
267
|
+
});
|
|
268
|
+
it('returns summary with repoRoot', () => {
|
|
269
|
+
fs.writeFileSync(path.join(repoDir, '.worktreerc'), '{}');
|
|
270
|
+
fs.writeFileSync(path.join(repoDir, '.worktreerc.local'), '{}');
|
|
271
|
+
const summary = getConfigSummary(repoDir);
|
|
272
|
+
expect(summary.repo).toBe(true);
|
|
273
|
+
expect(summary.local).toBe(true);
|
|
274
|
+
});
|
|
275
|
+
it('returns false for non-existing configs', () => {
|
|
276
|
+
const summary = getConfigSummary(repoDir);
|
|
277
|
+
expect(summary.repo).toBe(false);
|
|
278
|
+
expect(summary.local).toBe(false);
|
|
279
|
+
});
|
|
280
|
+
});
|
|
281
|
+
});
|
|
282
|
+
//# sourceMappingURL=global-config.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"global-config.test.js","sourceRoot":"","sources":["../../src/lib/global-config.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logging system for git-worktree-tools
|
|
3
|
+
*
|
|
4
|
+
* Provides a singleton logger with:
|
|
5
|
+
* - Multiple log levels (silent, error, warn, info, debug, trace)
|
|
6
|
+
* - Console and file output support
|
|
7
|
+
* - Log file rotation
|
|
8
|
+
* - Timestamps and context
|
|
9
|
+
* - Color support for console output
|
|
10
|
+
*
|
|
11
|
+
* Configuration sources (in order of priority):
|
|
12
|
+
* 1. CLI flags (--verbose, --debug, --log-file)
|
|
13
|
+
* 2. Environment variables (GWT_LOG_LEVEL, GWT_LOG_FILE)
|
|
14
|
+
* 3. Config files (logLevel, logFile properties)
|
|
15
|
+
*/
|
|
16
|
+
import { LogLevel } from './constants.js';
|
|
17
|
+
export { LogLevel };
|
|
18
|
+
/**
|
|
19
|
+
* Logger configuration options
|
|
20
|
+
*/
|
|
21
|
+
export interface LoggerConfig {
|
|
22
|
+
/** Log level threshold */
|
|
23
|
+
level?: LogLevel;
|
|
24
|
+
/** Path to log file (enables file logging) */
|
|
25
|
+
logFile?: string;
|
|
26
|
+
/** Whether to include timestamps in output */
|
|
27
|
+
timestamps?: boolean;
|
|
28
|
+
/** Whether to use colors in console output */
|
|
29
|
+
colors?: boolean;
|
|
30
|
+
/** Whether to also write to console when file logging is enabled */
|
|
31
|
+
consoleOutput?: boolean;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Parse log level from string
|
|
35
|
+
*/
|
|
36
|
+
export declare function parseLogLevel(value: string): LogLevel | undefined;
|
|
37
|
+
/**
|
|
38
|
+
* Singleton Logger class
|
|
39
|
+
*/
|
|
40
|
+
declare class Logger {
|
|
41
|
+
private static instance;
|
|
42
|
+
private level;
|
|
43
|
+
private logFile;
|
|
44
|
+
private fileStream;
|
|
45
|
+
private timestamps;
|
|
46
|
+
private colors;
|
|
47
|
+
private consoleOutput;
|
|
48
|
+
private context;
|
|
49
|
+
private initialized;
|
|
50
|
+
private constructor();
|
|
51
|
+
/**
|
|
52
|
+
* Get the singleton logger instance
|
|
53
|
+
*/
|
|
54
|
+
static getInstance(): Logger;
|
|
55
|
+
/**
|
|
56
|
+
* Initialize the logger with configuration
|
|
57
|
+
* Should be called early in CLI startup
|
|
58
|
+
*/
|
|
59
|
+
initialize(config?: LoggerConfig): void;
|
|
60
|
+
/**
|
|
61
|
+
* Set up file logging with rotation
|
|
62
|
+
*/
|
|
63
|
+
private setupFileLogging;
|
|
64
|
+
/**
|
|
65
|
+
* Rotate log files
|
|
66
|
+
*/
|
|
67
|
+
private rotateLogFiles;
|
|
68
|
+
/**
|
|
69
|
+
* Set the current context (e.g., command name)
|
|
70
|
+
*/
|
|
71
|
+
setContext(context: string | null): void;
|
|
72
|
+
/**
|
|
73
|
+
* Set the log level
|
|
74
|
+
*/
|
|
75
|
+
setLevel(level: LogLevel): void;
|
|
76
|
+
/**
|
|
77
|
+
* Get the current log level
|
|
78
|
+
*/
|
|
79
|
+
getLevel(): LogLevel;
|
|
80
|
+
/**
|
|
81
|
+
* Check if a log level is enabled
|
|
82
|
+
*/
|
|
83
|
+
isLevelEnabled(level: LogLevel): boolean;
|
|
84
|
+
/**
|
|
85
|
+
* Check if the logger is in debug mode
|
|
86
|
+
*/
|
|
87
|
+
isDebug(): boolean;
|
|
88
|
+
/**
|
|
89
|
+
* Check if the logger is in trace mode
|
|
90
|
+
*/
|
|
91
|
+
isTrace(): boolean;
|
|
92
|
+
/**
|
|
93
|
+
* Internal log method
|
|
94
|
+
*/
|
|
95
|
+
private log;
|
|
96
|
+
/**
|
|
97
|
+
* Internal log method with explicit context (thread-safe for child loggers)
|
|
98
|
+
*/
|
|
99
|
+
logWithContext(level: LogLevel, context: string | null, message: string, ...args: unknown[]): void;
|
|
100
|
+
/**
|
|
101
|
+
* Format message with arguments (simple substitution)
|
|
102
|
+
*/
|
|
103
|
+
private formatMessage;
|
|
104
|
+
/**
|
|
105
|
+
* Log an error message
|
|
106
|
+
*/
|
|
107
|
+
error(message: string, ...args: unknown[]): void;
|
|
108
|
+
/**
|
|
109
|
+
* Log a warning message
|
|
110
|
+
*/
|
|
111
|
+
warn(message: string, ...args: unknown[]): void;
|
|
112
|
+
/**
|
|
113
|
+
* Log an info message
|
|
114
|
+
*/
|
|
115
|
+
info(message: string, ...args: unknown[]): void;
|
|
116
|
+
/**
|
|
117
|
+
* Log a debug message
|
|
118
|
+
*/
|
|
119
|
+
debug(message: string, ...args: unknown[]): void;
|
|
120
|
+
/**
|
|
121
|
+
* Log a trace message
|
|
122
|
+
*/
|
|
123
|
+
trace(message: string, ...args: unknown[]): void;
|
|
124
|
+
/**
|
|
125
|
+
* Log an error with stack trace
|
|
126
|
+
*/
|
|
127
|
+
errorWithStack(err: Error, message?: string): void;
|
|
128
|
+
/**
|
|
129
|
+
* Create a child logger with a specific context
|
|
130
|
+
*/
|
|
131
|
+
child(context: string): ChildLogger;
|
|
132
|
+
/**
|
|
133
|
+
* Close the logger (flush file stream)
|
|
134
|
+
*/
|
|
135
|
+
close(): Promise<void>;
|
|
136
|
+
/**
|
|
137
|
+
* Get the default log file path
|
|
138
|
+
*/
|
|
139
|
+
static getDefaultLogFilePath(): string;
|
|
140
|
+
/**
|
|
141
|
+
* Reset the singleton instance (for testing)
|
|
142
|
+
*/
|
|
143
|
+
static reset(): void;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Child logger with a specific context
|
|
147
|
+
* Uses logWithContext to avoid race conditions with concurrent logging
|
|
148
|
+
*/
|
|
149
|
+
declare class ChildLogger {
|
|
150
|
+
private parent;
|
|
151
|
+
private context;
|
|
152
|
+
constructor(parent: Logger, context: string);
|
|
153
|
+
error(message: string, ...args: unknown[]): void;
|
|
154
|
+
warn(message: string, ...args: unknown[]): void;
|
|
155
|
+
info(message: string, ...args: unknown[]): void;
|
|
156
|
+
debug(message: string, ...args: unknown[]): void;
|
|
157
|
+
trace(message: string, ...args: unknown[]): void;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* The singleton logger instance
|
|
161
|
+
*/
|
|
162
|
+
export declare const logger: Logger;
|
|
163
|
+
/**
|
|
164
|
+
* Initialize the logger from CLI arguments and config
|
|
165
|
+
* Call this early in CLI entry points
|
|
166
|
+
*/
|
|
167
|
+
export declare function initializeLogger(options: {
|
|
168
|
+
verbose?: boolean | number;
|
|
169
|
+
debug?: boolean;
|
|
170
|
+
logFile?: string;
|
|
171
|
+
quiet?: boolean;
|
|
172
|
+
configLogLevel?: LogLevel | string;
|
|
173
|
+
configLogFile?: string;
|
|
174
|
+
}): void;
|
|
175
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/lib/logger.ts"],"names":[],"mappings":"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"}
|