@grafana/create-plugin 6.2.0-canary.2233.19133609453.0 → 6.2.0-canary.2283.19225164741.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/CHANGELOG.md +23 -0
- package/CONTRIBUTING.md +3 -0
- package/dist/bin/run.js +1 -3
- package/dist/commands/update.command.js +1 -1
- package/dist/{codemods → migrations}/context.js +2 -3
- package/dist/{codemods/migrations → migrations}/manager.js +7 -8
- package/dist/{codemods/migrations → migrations}/migrations.js +6 -3
- package/dist/{codemods/migrations → migrations}/scripts/003-update-eslint-deprecation-rule.js +1 -1
- package/dist/{codemods/migrations → migrations}/scripts/004-eslint9-flat-config.js +1 -2
- package/dist/migrations/scripts/005-react-18-3.js +20 -0
- package/dist/{codemods → migrations}/utils.js +22 -5
- package/dist/utils/utils.config.js +1 -16
- package/package.json +2 -2
- package/src/bin/run.ts +1 -2
- package/src/commands/index.ts +0 -1
- package/src/commands/update.command.ts +1 -1
- package/src/{codemods → migrations}/context.test.ts +10 -10
- package/src/{codemods → migrations}/context.ts +2 -4
- package/src/{codemods/migrations → migrations}/manager.test.ts +18 -23
- package/src/{codemods/migrations → migrations}/manager.ts +9 -10
- package/src/migrations/migrations.test.ts +16 -0
- package/src/{codemods/migrations → migrations}/migrations.ts +8 -3
- package/src/{codemods/migrations → migrations}/scripts/001-update-grafana-compose-extend.test.ts +1 -1
- package/src/{codemods/migrations → migrations}/scripts/001-update-grafana-compose-extend.ts +1 -1
- package/src/{codemods/migrations → migrations}/scripts/002-update-is-compatible-workflow.test.ts +1 -1
- package/src/{codemods/migrations → migrations}/scripts/002-update-is-compatible-workflow.ts +1 -1
- package/src/{codemods/migrations → migrations}/scripts/003-update-eslint-deprecation-rule.test.ts +1 -1
- package/src/{codemods/migrations → migrations}/scripts/003-update-eslint-deprecation-rule.ts +2 -2
- package/src/{codemods/migrations → migrations}/scripts/004-eslint9-flat-config.test.ts +1 -1
- package/src/{codemods/migrations → migrations}/scripts/004-eslint9-flat-config.ts +2 -3
- package/src/migrations/scripts/005-react-18-3.test.ts +145 -0
- package/src/migrations/scripts/005-react-18-3.ts +19 -0
- package/src/{codemods/migrations → migrations}/scripts/example-migration.test.ts +1 -1
- package/src/{codemods/migrations → migrations}/scripts/example-migration.ts +1 -1
- package/src/{codemods/migrations → migrations}/utils.test.ts +4 -4
- package/src/{codemods → migrations}/utils.ts +33 -37
- package/src/utils/utils.config.ts +1 -28
- package/templates/common/_package.json +5 -3
- package/templates/github/workflows/cp-update.yml +8 -13
- package/vitest.config.ts +12 -0
- package/dist/codemods/additions/additions.js +0 -11
- package/dist/codemods/additions/manager.js +0 -115
- package/dist/codemods/additions/scripts/example-addition.js +0 -61
- package/dist/codemods/additions/utils.js +0 -10
- package/dist/codemods/migrations/utils.js +0 -10
- package/dist/commands/add.command.js +0 -86
- package/src/codemods/additions/additions.ts +0 -23
- package/src/codemods/additions/manager.ts +0 -145
- package/src/codemods/additions/scripts/example-addition.test.ts +0 -111
- package/src/codemods/additions/scripts/example-addition.ts +0 -79
- package/src/codemods/additions/utils.ts +0 -12
- package/src/codemods/migrations/migrations.test.ts +0 -12
- package/src/codemods/migrations/utils.ts +0 -12
- package/src/codemods/types.ts +0 -21
- package/src/commands/add.command.ts +0 -97
- /package/dist/{codemods/migrations → migrations}/scripts/001-update-grafana-compose-extend.js +0 -0
- /package/dist/{codemods/migrations → migrations}/scripts/002-update-is-compatible-workflow.js +0 -0
- /package/dist/{codemods/migrations → migrations}/scripts/example-migration.js +0 -0
- /package/src/{codemods/migrations → migrations}/fixtures/foo/bar.ts +0 -0
- /package/src/{codemods/migrations → migrations}/fixtures/foo/baz.ts +0 -0
- /package/src/{codemods/migrations → migrations}/fixtures/migrations.ts +0 -0
- /package/src/{codemods → migrations}/test-utils.ts +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,26 @@
|
|
|
1
|
+
# v6.1.8 (Fri Nov 07 2025)
|
|
2
|
+
|
|
3
|
+
### Release Notes
|
|
4
|
+
|
|
5
|
+
#### chore(deps): update grafana patch dependencies ([#2217](https://github.com/grafana/plugin-tools/pull/2217))
|
|
6
|
+
|
|
7
|
+
<details>
|
|
8
|
+
<summary>grafana/grafana (@​grafana/data)</summary>
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
#### 🐛 Bug Fix
|
|
13
|
+
|
|
14
|
+
- Create plugin: fix permissions issue in cp-update workflow [#2281](https://github.com/grafana/plugin-tools/pull/2281) ([@jackw](https://github.com/jackw))
|
|
15
|
+
- chore(deps): update grafana patch dependencies [#2217](https://github.com/grafana/plugin-tools/pull/2217) ([@renovate-sh-app[bot]](https://github.com/renovate-sh-app[bot]))
|
|
16
|
+
|
|
17
|
+
#### Authors: 2
|
|
18
|
+
|
|
19
|
+
- [@renovate-sh-app[bot]](https://github.com/renovate-sh-app[bot])
|
|
20
|
+
- Jack Westbrook ([@jackw](https://github.com/jackw))
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
1
24
|
# v6.1.7 (Mon Nov 03 2025)
|
|
2
25
|
|
|
3
26
|
:tada: This release contains work from a new contributor! :tada:
|
package/CONTRIBUTING.md
CHANGED
|
@@ -222,6 +222,9 @@ describe('Migration - append profile to webpack', () => {
|
|
|
222
222
|
});
|
|
223
223
|
```
|
|
224
224
|
|
|
225
|
+
> [!TIP]
|
|
226
|
+
> A lot of the code used by migrations has debug messaging. You can output this in tests to help debugging by using `DEBUG="create-plugin:migrations" npm run test -w @grafana/create-plugin`
|
|
227
|
+
|
|
225
228
|
#### How to test a migration locally
|
|
226
229
|
|
|
227
230
|
To test a migration locally you'll need a plugin to test on.
|
package/dist/bin/run.js
CHANGED
|
@@ -4,7 +4,6 @@ import { update } from '../commands/update.command.js';
|
|
|
4
4
|
import { migrate } from '../commands/migrate.command.js';
|
|
5
5
|
import { version } from '../commands/version.command.js';
|
|
6
6
|
import { provisioning } from '../commands/provisioning.command.js';
|
|
7
|
-
import { add } from '../commands/add.command.js';
|
|
8
7
|
import { isUnsupportedPlatform } from '../utils/utils.os.js';
|
|
9
8
|
import { argv, commandName } from '../utils/utils.cli.js';
|
|
10
9
|
import { output } from '../utils/utils.console.js';
|
|
@@ -22,8 +21,7 @@ const commands = {
|
|
|
22
21
|
generate,
|
|
23
22
|
update,
|
|
24
23
|
version,
|
|
25
|
-
provisioning
|
|
26
|
-
add
|
|
24
|
+
provisioning
|
|
27
25
|
};
|
|
28
26
|
const command = commands[commandName] || "generate";
|
|
29
27
|
command(argv);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getMigrationsToRun, runMigrations } from '../
|
|
1
|
+
import { getMigrationsToRun, runMigrations } from '../migrations/manager.js';
|
|
2
2
|
import { getPackageManagerWithFallback, getPackageManagerExecCmd, getPackageManagerSilentInstallCmd } from '../utils/utils.packageManager.js';
|
|
3
3
|
import { lt, gte } from 'semver';
|
|
4
4
|
import { isGitDirectory, isGitDirectoryClean } from '../utils/utils.git.js';
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { accessSync, constants, readFileSync, readdirSync } from 'node:fs';
|
|
2
2
|
import { join, dirname, normalize, relative } from 'node:path';
|
|
3
|
-
import {
|
|
3
|
+
import { migrationsDebug } from './utils.js';
|
|
4
4
|
|
|
5
5
|
var __defProp = Object.defineProperty;
|
|
6
6
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
7
7
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
8
|
-
const codemodsDebug = debug.extend("codemods");
|
|
9
8
|
class Context {
|
|
10
9
|
constructor(basePath) {
|
|
11
10
|
__publicField(this, "files", {});
|
|
@@ -42,7 +41,7 @@ class Context {
|
|
|
42
41
|
if (originalContent !== content) {
|
|
43
42
|
this.files[path] = { content, changeType: "update" };
|
|
44
43
|
} else {
|
|
45
|
-
|
|
44
|
+
migrationsDebug(`Context.updateFile() - no updates for ${filePath}`);
|
|
46
45
|
}
|
|
47
46
|
}
|
|
48
47
|
doesFileExist(filePath) {
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import defaultMigrations from './migrations.js';
|
|
2
|
-
import { formatFiles, flushChanges, installNPMDependencies } from '../utils.js';
|
|
3
1
|
import { gte, satisfies } from 'semver';
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
7
|
-
import { gitCommitNoVerify } from '
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
2
|
+
import { Context } from './context.js';
|
|
3
|
+
import defaultMigrations from './migrations.js';
|
|
4
|
+
import { migrationsDebug, formatFiles, flushChanges, printChanges, installNPMDependencies } from './utils.js';
|
|
5
|
+
import { gitCommitNoVerify } from '../utils/utils.git.js';
|
|
6
|
+
import { setRootConfig } from '../utils/utils.config.js';
|
|
7
|
+
import { output } from '../utils/utils.console.js';
|
|
8
|
+
import { CURRENT_APP_VERSION } from '../utils/utils.version.js';
|
|
10
9
|
|
|
11
10
|
function getMigrationsToRun(fromVersion, toVersion, migrations = defaultMigrations.migrations) {
|
|
12
11
|
const semverRange = `${fromVersion} - ${toVersion}`;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LEGACY_UPDATE_CUTOFF_VERSION } from '
|
|
1
|
+
import { LEGACY_UPDATE_CUTOFF_VERSION } from '../constants.js';
|
|
2
2
|
|
|
3
3
|
var defaultMigrations = {
|
|
4
4
|
migrations: {
|
|
@@ -21,9 +21,12 @@ var defaultMigrations = {
|
|
|
21
21
|
version: LEGACY_UPDATE_CUTOFF_VERSION,
|
|
22
22
|
description: "Migrate eslint config to flat config format and update devDependencies to latest versions.",
|
|
23
23
|
migrationScript: "./scripts/004-eslint9-flat-config.js"
|
|
24
|
+
},
|
|
25
|
+
"005-react-18-3": {
|
|
26
|
+
version: "6.1.7-beta.1",
|
|
27
|
+
description: "Update React and ReactDOM 18.x versions to ^18.3.0 to surface React 19 compatibility issues.",
|
|
28
|
+
migrationScript: "./scripts/005-react-18-3.js"
|
|
24
29
|
}
|
|
25
|
-
// Do not use LEGACY_UPDATE_CUTOFF_VERSION for new migrations. It is only used above to force migrations to run
|
|
26
|
-
// for those written before the switch to updates as migrations.
|
|
27
30
|
}
|
|
28
31
|
};
|
|
29
32
|
|
package/dist/{codemods/migrations → migrations}/scripts/003-update-eslint-deprecation-rule.js
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { addDependenciesToPackageJson, removeDependenciesFromPackageJson } from '
|
|
1
|
+
import { addDependenciesToPackageJson, removeDependenciesFromPackageJson } from '../utils.js';
|
|
2
2
|
|
|
3
3
|
function migrate(context) {
|
|
4
4
|
if (context.doesFileExist(".config/.eslintrc") && context.doesFileExist("package.json")) {
|
|
@@ -4,8 +4,7 @@ import { parse } from 'jsonc-parser';
|
|
|
4
4
|
import minimist from 'minimist';
|
|
5
5
|
import { resolve, dirname, relative } from 'node:path';
|
|
6
6
|
import * as recast from 'recast';
|
|
7
|
-
import { addDependenciesToPackageJson } from '
|
|
8
|
-
import { migrationsDebug } from '../utils.js';
|
|
7
|
+
import { addDependenciesToPackageJson, migrationsDebug } from '../utils.js';
|
|
9
8
|
|
|
10
9
|
const { builders } = recast.types;
|
|
11
10
|
const legacyKeysToCopy = ["rules", "settings"];
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { isVersionGreater, addDependenciesToPackageJson } from '../utils.js';
|
|
2
|
+
|
|
3
|
+
function migrate(context) {
|
|
4
|
+
if (context.doesFileExist("package.json")) {
|
|
5
|
+
const packageJson = JSON.parse(context.getFile("package.json") || "{}");
|
|
6
|
+
if (packageJson.dependencies?.react) {
|
|
7
|
+
if (isVersionGreater(packageJson.dependencies.react, "18.0.0", true)) {
|
|
8
|
+
addDependenciesToPackageJson(context, { react: "^18.3.0" }, { "@types/react": "^18.3.0" });
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
if (packageJson.dependencies?.["react-dom"]) {
|
|
12
|
+
if (isVersionGreater(packageJson.dependencies["react-dom"], "18.0.0", true)) {
|
|
13
|
+
addDependenciesToPackageJson(context, { "react-dom": "^18.3.0" }, { "@types/react-dom": "^18.3.0" });
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return context;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export { migrate as default };
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { join, dirname } from 'node:path';
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
3
|
import { mkdirSync, writeFileSync, rmSync } from 'node:fs';
|
|
4
|
+
import { debug } from '../utils/utils.cli.js';
|
|
4
5
|
import chalk from 'chalk';
|
|
5
6
|
import { output } from '../utils/utils.console.js';
|
|
6
7
|
import { getPackageManagerWithFallback, getPackageManagerSilentInstallCmd } from '../utils/utils.packageManager.js';
|
|
7
8
|
import { execSync } from 'node:child_process';
|
|
8
|
-
import { gt, clean, coerce } from 'semver';
|
|
9
|
+
import { gte, gt, clean, coerce } from 'semver';
|
|
9
10
|
|
|
10
|
-
function printChanges(context, key,
|
|
11
|
+
function printChanges(context, key, migration) {
|
|
11
12
|
const changes = context.listChanges();
|
|
12
13
|
const lines = [];
|
|
13
14
|
for (const [filePath, { changeType }] of Object.entries(changes)) {
|
|
@@ -20,7 +21,7 @@ function printChanges(context, key, meta) {
|
|
|
20
21
|
}
|
|
21
22
|
}
|
|
22
23
|
output.addHorizontalLine("gray");
|
|
23
|
-
output.logSingleLine(`${key} (${
|
|
24
|
+
output.logSingleLine(`${key} (${migration.description})`);
|
|
24
25
|
if (lines.length === 0) {
|
|
25
26
|
output.logSingleLine("No changes were made");
|
|
26
27
|
} else {
|
|
@@ -42,6 +43,7 @@ function flushChanges(context) {
|
|
|
42
43
|
}
|
|
43
44
|
}
|
|
44
45
|
}
|
|
46
|
+
const migrationsDebug = debug.extend("migrations");
|
|
45
47
|
async function formatFiles(context) {
|
|
46
48
|
let prettier;
|
|
47
49
|
const require = createRequire(import.meta.url);
|
|
@@ -118,10 +120,14 @@ function addDependenciesToPackageJson(context, dependencies, devDependencies = {
|
|
|
118
120
|
if (currentDeps[dep]) {
|
|
119
121
|
if (isVersionGreater(newVersion, currentDeps[dep])) {
|
|
120
122
|
currentDeps[dep] = newVersion;
|
|
123
|
+
} else {
|
|
124
|
+
migrationsDebug("would downgrade dependency %s to %s", dep, newVersion);
|
|
121
125
|
}
|
|
122
126
|
} else if (currentDevDeps[dep]) {
|
|
123
127
|
if (isVersionGreater(newVersion, currentDevDeps[dep])) {
|
|
124
128
|
currentDevDeps[dep] = newVersion;
|
|
129
|
+
} else {
|
|
130
|
+
migrationsDebug("would downgrade devDependency %s to %s", dep, newVersion);
|
|
125
131
|
}
|
|
126
132
|
} else {
|
|
127
133
|
currentDeps[dep] = newVersion;
|
|
@@ -131,10 +137,14 @@ function addDependenciesToPackageJson(context, dependencies, devDependencies = {
|
|
|
131
137
|
if (currentDeps[dep]) {
|
|
132
138
|
if (isVersionGreater(newVersion, currentDeps[dep])) {
|
|
133
139
|
currentDeps[dep] = newVersion;
|
|
140
|
+
} else {
|
|
141
|
+
migrationsDebug("would downgrade dependency %s to %s", dep, newVersion);
|
|
134
142
|
}
|
|
135
143
|
} else if (currentDevDeps[dep]) {
|
|
136
144
|
if (isVersionGreater(newVersion, currentDevDeps[dep])) {
|
|
137
145
|
currentDevDeps[dep] = newVersion;
|
|
146
|
+
} else {
|
|
147
|
+
migrationsDebug("would downgrade devDependency %s to %s", dep, newVersion);
|
|
138
148
|
}
|
|
139
149
|
} else {
|
|
140
150
|
currentDevDeps[dep] = newVersion;
|
|
@@ -151,6 +161,7 @@ function addDependenciesToPackageJson(context, dependencies, devDependencies = {
|
|
|
151
161
|
...Object.keys(sortedDeps).length > 0 && { dependencies: sortedDeps },
|
|
152
162
|
...Object.keys(sortedDevDeps).length > 0 && { devDependencies: sortedDevDeps }
|
|
153
163
|
};
|
|
164
|
+
migrationsDebug("updated package.json", updatedPackageJson);
|
|
154
165
|
context.updateFile(packageJsonPath, JSON.stringify(updatedPackageJson, null, 2));
|
|
155
166
|
}
|
|
156
167
|
function removeDependenciesFromPackageJson(context, dependencies, devDependencies = [], packageJsonPath = "package.json") {
|
|
@@ -159,18 +170,21 @@ function removeDependenciesFromPackageJson(context, dependencies, devDependencie
|
|
|
159
170
|
for (const dep of dependencies) {
|
|
160
171
|
if (currentPackageJson.dependencies?.[dep]) {
|
|
161
172
|
delete currentPackageJson.dependencies[dep];
|
|
173
|
+
migrationsDebug("removed dependency %s", dep);
|
|
162
174
|
hasChanges = true;
|
|
163
175
|
}
|
|
164
176
|
}
|
|
165
177
|
for (const dep of devDependencies) {
|
|
166
178
|
if (currentPackageJson.devDependencies?.[dep]) {
|
|
167
179
|
delete currentPackageJson.devDependencies[dep];
|
|
180
|
+
migrationsDebug("removed devDependency %s", dep);
|
|
168
181
|
hasChanges = true;
|
|
169
182
|
}
|
|
170
183
|
}
|
|
171
184
|
if (!hasChanges) {
|
|
172
185
|
return;
|
|
173
186
|
}
|
|
187
|
+
migrationsDebug("updated package.json", currentPackageJson);
|
|
174
188
|
context.updateFile(packageJsonPath, JSON.stringify(currentPackageJson, null, 2));
|
|
175
189
|
}
|
|
176
190
|
const DIST_TAGS = {
|
|
@@ -178,7 +192,7 @@ const DIST_TAGS = {
|
|
|
178
192
|
next: 1,
|
|
179
193
|
latest: 0
|
|
180
194
|
};
|
|
181
|
-
function isVersionGreater(incomingVersion, existingVersion) {
|
|
195
|
+
function isVersionGreater(incomingVersion, existingVersion, orEqualTo = false) {
|
|
182
196
|
const incomingIsDistTag = incomingVersion in DIST_TAGS;
|
|
183
197
|
const existingIsDistTag = existingVersion in DIST_TAGS;
|
|
184
198
|
if (incomingIsDistTag && existingIsDistTag) {
|
|
@@ -192,6 +206,9 @@ function isVersionGreater(incomingVersion, existingVersion) {
|
|
|
192
206
|
if (!incomingSemver || !existingSemver) {
|
|
193
207
|
return true;
|
|
194
208
|
}
|
|
209
|
+
if (orEqualTo) {
|
|
210
|
+
return gte(incomingSemver, existingSemver);
|
|
211
|
+
}
|
|
195
212
|
return gt(incomingSemver, existingSemver);
|
|
196
213
|
}
|
|
197
214
|
function cleanSemver(version) {
|
|
@@ -201,4 +218,4 @@ function sortObjectByKeys(obj) {
|
|
|
201
218
|
return Object.keys(obj).sort().reduce((acc, key) => ({ ...acc, [key]: obj[key] }), {});
|
|
202
219
|
}
|
|
203
220
|
|
|
204
|
-
export { addDependenciesToPackageJson, flushChanges, formatFiles, installNPMDependencies, isVersionGreater, printChanges, readJsonFile, removeDependenciesFromPackageJson };
|
|
221
|
+
export { addDependenciesToPackageJson, flushChanges, formatFiles, installNPMDependencies, isVersionGreater, migrationsDebug, printChanges, readJsonFile, removeDependenciesFromPackageJson };
|
|
@@ -8,9 +8,6 @@ import path from 'node:path';
|
|
|
8
8
|
import { writeFile } from 'node:fs/promises';
|
|
9
9
|
import { EOL } from 'node:os';
|
|
10
10
|
|
|
11
|
-
function isFeatureEnabled(features, featureName) {
|
|
12
|
-
return features[featureName] === true;
|
|
13
|
-
}
|
|
14
11
|
let hasShownConfigWarnings = false;
|
|
15
12
|
function getConfig(workDir = process.cwd()) {
|
|
16
13
|
const rootConfig = getRootConfig(workDir);
|
|
@@ -95,17 +92,5 @@ async function setRootConfig(configOverride = {}) {
|
|
|
95
92
|
await writeFile(rootConfigPath, JSON.stringify(updatedConfig, null, 2) + EOL);
|
|
96
93
|
return updatedConfig;
|
|
97
94
|
}
|
|
98
|
-
async function setFeatureFlag(featureName, enabled = true) {
|
|
99
|
-
const userConfig = getUserConfig() || { features: {} };
|
|
100
|
-
const userConfigPath = path.resolve(process.cwd(), ".cprc.json");
|
|
101
|
-
const updatedConfig = {
|
|
102
|
-
...userConfig,
|
|
103
|
-
features: {
|
|
104
|
-
...userConfig.features,
|
|
105
|
-
[featureName]: enabled
|
|
106
|
-
}
|
|
107
|
-
};
|
|
108
|
-
await writeFile(userConfigPath, JSON.stringify(updatedConfig, null, 2) + EOL);
|
|
109
|
-
}
|
|
110
95
|
|
|
111
|
-
export { getConfig,
|
|
96
|
+
export { getConfig, setRootConfig };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@grafana/create-plugin",
|
|
3
|
-
"version": "6.2.0-canary.
|
|
3
|
+
"version": "6.2.0-canary.2283.19225164741.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"directory": "packages/create-plugin",
|
|
6
6
|
"url": "https://github.com/grafana/plugin-tools"
|
|
@@ -59,5 +59,5 @@
|
|
|
59
59
|
"engines": {
|
|
60
60
|
"node": ">=20"
|
|
61
61
|
},
|
|
62
|
-
"gitHead": "
|
|
62
|
+
"gitHead": "2771e041152fce899b6ecbbf3a37dce085a4a563"
|
|
63
63
|
}
|
package/src/bin/run.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import minimist from 'minimist';
|
|
4
|
-
import {
|
|
4
|
+
import { generate, update, migrate, version, provisioning } from '../commands/index.js';
|
|
5
5
|
import { isUnsupportedPlatform } from '../utils/utils.os.js';
|
|
6
6
|
import { argv, commandName } from '../utils/utils.cli.js';
|
|
7
7
|
import { output } from '../utils/utils.console.js';
|
|
@@ -23,7 +23,6 @@ const commands: Record<string, (argv: minimist.ParsedArgs) => void> = {
|
|
|
23
23
|
update,
|
|
24
24
|
version,
|
|
25
25
|
provisioning,
|
|
26
|
-
add,
|
|
27
26
|
};
|
|
28
27
|
const command = commands[commandName] || 'generate';
|
|
29
28
|
|
package/src/commands/index.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { Context } from './context.js';
|
|
|
3
3
|
describe('Context', () => {
|
|
4
4
|
describe('getFile', () => {
|
|
5
5
|
it('should read a file from the file system', () => {
|
|
6
|
-
const context = new Context(`${__dirname}/
|
|
6
|
+
const context = new Context(`${__dirname}/fixtures`);
|
|
7
7
|
const content = context.getFile('foo/bar.ts');
|
|
8
8
|
expect(content).toEqual("console.log('foo/bar.ts');\n");
|
|
9
9
|
});
|
|
@@ -16,14 +16,14 @@ describe('Context', () => {
|
|
|
16
16
|
});
|
|
17
17
|
|
|
18
18
|
it('should get a file that was updated in the current context', () => {
|
|
19
|
-
const context = new Context(`${__dirname}/
|
|
19
|
+
const context = new Context(`${__dirname}/fixtures`);
|
|
20
20
|
context.updateFile('foo/bar.ts', 'content');
|
|
21
21
|
const content = context.getFile('foo/bar.ts');
|
|
22
22
|
expect(content).toEqual('content');
|
|
23
23
|
});
|
|
24
24
|
|
|
25
25
|
it('should not return a file that was marked for deletion', () => {
|
|
26
|
-
const context = new Context(`${__dirname}/
|
|
26
|
+
const context = new Context(`${__dirname}/fixtures`);
|
|
27
27
|
context.deleteFile('foo/bar.ts');
|
|
28
28
|
const content = context.getFile('foo/bar.ts');
|
|
29
29
|
expect(content).toEqual(undefined);
|
|
@@ -77,7 +77,7 @@ describe('Context', () => {
|
|
|
77
77
|
|
|
78
78
|
describe('renameFile', () => {
|
|
79
79
|
it('should rename a file', () => {
|
|
80
|
-
const context = new Context(`${__dirname}/
|
|
80
|
+
const context = new Context(`${__dirname}/fixtures`);
|
|
81
81
|
context.renameFile('foo/bar.ts', 'new-file.txt');
|
|
82
82
|
expect(context.listChanges()).toEqual({
|
|
83
83
|
'new-file.txt': { content: "console.log('foo/bar.ts');\n", changeType: 'add' },
|
|
@@ -102,20 +102,20 @@ describe('Context', () => {
|
|
|
102
102
|
|
|
103
103
|
describe('readDir', () => {
|
|
104
104
|
it('should read the directory', () => {
|
|
105
|
-
const context = new Context(`${__dirname}/
|
|
105
|
+
const context = new Context(`${__dirname}/fixtures`);
|
|
106
106
|
const files = context.readDir('foo');
|
|
107
107
|
expect(files).toEqual(['foo/bar.ts', 'foo/baz.ts']);
|
|
108
108
|
});
|
|
109
109
|
|
|
110
110
|
it('should filter out deleted files', () => {
|
|
111
|
-
const context = new Context(`${__dirname}/
|
|
111
|
+
const context = new Context(`${__dirname}/fixtures`);
|
|
112
112
|
context.deleteFile('foo/bar.ts');
|
|
113
113
|
const files = context.readDir('foo');
|
|
114
114
|
expect(files).toEqual(['foo/baz.ts']);
|
|
115
115
|
});
|
|
116
116
|
|
|
117
117
|
it('should include files that are only added to the context', () => {
|
|
118
|
-
const context = new Context(`${__dirname}/
|
|
118
|
+
const context = new Context(`${__dirname}/fixtures`);
|
|
119
119
|
context.addFile('foo/foo.txt', '');
|
|
120
120
|
const files = context.readDir('foo');
|
|
121
121
|
expect(files).toEqual(['foo/bar.ts', 'foo/baz.ts', 'foo/foo.txt']);
|
|
@@ -124,7 +124,7 @@ describe('Context', () => {
|
|
|
124
124
|
|
|
125
125
|
describe('normalisePath', () => {
|
|
126
126
|
it('should normalise the path', () => {
|
|
127
|
-
const context = new Context(`${__dirname}/
|
|
127
|
+
const context = new Context(`${__dirname}/fixtures`);
|
|
128
128
|
expect(context.normalisePath('foo/bar.ts')).toEqual('foo/bar.ts');
|
|
129
129
|
expect(context.normalisePath('./foo/bar.ts')).toEqual('foo/bar.ts');
|
|
130
130
|
expect(context.normalisePath('/foo/bar.ts')).toEqual('foo/bar.ts');
|
|
@@ -133,12 +133,12 @@ describe('Context', () => {
|
|
|
133
133
|
|
|
134
134
|
describe('hasChanges', () => {
|
|
135
135
|
it('should return FALSE if the context has no changes', () => {
|
|
136
|
-
const context = new Context(`${__dirname}/
|
|
136
|
+
const context = new Context(`${__dirname}/fixtures`);
|
|
137
137
|
expect(context.hasChanges()).toEqual(false);
|
|
138
138
|
});
|
|
139
139
|
|
|
140
140
|
it('should return TRUE if the context has changes', () => {
|
|
141
|
-
const context = new Context(`${__dirname}/
|
|
141
|
+
const context = new Context(`${__dirname}/fixtures`);
|
|
142
142
|
|
|
143
143
|
context.addFile('foo.ts', '');
|
|
144
144
|
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { constants, accessSync, readFileSync, readdirSync } from 'node:fs';
|
|
2
2
|
import { relative, normalize, join, dirname } from 'node:path';
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
const codemodsDebug = debug.extend('codemods');
|
|
3
|
+
import { migrationsDebug } from './utils.js';
|
|
6
4
|
|
|
7
5
|
export type ContextFile = Record<
|
|
8
6
|
string,
|
|
@@ -60,7 +58,7 @@ export class Context {
|
|
|
60
58
|
if (originalContent !== content) {
|
|
61
59
|
this.files[path] = { content, changeType: 'update' };
|
|
62
60
|
} else {
|
|
63
|
-
|
|
61
|
+
migrationsDebug(`Context.updateFile() - no updates for ${filePath}`);
|
|
64
62
|
}
|
|
65
63
|
}
|
|
66
64
|
|
|
@@ -1,27 +1,22 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { vi } from 'vitest';
|
|
2
2
|
import { getMigrationsToRun, runMigration, runMigrations } from './manager.js';
|
|
3
|
-
|
|
4
|
-
import { Context } from '../context.js';
|
|
5
|
-
import { MigrationMeta } from './migrations.js';
|
|
6
|
-
import { gitCommitNoVerify } from '../../utils/utils.git.js';
|
|
7
3
|
import migrationFixtures from './fixtures/migrations.js';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
4
|
+
import { Context } from './context.js';
|
|
5
|
+
import { gitCommitNoVerify } from '../utils/utils.git.js';
|
|
6
|
+
import { flushChanges, printChanges, formatFiles } from './utils.js';
|
|
7
|
+
import { setRootConfig } from '../utils/utils.config.js';
|
|
8
|
+
import { MigrationMeta } from './migrations.js';
|
|
11
9
|
|
|
12
10
|
vi.mock('./utils.js', () => ({
|
|
11
|
+
flushChanges: vi.fn(),
|
|
13
12
|
printChanges: vi.fn(),
|
|
14
13
|
migrationsDebug: vi.fn(),
|
|
15
|
-
}));
|
|
16
|
-
|
|
17
|
-
vi.mock('../utils.js', () => ({
|
|
18
|
-
flushChanges: vi.fn(),
|
|
19
14
|
formatFiles: vi.fn(),
|
|
20
15
|
installNPMDependencies: vi.fn(),
|
|
21
16
|
}));
|
|
22
17
|
|
|
23
18
|
// Silence terminal output during tests.
|
|
24
|
-
vi.mock('
|
|
19
|
+
vi.mock('../utils/utils.console.js', () => ({
|
|
25
20
|
output: {
|
|
26
21
|
log: vi.fn(),
|
|
27
22
|
addHorizontalLine: vi.fn(),
|
|
@@ -30,10 +25,10 @@ vi.mock('../../utils/utils.console.js', () => ({
|
|
|
30
25
|
},
|
|
31
26
|
}));
|
|
32
27
|
|
|
33
|
-
vi.mock('
|
|
28
|
+
vi.mock('../utils/utils.config.js', () => ({
|
|
34
29
|
setRootConfig: vi.fn(),
|
|
35
30
|
}));
|
|
36
|
-
vi.mock('
|
|
31
|
+
vi.mock('../utils/utils.git.js', () => ({
|
|
37
32
|
gitCommitNoVerify: vi.fn(),
|
|
38
33
|
}));
|
|
39
34
|
|
|
@@ -122,14 +117,14 @@ describe('Migrations', () => {
|
|
|
122
117
|
const mockContext = new Context('/virtual');
|
|
123
118
|
const migrationFn = vi.fn().mockResolvedValue(mockContext);
|
|
124
119
|
|
|
125
|
-
vi.doMock('
|
|
120
|
+
vi.doMock('virtual-test-migration.js', () => ({
|
|
126
121
|
default: migrationFn,
|
|
127
122
|
}));
|
|
128
123
|
|
|
129
124
|
const migration: MigrationMeta = {
|
|
130
125
|
version: '1.0.0',
|
|
131
126
|
description: 'test migration',
|
|
132
|
-
migrationScript: '
|
|
127
|
+
migrationScript: 'virtual-test-migration.js',
|
|
133
128
|
};
|
|
134
129
|
|
|
135
130
|
const result = await runMigration(migration, mockContext);
|
|
@@ -144,10 +139,10 @@ describe('Migrations', () => {
|
|
|
144
139
|
const migrationTwoFn = vi.fn();
|
|
145
140
|
const consoleMock = vi.spyOn(console, 'log').mockImplementation(() => undefined);
|
|
146
141
|
|
|
147
|
-
vi.doMock('
|
|
142
|
+
vi.doMock('virtual-test-migration.js', async () => ({
|
|
148
143
|
default: migrationOneFn,
|
|
149
144
|
}));
|
|
150
|
-
vi.doMock('
|
|
145
|
+
vi.doMock('virtual-test-migration2.js', async () => ({
|
|
151
146
|
default: migrationTwoFn,
|
|
152
147
|
}));
|
|
153
148
|
|
|
@@ -155,12 +150,12 @@ describe('Migrations', () => {
|
|
|
155
150
|
'migration-one': {
|
|
156
151
|
version: '1.0.0',
|
|
157
152
|
description: '...',
|
|
158
|
-
migrationScript: '
|
|
153
|
+
migrationScript: 'virtual-test-migration.js',
|
|
159
154
|
},
|
|
160
155
|
'migration-two': {
|
|
161
156
|
version: '1.2.0',
|
|
162
157
|
description: '...',
|
|
163
|
-
migrationScript: '
|
|
158
|
+
migrationScript: 'virtual-test-migration2.js',
|
|
164
159
|
},
|
|
165
160
|
};
|
|
166
161
|
|
|
@@ -208,7 +203,7 @@ describe('Migrations', () => {
|
|
|
208
203
|
it('should commit the changes for each migration if the CLI arg is present', async () => {
|
|
209
204
|
await runMigrations(migrations, { commitEachMigration: true });
|
|
210
205
|
|
|
211
|
-
expect(gitCommitNoVerify).toHaveBeenCalledTimes(
|
|
206
|
+
expect(gitCommitNoVerify).toHaveBeenCalledTimes(2);
|
|
212
207
|
});
|
|
213
208
|
|
|
214
209
|
it('should not create a commit for a migration that has no changes', async () => {
|
|
@@ -216,7 +211,7 @@ describe('Migrations', () => {
|
|
|
216
211
|
|
|
217
212
|
await runMigrations(migrations, { commitEachMigration: true });
|
|
218
213
|
|
|
219
|
-
expect(gitCommitNoVerify).toHaveBeenCalledTimes(
|
|
214
|
+
expect(gitCommitNoVerify).toHaveBeenCalledTimes(1);
|
|
220
215
|
});
|
|
221
216
|
|
|
222
217
|
it('should update version in ".config/.cprc.json" on a successful update', async () => {
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
+
import { satisfies, gte } from 'semver';
|
|
2
|
+
import { Context } from './context.js';
|
|
1
3
|
import defaultMigrations, { MigrationMeta } from './migrations.js';
|
|
2
|
-
import { flushChanges, formatFiles, installNPMDependencies } from '
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
4
|
+
import { flushChanges, printChanges, migrationsDebug, formatFiles, installNPMDependencies } from './utils.js';
|
|
5
|
+
import { gitCommitNoVerify } from '../utils/utils.git.js';
|
|
6
|
+
import { setRootConfig } from '../utils/utils.config.js';
|
|
7
|
+
import { output } from '../utils/utils.console.js';
|
|
8
|
+
import { CURRENT_APP_VERSION } from '../utils/utils.version.js';
|
|
5
9
|
|
|
6
|
-
|
|
7
|
-
import { Context } from '../context.js';
|
|
8
|
-
import type { MigrationModule } from '../types.js';
|
|
9
|
-
import { gitCommitNoVerify } from '../../utils/utils.git.js';
|
|
10
|
-
import { output } from '../../utils/utils.console.js';
|
|
11
|
-
import { setRootConfig } from '../../utils/utils.config.js';
|
|
10
|
+
export type MigrationFn = (context: Context) => Context | Promise<Context>;
|
|
12
11
|
|
|
13
12
|
export function getMigrationsToRun(
|
|
14
13
|
fromVersion: string,
|
|
@@ -77,7 +76,7 @@ export async function runMigrations(migrations: Record<string, MigrationMeta>, o
|
|
|
77
76
|
}
|
|
78
77
|
|
|
79
78
|
export async function runMigration(migration: MigrationMeta, context: Context): Promise<Context> {
|
|
80
|
-
const module =
|
|
79
|
+
const module: { default: MigrationFn } = await import(migration.migrationScript);
|
|
81
80
|
|
|
82
81
|
return module.default(context);
|
|
83
82
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import defaultMigrations from './migrations.js';
|
|
4
|
+
|
|
5
|
+
describe('migrations json', () => {
|
|
6
|
+
// As migration scripts are imported dynamically when update is run we assert the path is valid
|
|
7
|
+
// Vitest 4 reimplemented it's workers which caused the previous dynamic import tests to fail.
|
|
8
|
+
// This test now only asserts that the source file exists.
|
|
9
|
+
Object.entries(defaultMigrations.migrations).forEach(([key, migration]) => {
|
|
10
|
+
it(`should have a valid migration script path for ${key}`, () => {
|
|
11
|
+
const migrationPathString = migration.migrationScript.replace('.js', '.ts');
|
|
12
|
+
const path = join(__dirname, migrationPathString);
|
|
13
|
+
expect(existsSync(path)).toBe(true);
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LEGACY_UPDATE_CUTOFF_VERSION } from '
|
|
1
|
+
import { LEGACY_UPDATE_CUTOFF_VERSION } from '../constants.js';
|
|
2
2
|
|
|
3
3
|
export type MigrationMeta = {
|
|
4
4
|
version: string;
|
|
@@ -10,6 +10,8 @@ type Migrations = {
|
|
|
10
10
|
migrations: Record<string, MigrationMeta>;
|
|
11
11
|
};
|
|
12
12
|
|
|
13
|
+
// Do not use LEGACY_UPDATE_CUTOFF_VERSION for new migrations. It was used to force migrations to run
|
|
14
|
+
// for those written before the switch to updates as migrations.
|
|
13
15
|
export default {
|
|
14
16
|
migrations: {
|
|
15
17
|
'001-update-grafana-compose-extend': {
|
|
@@ -33,7 +35,10 @@ export default {
|
|
|
33
35
|
description: 'Migrate eslint config to flat config format and update devDependencies to latest versions.',
|
|
34
36
|
migrationScript: './scripts/004-eslint9-flat-config.js',
|
|
35
37
|
},
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
'005-react-18-3': {
|
|
39
|
+
version: '6.1.7-beta.1',
|
|
40
|
+
description: 'Update React and ReactDOM 18.x versions to ^18.3.0 to surface React 19 compatibility issues.',
|
|
41
|
+
migrationScript: './scripts/005-react-18-3.js',
|
|
42
|
+
},
|
|
38
43
|
},
|
|
39
44
|
} as Migrations;
|