skuba 12.2.0 → 12.3.0-add-minimumReleaseAge-20250919032927
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/lib/cli/configure/processing/configFile.d.ts +1 -1
- package/lib/cli/configure/processing/configFile.js +47 -6
- package/lib/cli/configure/processing/configFile.js.map +3 -3
- package/lib/cli/lint/internalLints/refreshConfigFiles.js +5 -3
- package/lib/cli/lint/internalLints/refreshConfigFiles.js.map +2 -2
- package/package.json +2 -2
- package/template/base/_pnpm-workspace.yaml +5 -0
- package/template/express-rest-api/package.json +2 -2
- package/template/greeter/package.json +2 -2
- package/template/koa-rest-api/package.json +2 -2
- package/template/lambda-sqs-worker-cdk/package.json +2 -2
- package/template/oss-npm-package/.github/workflows/release.yml +1 -1
- package/template/oss-npm-package/.github/workflows/validate.yml +1 -1
|
@@ -6,4 +6,4 @@
|
|
|
6
6
|
*/
|
|
7
7
|
export declare const generateIgnoreFileSimpleVariants: (patterns: string[]) => Set<string>;
|
|
8
8
|
export declare const replaceManagedSection: (input: string, template: string) => string;
|
|
9
|
-
export declare const mergeWithConfigFile: (rawTemplateFile: string, fileType?: "ignore" | "pnpm-workspace") => (rawInputFile?: string) => string;
|
|
9
|
+
export declare const mergeWithConfigFile: (rawTemplateFile: string, fileType?: "ignore" | "pnpm-workspace", packageJson?: string) => (rawInputFile?: string) => string;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
var configFile_exports = {};
|
|
20
30
|
__export(configFile_exports, {
|
|
@@ -23,6 +33,7 @@ __export(configFile_exports, {
|
|
|
23
33
|
replaceManagedSection: () => replaceManagedSection
|
|
24
34
|
});
|
|
25
35
|
module.exports = __toCommonJS(configFile_exports);
|
|
36
|
+
var import_v4 = __toESM(require("zod/v4"));
|
|
26
37
|
const OUTDATED_PATTERNS = ["node_modules_bak/", "tmp-*/"];
|
|
27
38
|
const ASTERISKS = /\*/g;
|
|
28
39
|
const LEADING_SLASH = /^\//;
|
|
@@ -46,9 +57,36 @@ const generateIgnoreFileSimpleVariants = (patterns) => {
|
|
|
46
57
|
set.delete("");
|
|
47
58
|
return set;
|
|
48
59
|
};
|
|
60
|
+
const ammendPnpmWorkspaceTemplate = (templateFile, packageJson) => {
|
|
61
|
+
const lines = templateFile.split("\n");
|
|
62
|
+
const result = [];
|
|
63
|
+
for (const line of lines) {
|
|
64
|
+
result.push(line);
|
|
65
|
+
if (!packageJson || !line.startsWith("minimumReleaseAgeExclude:")) {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
let rawJSON;
|
|
69
|
+
try {
|
|
70
|
+
rawJSON = JSON.parse(packageJson);
|
|
71
|
+
} catch {
|
|
72
|
+
throw new Error("package.json is not valid JSON");
|
|
73
|
+
}
|
|
74
|
+
const parsed = import_v4.default.object({
|
|
75
|
+
minimumReleaseAgeExcludeOverload: import_v4.default.array(import_v4.default.string()).optional()
|
|
76
|
+
}).safeParse(rawJSON);
|
|
77
|
+
const excludes = parsed.data?.minimumReleaseAgeExcludeOverload;
|
|
78
|
+
if (!excludes || Array.isArray(excludes) === false || excludes.some((e) => typeof e !== "string")) {
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
for (const exclude of excludes) {
|
|
82
|
+
result.push(` - '${exclude}'`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return result.join("\n");
|
|
86
|
+
};
|
|
49
87
|
const replaceManagedSection = (input, template) => input.replace(/# managed by skuba[\s\S]*# end managed by skuba/, template);
|
|
50
|
-
const mergeWithConfigFile = (rawTemplateFile, fileType = "ignore") => {
|
|
51
|
-
const templateFile = rawTemplateFile.trim();
|
|
88
|
+
const mergeWithConfigFile = (rawTemplateFile, fileType = "ignore", packageJson) => {
|
|
89
|
+
const templateFile = fileType === "pnpm-workspace" ? ammendPnpmWorkspaceTemplate(rawTemplateFile.trim(), packageJson) : rawTemplateFile.trim();
|
|
52
90
|
let generator;
|
|
53
91
|
switch (fileType) {
|
|
54
92
|
case "ignore":
|
|
@@ -58,10 +96,13 @@ const mergeWithConfigFile = (rawTemplateFile, fileType = "ignore") => {
|
|
|
58
96
|
generator = () => /* @__PURE__ */ new Set();
|
|
59
97
|
break;
|
|
60
98
|
}
|
|
61
|
-
const templatePatterns = generator(
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
99
|
+
const templatePatterns = generator(
|
|
100
|
+
[
|
|
101
|
+
...OUTDATED_PATTERNS,
|
|
102
|
+
...templateFile.split("\n").map((line) => line.trim())
|
|
103
|
+
],
|
|
104
|
+
packageJson
|
|
105
|
+
);
|
|
65
106
|
return (rawInputFile) => {
|
|
66
107
|
if (rawInputFile === void 0) {
|
|
67
108
|
return `${templateFile}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/cli/configure/processing/configFile.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Patterns that are superseded by skuba's bundled ignore file patterns and are\n * non-trivial to derive using e.g. `generateSimpleVariants`.\n */\nconst OUTDATED_PATTERNS = ['node_modules_bak/', 'tmp-*/'];\n\nconst ASTERISKS = /\\*/g;\nconst LEADING_SLASH = /^\\//;\nconst TRAILING_SLASH = /\\/$/;\n\n/**\n * Generate simple variants of an ignore pattern for exact matching purposes.\n *\n * Note that these patterns are not actually equivalent (e.g. `lib` matches more\n * than `lib/`) but they generally represent the same _intent_.\n */\nexport const generateIgnoreFileSimpleVariants = (patterns: string[]) => {\n const set = new Set<string>();\n\n for (const pattern of patterns) {\n const deAsterisked = pattern.replace(ASTERISKS, '');\n const stripped = deAsterisked\n .replace(LEADING_SLASH, '')\n .replace(TRAILING_SLASH, '');\n\n set.add(pattern);\n set.add(deAsterisked);\n set.add(deAsterisked.replace(LEADING_SLASH, ''));\n set.add(deAsterisked.replace(TRAILING_SLASH, ''));\n set.add(stripped);\n\n if (stripped !== '') {\n set.add(`/${stripped}`);\n set.add(`${stripped}/`);\n set.add(`/${stripped}/`);\n }\n }\n\n set.delete('');\n\n return set;\n};\n\nexport const replaceManagedSection = (input: string, template: string) =>\n input.replace(/# managed by skuba[\\s\\S]*# end managed by skuba/, template);\n\nexport const mergeWithConfigFile = (\n rawTemplateFile: string,\n fileType: 'ignore' | 'pnpm-workspace' = 'ignore',\n) => {\n const templateFile
|
|
5
|
-
"mappings": "
|
|
6
|
-
"names": []
|
|
4
|
+
"sourcesContent": ["import z from 'zod/v4';\n\n/**\n * Patterns that are superseded by skuba's bundled ignore file patterns and are\n * non-trivial to derive using e.g. `generateSimpleVariants`.\n */\nconst OUTDATED_PATTERNS = ['node_modules_bak/', 'tmp-*/'];\n\nconst ASTERISKS = /\\*/g;\nconst LEADING_SLASH = /^\\//;\nconst TRAILING_SLASH = /\\/$/;\n\n/**\n * Generate simple variants of an ignore pattern for exact matching purposes.\n *\n * Note that these patterns are not actually equivalent (e.g. `lib` matches more\n * than `lib/`) but they generally represent the same _intent_.\n */\nexport const generateIgnoreFileSimpleVariants = (patterns: string[]) => {\n const set = new Set<string>();\n\n for (const pattern of patterns) {\n const deAsterisked = pattern.replace(ASTERISKS, '');\n const stripped = deAsterisked\n .replace(LEADING_SLASH, '')\n .replace(TRAILING_SLASH, '');\n\n set.add(pattern);\n set.add(deAsterisked);\n set.add(deAsterisked.replace(LEADING_SLASH, ''));\n set.add(deAsterisked.replace(TRAILING_SLASH, ''));\n set.add(stripped);\n\n if (stripped !== '') {\n set.add(`/${stripped}`);\n set.add(`${stripped}/`);\n set.add(`/${stripped}/`);\n }\n }\n\n set.delete('');\n\n return set;\n};\n\nconst ammendPnpmWorkspaceTemplate = (\n templateFile: string,\n packageJson?: string,\n) => {\n const lines = templateFile.split('\\n');\n const result: string[] = [];\n for (const line of lines) {\n result.push(line);\n if (!packageJson || !line.startsWith('minimumReleaseAgeExclude:')) {\n continue;\n }\n\n let rawJSON;\n try {\n rawJSON = JSON.parse(packageJson) as unknown;\n } catch {\n throw new Error('package.json is not valid JSON');\n }\n const parsed = z\n .object({\n minimumReleaseAgeExcludeOverload: z.array(z.string()).optional(),\n })\n .safeParse(rawJSON);\n\n const excludes = parsed.data?.minimumReleaseAgeExcludeOverload;\n\n if (\n !excludes ||\n Array.isArray(excludes) === false ||\n excludes.some((e) => typeof e !== 'string')\n ) {\n continue;\n }\n for (const exclude of excludes) {\n result.push(` - '${exclude}'`);\n }\n }\n\n return result.join('\\n');\n};\n\nexport const replaceManagedSection = (input: string, template: string) =>\n input.replace(/# managed by skuba[\\s\\S]*# end managed by skuba/, template);\n\nexport const mergeWithConfigFile = (\n rawTemplateFile: string,\n fileType: 'ignore' | 'pnpm-workspace' = 'ignore',\n packageJson?: string,\n) => {\n const templateFile =\n fileType === 'pnpm-workspace'\n ? ammendPnpmWorkspaceTemplate(rawTemplateFile.trim(), packageJson)\n : rawTemplateFile.trim();\n\n let generator: (s: string[], packageJson?: string) => Set<string>;\n\n switch (fileType) {\n case 'ignore':\n generator = generateIgnoreFileSimpleVariants;\n break;\n case 'pnpm-workspace':\n generator = () => new Set<string>();\n break;\n }\n\n const templatePatterns = generator(\n [\n ...OUTDATED_PATTERNS,\n ...templateFile.split('\\n').map((line) => line.trim()),\n ],\n packageJson,\n );\n\n return (rawInputFile?: string) => {\n if (rawInputFile === undefined) {\n return `${templateFile}\\n`;\n }\n\n const replacedFile = replaceManagedSection(\n rawInputFile.replace(/\\r?\\n/g, '\\n'),\n templateFile,\n );\n\n if (replacedFile.includes(templateFile)) {\n return replacedFile;\n }\n\n // Crunch the existing lines of a non-skuba config.\n const migratedFile = replacedFile\n .split('\\n')\n .filter((line) => !templatePatterns.has(line))\n .join('\\n')\n .replace(/\\n{3,}/g, '\\n\\n')\n .trim();\n\n const outputFile = [templateFile, migratedFile].join('\\n\\n').trim();\n\n return `${outputFile}\\n`;\n };\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["z"]
|
|
7
7
|
}
|
|
@@ -87,19 +87,21 @@ const refreshConfigFiles = async (mode, logger) => {
|
|
|
87
87
|
if (!condition(conditionOptions)) {
|
|
88
88
|
return { needsChange: false };
|
|
89
89
|
}
|
|
90
|
-
const
|
|
90
|
+
const maybeReadPackageJson = async (type) => type === "pnpm-workspace" ? await readDestinationFile("package.json") : void 0;
|
|
91
|
+
const [inputFile, templateFile, isGitIgnored, packageJson] = await Promise.all([
|
|
91
92
|
readDestinationFile(filename),
|
|
92
93
|
(0, import_template.readBaseTemplateFile)(`_${filename}`),
|
|
93
94
|
gitRoot ? import__.Git.isFileGitIgnored({
|
|
94
95
|
gitRoot,
|
|
95
96
|
absolutePath: import_path.default.join(destinationRoot, filename)
|
|
96
|
-
}) : false
|
|
97
|
+
}) : false,
|
|
98
|
+
maybeReadPackageJson(fileType)
|
|
97
99
|
]);
|
|
98
100
|
if (inputFile === void 0 && isGitIgnored) {
|
|
99
101
|
return { needsChange: false };
|
|
100
102
|
}
|
|
101
103
|
const data = additionalMapping(
|
|
102
|
-
inputFile ? (0, import_configFile.mergeWithConfigFile)(templateFile, fileType)(inputFile) : templateFile,
|
|
104
|
+
inputFile ? (0, import_configFile.mergeWithConfigFile)(templateFile, fileType, packageJson)(inputFile) : templateFile,
|
|
103
105
|
packageManager
|
|
104
106
|
);
|
|
105
107
|
const filepath = import_path.default.join(destinationRoot, filename);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/cli/lint/internalLints/refreshConfigFiles.ts"],
|
|
4
|
-
"sourcesContent": ["import path from 'path';\nimport { inspect, stripVTControlCharacters as stripAnsi } from 'util';\n\nimport fs from 'fs-extra';\n\nimport { Git } from '../../../index.js';\nimport {\n findCurrentWorkspaceProjectRoot,\n findWorkspaceRoot,\n} from '../../../utils/dir.js';\nimport type { Logger } from '../../../utils/logging.js';\nimport {\n type PackageManagerConfig,\n detectPackageManager,\n} from '../../../utils/packageManager.js';\nimport { readBaseTemplateFile } from '../../../utils/template.js';\nimport { getDestinationManifest } from '../../configure/analysis/package.js';\nimport { createDestinationFileReader } from '../../configure/analysis/project.js';\nimport { mergeWithConfigFile } from '../../configure/processing/configFile.js';\nimport type { InternalLintResult } from '../internal.js';\n\ntype ConditionOptions = {\n packageManager: PackageManagerConfig;\n isInWorkspaceRoot: boolean;\n};\n\ntype RefreshableConfigFile = {\n name: string;\n type: 'ignore' | 'pnpm-workspace';\n additionalMapping?: (\n s: string,\n packageManager: PackageManagerConfig,\n ) => string;\n if?: (options: ConditionOptions) => boolean;\n};\n\nconst OLD_IGNORE_WARNING = `# Ignore .npmrc. This is no longer managed by skuba as pnpm projects use a managed .npmrc.\n# IMPORTANT: if migrating to pnpm, remove this line and add an .npmrc IN THE SAME COMMIT.\n# You can use \\`skuba format\\` to generate the file or otherwise commit an empty file.\n# Doing so will conflict with a local .npmrc and make it more difficult to unintentionally commit auth secrets.\n.npmrc\n`;\n\nconst removeOldWarning = (contents: string) =>\n contents.includes(OLD_IGNORE_WARNING)\n ? `${contents.replace(OLD_IGNORE_WARNING, '').trim()}\\n`\n : contents;\n\nexport const REFRESHABLE_CONFIG_FILES: RefreshableConfigFile[] = [\n {\n name: '.gitignore',\n type: 'ignore',\n additionalMapping: removeOldWarning,\n },\n { name: '.prettierignore', type: 'ignore' },\n {\n name: 'pnpm-workspace.yaml',\n type: 'pnpm-workspace',\n if: ({ packageManager, isInWorkspaceRoot }) =>\n isInWorkspaceRoot && packageManager.command === 'pnpm',\n },\n {\n name: '.dockerignore',\n type: 'ignore',\n additionalMapping: removeOldWarning,\n },\n];\n\nexport const refreshConfigFiles = async (\n mode: 'format' | 'lint',\n logger: Logger,\n) => {\n const [manifest, gitRoot, workspaceRoot, currentWorkspaceProjectRoot] =\n await Promise.all([\n getDestinationManifest(),\n Git.findRoot({ dir: process.cwd() }),\n findWorkspaceRoot(),\n findCurrentWorkspaceProjectRoot(),\n ]);\n\n const destinationRoot = path.dirname(manifest.path);\n\n const readDestinationFile = createDestinationFileReader(destinationRoot);\n\n const refreshConfigFile = async (\n {\n name: filename,\n type: fileType,\n additionalMapping = (s) => s,\n if: condition = () => true,\n }: RefreshableConfigFile,\n conditionOptions: ConditionOptions,\n ) => {\n if (!condition(conditionOptions)) {\n return { needsChange: false };\n }\n\n const [inputFile, templateFile, isGitIgnored]
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAiB;AACjB,kBAA+D;AAE/D,sBAAe;AAEf,eAAoB;AACpB,iBAGO;AAEP,4BAGO;AACP,sBAAqC;AACrC,qBAAuC;AACvC,qBAA4C;AAC5C,wBAAoC;AAkBpC,MAAM,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAO3B,MAAM,mBAAmB,CAAC,aACxB,SAAS,SAAS,kBAAkB,IAChC,GAAG,SAAS,QAAQ,oBAAoB,EAAE,EAAE,KAAK,CAAC;AAAA,IAClD;AAEC,MAAM,2BAAoD;AAAA,EAC/D;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,mBAAmB;AAAA,EACrB;AAAA,EACA,EAAE,MAAM,mBAAmB,MAAM,SAAS;AAAA,EAC1C;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,IAAI,CAAC,EAAE,gBAAgB,kBAAkB,MACvC,qBAAqB,eAAe,YAAY;AAAA,EACpD;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,mBAAmB;AAAA,EACrB;AACF;AAEO,MAAM,qBAAqB,OAChC,MACA,WACG;AACH,QAAM,CAAC,UAAU,SAAS,eAAe,2BAA2B,IAClE,MAAM,QAAQ,IAAI;AAAA,QAChB,uCAAuB;AAAA,IACvB,aAAI,SAAS,EAAE,KAAK,QAAQ,IAAI,EAAE,CAAC;AAAA,QACnC,8BAAkB;AAAA,QAClB,4CAAgC;AAAA,EAClC,CAAC;AAEH,QAAM,kBAAkB,YAAAA,QAAK,QAAQ,SAAS,IAAI;AAElD,QAAM,0BAAsB,4CAA4B,eAAe;AAEvE,QAAM,oBAAoB,OACxB;AAAA,IACE,MAAM;AAAA,IACN,MAAM;AAAA,IACN,oBAAoB,CAAC,MAAM;AAAA,IAC3B,IAAI,YAAY,MAAM;AAAA,EACxB,GACA,qBACG;AACH,QAAI,CAAC,UAAU,gBAAgB,GAAG;AAChC,aAAO,EAAE,aAAa,MAAM;AAAA,IAC9B;AAEA,UAAM,CAAC,WAAW,cAAc,
|
|
4
|
+
"sourcesContent": ["import path from 'path';\nimport { inspect, stripVTControlCharacters as stripAnsi } from 'util';\n\nimport fs from 'fs-extra';\n\nimport { Git } from '../../../index.js';\nimport {\n findCurrentWorkspaceProjectRoot,\n findWorkspaceRoot,\n} from '../../../utils/dir.js';\nimport type { Logger } from '../../../utils/logging.js';\nimport {\n type PackageManagerConfig,\n detectPackageManager,\n} from '../../../utils/packageManager.js';\nimport { readBaseTemplateFile } from '../../../utils/template.js';\nimport { getDestinationManifest } from '../../configure/analysis/package.js';\nimport { createDestinationFileReader } from '../../configure/analysis/project.js';\nimport { mergeWithConfigFile } from '../../configure/processing/configFile.js';\nimport type { InternalLintResult } from '../internal.js';\n\ntype ConditionOptions = {\n packageManager: PackageManagerConfig;\n isInWorkspaceRoot: boolean;\n};\n\ntype RefreshableConfigFile = {\n name: string;\n type: 'ignore' | 'pnpm-workspace';\n additionalMapping?: (\n s: string,\n packageManager: PackageManagerConfig,\n ) => string;\n if?: (options: ConditionOptions) => boolean;\n};\n\nconst OLD_IGNORE_WARNING = `# Ignore .npmrc. This is no longer managed by skuba as pnpm projects use a managed .npmrc.\n# IMPORTANT: if migrating to pnpm, remove this line and add an .npmrc IN THE SAME COMMIT.\n# You can use \\`skuba format\\` to generate the file or otherwise commit an empty file.\n# Doing so will conflict with a local .npmrc and make it more difficult to unintentionally commit auth secrets.\n.npmrc\n`;\n\nconst removeOldWarning = (contents: string) =>\n contents.includes(OLD_IGNORE_WARNING)\n ? `${contents.replace(OLD_IGNORE_WARNING, '').trim()}\\n`\n : contents;\n\nexport const REFRESHABLE_CONFIG_FILES: RefreshableConfigFile[] = [\n {\n name: '.gitignore',\n type: 'ignore',\n additionalMapping: removeOldWarning,\n },\n { name: '.prettierignore', type: 'ignore' },\n {\n name: 'pnpm-workspace.yaml',\n type: 'pnpm-workspace',\n if: ({ packageManager, isInWorkspaceRoot }) =>\n isInWorkspaceRoot && packageManager.command === 'pnpm',\n },\n {\n name: '.dockerignore',\n type: 'ignore',\n additionalMapping: removeOldWarning,\n },\n];\n\nexport const refreshConfigFiles = async (\n mode: 'format' | 'lint',\n logger: Logger,\n) => {\n const [manifest, gitRoot, workspaceRoot, currentWorkspaceProjectRoot] =\n await Promise.all([\n getDestinationManifest(),\n Git.findRoot({ dir: process.cwd() }),\n findWorkspaceRoot(),\n findCurrentWorkspaceProjectRoot(),\n ]);\n\n const destinationRoot = path.dirname(manifest.path);\n\n const readDestinationFile = createDestinationFileReader(destinationRoot);\n\n const refreshConfigFile = async (\n {\n name: filename,\n type: fileType,\n additionalMapping = (s) => s,\n if: condition = () => true,\n }: RefreshableConfigFile,\n conditionOptions: ConditionOptions,\n ) => {\n if (!condition(conditionOptions)) {\n return { needsChange: false };\n }\n\n const maybeReadPackageJson = async (type: RefreshableConfigFile['type']) =>\n type === 'pnpm-workspace'\n ? await readDestinationFile('package.json')\n : undefined;\n\n const [inputFile, templateFile, isGitIgnored, packageJson] =\n await Promise.all([\n readDestinationFile(filename),\n readBaseTemplateFile(`_${filename}`),\n gitRoot\n ? Git.isFileGitIgnored({\n gitRoot,\n absolutePath: path.join(destinationRoot, filename),\n })\n : false,\n maybeReadPackageJson(fileType),\n ]);\n\n // If the file is gitignored and doesn't exist, don't make it\n if (inputFile === undefined && isGitIgnored) {\n return { needsChange: false };\n }\n\n const data = additionalMapping(\n inputFile\n ? mergeWithConfigFile(templateFile, fileType, packageJson)(inputFile)\n : templateFile,\n packageManager,\n );\n\n const filepath = path.join(destinationRoot, filename);\n\n if (mode === 'format') {\n if (data === inputFile) {\n return { needsChange: false };\n }\n\n await fs.writeFile(filepath, data);\n return {\n needsChange: false,\n msg: `Refreshed ${logger.bold(filename)}.`,\n filename,\n };\n }\n\n if (data !== inputFile) {\n return {\n needsChange: true,\n msg: `The ${logger.bold(\n filename,\n )} file is out of date. Run \\`${logger.bold(\n packageManager.print.exec,\n 'skuba',\n 'format',\n )}\\` to update it.`,\n filename,\n };\n }\n\n return { needsChange: false };\n };\n\n const packageManager = await detectPackageManager(destinationRoot);\n\n const results = await Promise.all(\n REFRESHABLE_CONFIG_FILES.map((conf) =>\n refreshConfigFile(conf, {\n packageManager,\n isInWorkspaceRoot: workspaceRoot === currentWorkspaceProjectRoot,\n }),\n ),\n );\n\n // Log after for reproducible test output ordering\n results.forEach((result) => {\n if (result.msg) {\n logger.warn(result.msg);\n }\n });\n\n const anyNeedChanging = results.some(({ needsChange }) => needsChange);\n\n return {\n ok: !anyNeedChanging,\n fixable: anyNeedChanging,\n annotations: results.flatMap(({ needsChange, filename, msg }) =>\n needsChange && msg\n ? [\n {\n path: filename,\n message: stripAnsi(msg),\n },\n ]\n : [],\n ),\n };\n};\n\nexport const tryRefreshConfigFiles = async (\n mode: 'format' | 'lint',\n logger: Logger,\n): Promise<InternalLintResult> => {\n try {\n return await refreshConfigFiles(mode, logger);\n } catch (err) {\n logger.warn('Failed to refresh config files.');\n logger.subtle(inspect(err));\n\n return {\n ok: false,\n fixable: false,\n annotations: [],\n };\n }\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["path", "fs", "stripAnsi"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skuba",
|
|
3
|
-
"version": "12.
|
|
3
|
+
"version": "12.3.0-add-minimumReleaseAge-20250919032927",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "SEEK development toolkit for backend applications and packages",
|
|
6
6
|
"homepage": "https://github.com/seek-oss/skuba#readme",
|
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
"tsx": "^4.16.2",
|
|
98
98
|
"typescript": "~5.9.0",
|
|
99
99
|
"zod": "^4.0.0",
|
|
100
|
-
"eslint-config-skuba": "7.1.
|
|
100
|
+
"eslint-config-skuba": "7.1.2-add-minimumReleaseAge-20250919032927"
|
|
101
101
|
},
|
|
102
102
|
"devDependencies": {
|
|
103
103
|
"@changesets/cli": "2.29.6",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"@opentelemetry/api": "^1.9.0",
|
|
17
17
|
"@opentelemetry/core": "^2.0.0",
|
|
18
18
|
"@opentelemetry/exporter-trace-otlp-grpc": "^0.204.0",
|
|
19
|
-
"@opentelemetry/instrumentation-aws-sdk": "^0.
|
|
19
|
+
"@opentelemetry/instrumentation-aws-sdk": "^0.59.0",
|
|
20
20
|
"@opentelemetry/instrumentation-http": "^0.204.0",
|
|
21
21
|
"@opentelemetry/propagator-b3": "^2.0.0",
|
|
22
22
|
"@opentelemetry/sdk-node": "^0.204.0",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"skuba": "*",
|
|
35
35
|
"supertest": "^7.0.0"
|
|
36
36
|
},
|
|
37
|
-
"packageManager": "pnpm@10.
|
|
37
|
+
"packageManager": "pnpm@10.17.0",
|
|
38
38
|
"engines": {
|
|
39
39
|
"node": ">=22"
|
|
40
40
|
}
|
|
@@ -17,9 +17,9 @@
|
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|
|
19
19
|
"@types/node": "^22.13.10",
|
|
20
|
-
"skuba": "
|
|
20
|
+
"skuba": "12.3.0-add-minimumReleaseAge-20250919032927"
|
|
21
21
|
},
|
|
22
|
-
"packageManager": "pnpm@10.
|
|
22
|
+
"packageManager": "pnpm@10.17.0",
|
|
23
23
|
"engines": {
|
|
24
24
|
"node": ">=22"
|
|
25
25
|
}
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"@opentelemetry/api": "^1.9.0",
|
|
19
19
|
"@opentelemetry/core": "^2.0.0",
|
|
20
20
|
"@opentelemetry/exporter-trace-otlp-grpc": "^0.204.0",
|
|
21
|
-
"@opentelemetry/instrumentation-aws-sdk": "^0.
|
|
21
|
+
"@opentelemetry/instrumentation-aws-sdk": "^0.59.0",
|
|
22
22
|
"@opentelemetry/instrumentation-http": "^0.204.0",
|
|
23
23
|
"@opentelemetry/propagator-b3": "^2.0.0",
|
|
24
24
|
"@opentelemetry/sdk-node": "^0.204.0",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"skuba": "*",
|
|
44
44
|
"supertest": "^7.0.0"
|
|
45
45
|
},
|
|
46
|
-
"packageManager": "pnpm@10.
|
|
46
|
+
"packageManager": "pnpm@10.17.0",
|
|
47
47
|
"engines": {
|
|
48
48
|
"node": ">=22"
|
|
49
49
|
}
|
|
@@ -35,9 +35,9 @@
|
|
|
35
35
|
"datadog-lambda-js": "^12.0.0",
|
|
36
36
|
"dd-trace": "^5.0.0",
|
|
37
37
|
"pino-pretty": "^13.0.0",
|
|
38
|
-
"skuba": "
|
|
38
|
+
"skuba": "12.3.0-add-minimumReleaseAge-20250919032927"
|
|
39
39
|
},
|
|
40
|
-
"packageManager": "pnpm@10.
|
|
40
|
+
"packageManager": "pnpm@10.17.0",
|
|
41
41
|
"engines": {
|
|
42
42
|
"node": ">=22"
|
|
43
43
|
}
|