@grafana/create-plugin 1.3.0-canary.226.e756884.0 → 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/CHANGELOG.md CHANGED
@@ -1,3 +1,25 @@
1
+ # v1.3.0 (Fri Apr 28 2023)
2
+
3
+ #### 🚀 Enhancement
4
+
5
+ - Create Plugin: Support different Node package managers [#226](https://github.com/grafana/plugin-tools/pull/226) ([@jackw](https://github.com/jackw))
6
+
7
+ #### 🐛 Bug Fix
8
+
9
+ - Documentation: Fix path in for template README.md for jest customizations [#218](https://github.com/grafana/plugin-tools/pull/218) ([@briangann](https://github.com/briangann))
10
+
11
+ #### 🔩 Dependency Updates
12
+
13
+ - Chore: Update `glob` to v10 [#230](https://github.com/grafana/plugin-tools/pull/230) ([@leventebalogh](https://github.com/leventebalogh))
14
+
15
+ #### Authors: 3
16
+
17
+ - Brian Gann ([@briangann](https://github.com/briangann))
18
+ - Jack Westbrook ([@jackw](https://github.com/jackw))
19
+ - Levente Balogh ([@leventebalogh](https://github.com/leventebalogh))
20
+
21
+ ---
22
+
1
23
  # v1.2.1 (Thu Mar 30 2023)
2
24
 
3
25
  #### 🐛 Bug Fix
@@ -15,11 +15,11 @@ var utils_handlebars_1 = require("../../utils/utils.handlebars");
15
15
  var utils_packageManager_1 = require("../../utils/utils.packageManager");
16
16
  function printGenerateSuccessMessage(answers) {
17
17
  var directory = (0, utils_handlebars_1.normalizeId)(answers.pluginName, answers.orgName, answers.pluginType);
18
- var packageManager = (0, utils_packageManager_1.getPackageManagerFromUserAgent)().packageManager;
18
+ var packageManagerName = (0, utils_packageManager_1.getPackageManagerFromUserAgent)().packageManagerName;
19
19
  var commands = __spreadArray(__spreadArray([
20
20
  "- `cd ./".concat(directory, "`"),
21
- "- `".concat(packageManager, " install` to install frontend dependencies."),
22
- "- `".concat(packageManager, " run dev` to build (and watch) the plugin frontend code.")
21
+ "- `".concat(packageManagerName, " install` to install frontend dependencies."),
22
+ "- `".concat(packageManagerName, " run dev` to build (and watch) the plugin frontend code.")
23
23
  ], (answers.hasBackend
24
24
  ? [
25
25
  '- `mage -v build:linux` to build the plugin backend code. Rerun this command every time you edit your backend files.',
@@ -98,17 +98,18 @@ function default_1(plop) {
98
98
  var pluginName = _a.pluginName, orgName = _a.orgName, pluginType = _a.pluginType, hasBackend = _a.hasBackend, hasGithubWorkflows = _a.hasGithubWorkflows, hasGithubLevitateWorkflow = _a.hasGithubLevitateWorkflow;
99
99
  var exportPath = (0, utils_path_1.getExportPath)(pluginName, orgName, pluginType);
100
100
  var pluginId = (0, utils_handlebars_1.normalizeId)(pluginName, orgName, pluginType);
101
- var _b = (0, utils_packageManager_1.getPackageManagerFromUserAgent)(), packageManager = _b.packageManager, packageManagerVersion = _b.version;
102
- var packageManagerInstallCmd = (0, utils_packageManager_1.getPackageManagerInstallCmd)(packageManager);
101
+ var _b = (0, utils_packageManager_1.getPackageManagerFromUserAgent)(), packageManagerName = _b.packageManagerName, packageManagerVersion = _b.packageManagerVersion;
102
+ var packageManagerInstallCmd = (0, utils_packageManager_1.getPackageManagerInstallCmd)(packageManagerName);
103
+ var templateData = {
104
+ pluginId: pluginId,
105
+ packageManagerName: packageManagerName,
106
+ packageManagerInstallCmd: packageManagerInstallCmd,
107
+ packageManagerVersion: packageManagerVersion
108
+ };
103
109
  var commonActions = getActionsForTemplateFolder({
104
110
  folderPath: constants_1.TEMPLATE_PATHS.common,
105
111
  exportPath: exportPath,
106
- templateData: {
107
- pluginId: pluginId,
108
- packageManager: packageManager,
109
- packageManagerInstallCmd: packageManagerInstallCmd,
110
- packageManagerVersion: packageManagerVersion
111
- }
112
+ templateData: templateData
112
113
  });
113
114
  var pluginTypeSpecificActions = getActionsForTemplateFolder({
114
115
  folderPath: constants_1.TEMPLATE_PATHS[pluginType],
@@ -130,17 +131,17 @@ function default_1(plop) {
130
131
  ? getActionsForTemplateFolder({
131
132
  folderPath: constants_1.TEMPLATE_PATHS.ciWorkflows,
132
133
  exportPath: exportPath,
133
- templateData: {
134
- packageManager: packageManager,
135
- packageManagerInstallCmd: packageManagerInstallCmd,
136
- packageManagerVersion: packageManagerVersion
137
- }
134
+ templateData: templateData
138
135
  })
139
136
  : [];
140
137
  var isCompatibleWorkflowActions = hasGithubLevitateWorkflow
141
- ? getActionsForTemplateFolder({ folderPath: constants_1.TEMPLATE_PATHS.isCompatibleWorkflow, exportPath: exportPath })
138
+ ? getActionsForTemplateFolder({
139
+ folderPath: constants_1.TEMPLATE_PATHS.isCompatibleWorkflow,
140
+ exportPath: exportPath,
141
+ templateData: templateData
142
+ })
142
143
  : [];
143
- var readmeActions = getActionsForReadme({ exportPath: exportPath });
144
+ var readmeActions = getActionsForReadme({ exportPath: exportPath, templateData: templateData });
144
145
  return __spreadArray(__spreadArray(__spreadArray(__spreadArray(__spreadArray([], pluginActions, true), ciWorkflowActions, true), readmeActions, true), isCompatibleWorkflowActions, true), [
145
146
  {
146
147
  type: 'updateGoSdkAndModules'
@@ -154,26 +155,30 @@ function default_1(plop) {
154
155
  }
155
156
  exports["default"] = default_1;
156
157
  function getActionsForReadme(_a) {
157
- var exportPath = _a.exportPath;
158
+ var exportPath = _a.exportPath, templateData = _a.templateData;
158
159
  return [
159
- replacePatternWithTemplateInReadme('-- INSERT FRONTEND GETTING STARTED --', 'frontend-getting-started.md', exportPath),
160
- replacePatternWithTemplateInReadme('-- INSERT BACKEND GETTING STARTED --', 'backend-getting-started.md', exportPath),
161
- replacePatternWithTemplateInReadme('-- INSERT DISTRIBUTING YOUR PLUGIN --', 'distributing-your-plugin.md', exportPath),
160
+ replacePatternWithTemplateInReadme('-- INSERT FRONTEND GETTING STARTED --', 'frontend-getting-started.md', exportPath, templateData),
161
+ replacePatternWithTemplateInReadme('-- INSERT BACKEND GETTING STARTED --', 'backend-getting-started.md', exportPath, templateData),
162
+ replacePatternWithTemplateInReadme('-- INSERT DISTRIBUTING YOUR PLUGIN --', 'distributing-your-plugin.md', exportPath, templateData),
162
163
  ];
163
164
  }
164
- function replacePatternWithTemplateInReadme(pattern, partialsFile, exportPath) {
165
+ function replacePatternWithTemplateInReadme(pattern, partialsFile, exportPath, templateData) {
166
+ if (templateData === void 0) { templateData = {}; }
165
167
  return {
166
168
  type: 'modify',
167
169
  path: path_1["default"].join(exportPath, 'README.md'),
168
170
  pattern: pattern,
169
171
  template: undefined,
170
172
  templateFile: path_1["default"].join(constants_1.PARTIALS_DIR, partialsFile),
171
- data: constants_1.EXTRA_TEMPLATE_VARIABLES
173
+ data: __assign(__assign({}, constants_1.EXTRA_TEMPLATE_VARIABLES), templateData)
172
174
  };
173
175
  }
174
176
  function getActionsForTemplateFolder(_a) {
175
177
  var folderPath = _a.folderPath, exportPath = _a.exportPath, _b = _a.templateData, templateData = _b === void 0 ? {} : _b;
176
178
  var files = glob_1["default"].sync("".concat(folderPath, "/**"), { dot: true });
179
+ if (templateData.packageManagerName !== 'pnpm') {
180
+ files = files.filter(function (file) { return path_1["default"].basename(file) !== 'npmrc'; });
181
+ }
177
182
  function getExportFileName(f) {
178
183
  if (path_1["default"].basename(f) === 'gitignore') {
179
184
  return '.gitignore';
@@ -186,11 +191,6 @@ function getActionsForTemplateFolder(_a) {
186
191
  function getExportPath(f) {
187
192
  return path_1["default"].relative(folderPath, path_1["default"].dirname(f));
188
193
  }
189
- if (templateData.packageManager !== 'pnpm') {
190
- files = files.filter(function (file) {
191
- return path_1["default"].basename(file) !== 'npmrc';
192
- });
193
- }
194
194
  return files.filter(isFile).map(function (f) { return ({
195
195
  type: 'add',
196
196
  templateFile: f,
@@ -122,7 +122,7 @@ var migrate = function () { return __awaiter(void 0, void 0, void 0, function ()
122
122
  (0, utils_console_1.printMessage)(constants_1.TEXT.updateNpmScriptsAborted);
123
123
  }
124
124
  packageManager = (0, utils_packageManager_1.getPackageManagerWithFallback)();
125
- (0, utils_npm_1.writePackageManager)(packageManager);
125
+ (0, utils_npm_1.writePackageManagerInPackageJson)(packageManager);
126
126
  (0, utils_npm_1.cleanUpPackageJson)();
127
127
  (0, utils_console_1.printSuccessMessage)(constants_1.TEXT.migrationCommandSuccess);
128
128
  return [3, 12];
@@ -95,7 +95,7 @@ var update = function () { return __awaiter(void 0, void 0, void 0, function ()
95
95
  (0, utils_console_1.printMessage)(constants_1.TEXT.updateNpmScriptsAborted);
96
96
  }
97
97
  packageManager = (0, utils_packageManager_1.getPackageManagerWithFallback)();
98
- (0, utils_npm_1.writePackageManager)(packageManager);
98
+ (0, utils_npm_1.writePackageManagerInPackageJson)(packageManager);
99
99
  (0, utils_console_1.printSuccessMessage)(constants_1.TEXT.updateCommandSuccess);
100
100
  return [3, 6];
101
101
  case 5:
@@ -14,7 +14,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
14
14
  return (mod && mod.__esModule) ? mod : { "default": mod };
15
15
  };
16
16
  exports.__esModule = true;
17
- exports.cleanUpPackageJson = exports.writePackageManager = exports.updateNpmScripts = exports.removeNpmDependencies = exports.getRemovableNpmDependencies = exports.getUpdatableNpmDependencies = exports.getPackageJsonUpdates = exports.updateNpmDependencies = exports.updatePackageJson = exports.hasNpmDependenciesToUpdate = exports.getPackageJsonUpdatesAsText = exports.getNpmDependencyUpdatesAsText = exports.writePackageJson = exports.getLatestPackageJson = exports.getPackageJson = void 0;
17
+ exports.cleanUpPackageJson = exports.writePackageManagerInPackageJson = exports.updateNpmScripts = exports.removeNpmDependencies = exports.getRemovableNpmDependencies = exports.getUpdatableNpmDependencies = exports.getPackageJsonUpdates = exports.updateNpmDependencies = exports.updatePackageJson = exports.hasNpmDependenciesToUpdate = exports.getPackageJsonUpdatesAsText = exports.getNpmDependencyUpdatesAsText = exports.writePackageJson = exports.getLatestPackageJson = exports.getPackageJson = void 0;
18
18
  var path_1 = __importDefault(require("path"));
19
19
  var fs_1 = __importDefault(require("fs"));
20
20
  var semver_1 = __importDefault(require("semver"));
@@ -204,15 +204,15 @@ function updateNpmScripts() {
204
204
  writePackageJson(packageJson);
205
205
  }
206
206
  exports.updateNpmScripts = updateNpmScripts;
207
- function writePackageManager(_a) {
208
- var packageManager = _a.packageManager, version = _a.version;
207
+ function writePackageManagerInPackageJson(_a) {
208
+ var packageManagerName = _a.packageManagerName, packageManagerVersion = _a.packageManagerVersion;
209
209
  var packageJson = getPackageJson();
210
210
  if (!packageJson.packageManager) {
211
- packageJson.packageManager = "".concat(packageManager, "@").concat(version);
211
+ packageJson.packageManager = "".concat(packageManagerName, "@").concat(packageManagerVersion);
212
212
  writePackageJson(packageJson);
213
213
  }
214
214
  }
215
- exports.writePackageManager = writePackageManager;
215
+ exports.writePackageManagerInPackageJson = writePackageManagerInPackageJson;
216
216
  function cleanUpPackageJson() {
217
217
  var packageJson = getPackageJson();
218
218
  packageJson.scripts = sortKeysAlphabetically(packageJson.scripts);
@@ -9,15 +9,15 @@ var NPM_LOCKFILE = 'package-lock.json';
9
9
  var PNPM_LOCKFILE = 'pnpm-lock.yaml';
10
10
  var YARN_LOCKFILE = 'yarn.lock';
11
11
  var SUPPORTED_PACKAGE_MANAGERS = ['npm', 'yarn', 'pnpm'];
12
- var LEGACY_PACKAGE_MANAGER = { packageManager: 'yarn', version: '1.22.19' };
12
+ var DEFAULT_PACKAGE_MANAGER = { packageManagerName: 'yarn', packageManagerVersion: '1.22.19' };
13
13
  function getPackageManagerFromUserAgent() {
14
14
  var agent = process.env.npm_config_user_agent;
15
- var _a = agent.split('/'), packageManager = _a[0], versionWithText = _a[1];
15
+ var _a = agent.split('/'), name = _a[0], versionWithText = _a[1];
16
16
  var version = versionWithText.split(' ')[0];
17
- if (SUPPORTED_PACKAGE_MANAGERS.includes(packageManager)) {
18
- return { packageManager: packageManager, version: version.trimEnd() };
17
+ if (SUPPORTED_PACKAGE_MANAGERS.includes(name)) {
18
+ return { packageManagerName: name, packageManagerVersion: version.trimEnd() };
19
19
  }
20
- return LEGACY_PACKAGE_MANAGER;
20
+ return DEFAULT_PACKAGE_MANAGER;
21
21
  }
22
22
  exports.getPackageManagerFromUserAgent = getPackageManagerFromUserAgent;
23
23
  function getPackageManagerWithFallback() {
@@ -29,11 +29,11 @@ function getPackageManagerWithFallback() {
29
29
  if (packageManagerFromLockFile) {
30
30
  return packageManagerFromLockFile;
31
31
  }
32
- return LEGACY_PACKAGE_MANAGER;
32
+ return DEFAULT_PACKAGE_MANAGER;
33
33
  }
34
34
  exports.getPackageManagerWithFallback = getPackageManagerWithFallback;
35
- function getPackageManagerInstallCmd(packageManager) {
36
- switch (packageManager) {
35
+ function getPackageManagerInstallCmd(packageManagerName) {
36
+ switch (packageManagerName) {
37
37
  case 'yarn':
38
38
  return 'yarn install --immutable --prefer-offline';
39
39
  case 'pnpm':
@@ -54,35 +54,35 @@ function getPackageManagerFromLockFile() {
54
54
  var npmVersionCommand = (0, child_process_1.spawnSync)('npm', ['--version'], {
55
55
  shell: true
56
56
  });
57
- var version = npmVersionCommand.stdout.toString().trimEnd();
58
- return { packageManager: 'npm', version: version };
57
+ var packageManagerVersion = npmVersionCommand.stdout.toString().trimEnd();
58
+ return { packageManagerName: 'npm', packageManagerVersion: packageManagerVersion };
59
59
  }
60
60
  if (closestLockfile === PNPM_LOCKFILE) {
61
61
  var pnpmVersionCommand = (0, child_process_1.spawnSync)('pnpm', ['--version'], {
62
62
  shell: true
63
63
  });
64
- var version = pnpmVersionCommand.stdout.toString().trimEnd();
65
- return { packageManager: 'pnpm', version: version };
64
+ var packageManagerVersion = pnpmVersionCommand.stdout.toString().trimEnd();
65
+ return { packageManagerName: 'pnpm', packageManagerVersion: packageManagerVersion };
66
66
  }
67
67
  if (closestLockfile === YARN_LOCKFILE) {
68
68
  var yarnVersionCommand = (0, child_process_1.spawnSync)('yarn', ['--version'], {
69
69
  shell: true
70
70
  });
71
- var version = yarnVersionCommand.stdout.toString().trimEnd();
72
- return { packageManager: 'yarn', version: version };
71
+ var packageManagerVersion = yarnVersionCommand.stdout.toString().trimEnd();
72
+ return { packageManagerName: 'yarn', packageManagerVersion: packageManagerVersion };
73
73
  }
74
74
  return undefined;
75
75
  }
76
76
  catch (error) {
77
- console.error('Failed to find package manager from lock file');
77
+ console.error('Failed to find package manager from lock file. Have you installed dependencies?');
78
78
  throw Error(error);
79
79
  }
80
80
  }
81
81
  function getPackageManagerFromPackageJson() {
82
82
  var packageJson = (0, utils_npm_1.getPackageJson)();
83
83
  if (packageJson.hasOwnProperty('packageManager')) {
84
- var _a = packageJson.packageManager.split('@'), packageManager = _a[0], version = _a[1];
85
- return { packageManager: packageManager, version: version };
84
+ var _a = packageJson.packageManager.split('@'), packageManagerName = _a[0], packageManagerVersion = _a[1];
85
+ return { packageManagerName: packageManagerName, packageManagerVersion: packageManagerVersion };
86
86
  }
87
87
  return undefined;
88
88
  }
@@ -73,7 +73,7 @@ exports.renderTemplateFromFile = renderTemplateFromFile;
73
73
  function getTemplateData() {
74
74
  var _a, _b, _c;
75
75
  var pluginJson = (0, utils_plugin_1.getPluginJson)();
76
- var _d = (0, utils_packageManager_1.getPackageManagerWithFallback)(), packageManager = _d.packageManager, packageManagerVersion = _d.version;
77
- return __assign(__assign({}, constants_1.EXTRA_TEMPLATE_VARIABLES), { pluginId: pluginJson.id, pluginName: pluginJson.name, pluginDescription: (_a = pluginJson.info) === null || _a === void 0 ? void 0 : _a.description, hasBackend: Boolean(pluginJson.backend), orgName: (_c = (_b = pluginJson.info) === null || _b === void 0 ? void 0 : _b.author) === null || _c === void 0 ? void 0 : _c.name, pluginType: pluginJson.type, packageManager: packageManager, packageManagerVersion: packageManagerVersion });
76
+ var _d = (0, utils_packageManager_1.getPackageManagerWithFallback)(), packageManagerName = _d.packageManagerName, packageManagerVersion = _d.packageManagerVersion;
77
+ return __assign(__assign({}, constants_1.EXTRA_TEMPLATE_VARIABLES), { pluginId: pluginJson.id, pluginName: pluginJson.name, pluginDescription: (_a = pluginJson.info) === null || _a === void 0 ? void 0 : _a.description, hasBackend: Boolean(pluginJson.backend), orgName: (_c = (_b = pluginJson.info) === null || _b === void 0 ? void 0 : _b.author) === null || _c === void 0 ? void 0 : _c.name, pluginType: pluginJson.type, packageManagerName: packageManagerName, packageManagerVersion: packageManagerVersion });
78
78
  }
79
79
  exports.getTemplateData = getTemplateData;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grafana/create-plugin",
3
- "version": "1.3.0-canary.226.e756884.0",
3
+ "version": "1.3.0",
4
4
  "main": "index.js",
5
5
  "repository": {
6
6
  "directory": "packages/create-plugin",
@@ -64,5 +64,5 @@
64
64
  "engines": {
65
65
  "node": ">=16"
66
66
  },
67
- "gitHead": "e7568843214a01dd1a86c2bb24d9a77e01982bdb"
67
+ "gitHead": "75bcdffdcffa1302a0ef270e149c58c4f921a7a7"
68
68
  }
@@ -5,11 +5,11 @@ import { CliArgs } from '../types';
5
5
 
6
6
  export function printGenerateSuccessMessage(answers: CliArgs) {
7
7
  const directory = normalizeId(answers.pluginName, answers.orgName, answers.pluginType);
8
- const { packageManager } = getPackageManagerFromUserAgent();
8
+ const { packageManagerName } = getPackageManagerFromUserAgent();
9
9
  const commands = [
10
10
  `- \`cd ./${directory}\``,
11
- `- \`${packageManager} install\` to install frontend dependencies.`,
12
- `- \`${packageManager} run dev\` to build (and watch) the plugin frontend code.`,
11
+ `- \`${packageManagerName} install\` to install frontend dependencies.`,
12
+ `- \`${packageManagerName} run dev\` to build (and watch) the plugin frontend code.`,
13
13
  ...(answers.hasBackend
14
14
  ? [
15
15
  '- `mage -v build:linux` to build the plugin backend code. Rerun this command every time you edit your backend files.',
@@ -86,19 +86,19 @@ export default function (plop: NodePlopAPI) {
86
86
  const exportPath = getExportPath(pluginName, orgName, pluginType);
87
87
  const pluginId = normalizeId(pluginName, orgName, pluginType);
88
88
  // Support the users package manager of choice.
89
- const { packageManager, version: packageManagerVersion } = getPackageManagerFromUserAgent();
90
- const packageManagerInstallCmd = getPackageManagerInstallCmd(packageManager);
91
-
89
+ const { packageManagerName, packageManagerVersion } = getPackageManagerFromUserAgent();
90
+ const packageManagerInstallCmd = getPackageManagerInstallCmd(packageManagerName);
91
+ const templateData = {
92
+ pluginId,
93
+ packageManagerName,
94
+ packageManagerInstallCmd,
95
+ packageManagerVersion,
96
+ };
92
97
  // Copy over files that are shared between plugins types
93
98
  const commonActions = getActionsForTemplateFolder({
94
99
  folderPath: TEMPLATE_PATHS.common,
95
100
  exportPath,
96
- templateData: {
97
- pluginId,
98
- packageManager,
99
- packageManagerInstallCmd,
100
- packageManagerVersion,
101
- },
101
+ templateData,
102
102
  });
103
103
 
104
104
  // Copy over files from the plugin type specific folder, e.g. "templates/app" for "app" plugins ("app" | "panel" | "datasource").
@@ -132,20 +132,20 @@ export default function (plop: NodePlopAPI) {
132
132
  ? getActionsForTemplateFolder({
133
133
  folderPath: TEMPLATE_PATHS.ciWorkflows,
134
134
  exportPath,
135
- templateData: {
136
- packageManager,
137
- packageManagerInstallCmd,
138
- packageManagerVersion,
139
- },
135
+ templateData,
140
136
  })
141
137
  : [];
142
138
 
143
139
  const isCompatibleWorkflowActions = hasGithubLevitateWorkflow
144
- ? getActionsForTemplateFolder({ folderPath: TEMPLATE_PATHS.isCompatibleWorkflow, exportPath })
140
+ ? getActionsForTemplateFolder({
141
+ folderPath: TEMPLATE_PATHS.isCompatibleWorkflow,
142
+ exportPath,
143
+ templateData,
144
+ })
145
145
  : [];
146
146
 
147
147
  // Replace conditional bits in the Readme files
148
- const readmeActions = getActionsForReadme({ exportPath });
148
+ const readmeActions = getActionsForReadme({ exportPath, templateData });
149
149
 
150
150
  return [
151
151
  ...pluginActions,
@@ -163,22 +163,31 @@ export default function (plop: NodePlopAPI) {
163
163
  });
164
164
  }
165
165
 
166
- function getActionsForReadme({ exportPath }: { exportPath: string }): ModifyActionConfig[] {
166
+ function getActionsForReadme({
167
+ exportPath,
168
+ templateData,
169
+ }: {
170
+ exportPath: string;
171
+ templateData: Record<string, string>;
172
+ }): ModifyActionConfig[] {
167
173
  return [
168
174
  replacePatternWithTemplateInReadme(
169
175
  '-- INSERT FRONTEND GETTING STARTED --',
170
176
  'frontend-getting-started.md',
171
- exportPath
177
+ exportPath,
178
+ templateData
172
179
  ),
173
180
  replacePatternWithTemplateInReadme(
174
181
  '-- INSERT BACKEND GETTING STARTED --',
175
182
  'backend-getting-started.md',
176
- exportPath
183
+ exportPath,
184
+ templateData
177
185
  ),
178
186
  replacePatternWithTemplateInReadme(
179
187
  '-- INSERT DISTRIBUTING YOUR PLUGIN --',
180
188
  'distributing-your-plugin.md',
181
- exportPath
189
+ exportPath,
190
+ templateData
182
191
  ),
183
192
  ];
184
193
  }
@@ -186,7 +195,8 @@ function getActionsForReadme({ exportPath }: { exportPath: string }): ModifyActi
186
195
  function replacePatternWithTemplateInReadme(
187
196
  pattern: string,
188
197
  partialsFile: string,
189
- exportPath: string
198
+ exportPath: string,
199
+ templateData: Record<string, string> = {}
190
200
  ): ModifyActionConfig {
191
201
  return {
192
202
  type: 'modify',
@@ -195,7 +205,10 @@ function replacePatternWithTemplateInReadme(
195
205
  // @ts-ignore
196
206
  template: undefined,
197
207
  templateFile: path.join(PARTIALS_DIR, partialsFile),
198
- data: EXTRA_TEMPLATE_VARIABLES,
208
+ data: {
209
+ ...EXTRA_TEMPLATE_VARIABLES,
210
+ ...templateData,
211
+ },
199
212
  };
200
213
  }
201
214
 
@@ -210,6 +223,12 @@ function getActionsForTemplateFolder({
210
223
  templateData?: Record<string, string>;
211
224
  }) {
212
225
  let files = glob.sync(`${folderPath}/**`, { dot: true });
226
+
227
+ // The npmrc file is only useful for `pnpm` settings. We can remove it for other package managers.
228
+ if (templateData.packageManagerName !== 'pnpm') {
229
+ files = files.filter((file) => path.basename(file) !== 'npmrc');
230
+ }
231
+
213
232
  function getExportFileName(f: string) {
214
233
  // yarn and npm packing will not include `.gitignore` files
215
234
  // so we have to manually rename them to add the dot prefix
@@ -222,17 +241,11 @@ function getActionsForTemplateFolder({
222
241
 
223
242
  return path.extname(f) === '.hbs' ? path.basename(f, '.hbs') : path.basename(f);
224
243
  }
244
+
225
245
  function getExportPath(f: string) {
226
246
  return path.relative(folderPath, path.dirname(f));
227
247
  }
228
248
 
229
- // Remove the npmrc file if not running `pnpm`.
230
- if (templateData.packageManager !== 'pnpm') {
231
- files = files.filter((file) => {
232
- return path.basename(file) !== 'npmrc';
233
- });
234
- }
235
-
236
249
  return files.filter(isFile).map((f) => ({
237
250
  type: 'add',
238
251
  templateFile: f,
@@ -10,7 +10,7 @@ import {
10
10
  removeNpmDependencies,
11
11
  updateNpmScripts,
12
12
  cleanUpPackageJson,
13
- writePackageManager,
13
+ writePackageManagerInPackageJson,
14
14
  } from '../utils/utils.npm';
15
15
  import { getPackageManagerWithFallback } from '../utils/utils.packageManager';
16
16
 
@@ -97,9 +97,9 @@ export const migrate = async () => {
97
97
  printMessage(TEXT.updateNpmScriptsAborted);
98
98
  }
99
99
 
100
- // Guarantee that the package manager property is set in the package.json file
100
+ // Guarantee that the package manager property is set in the package.json file if it is missing
101
101
  const packageManager = getPackageManagerWithFallback();
102
- writePackageManager(packageManager);
102
+ writePackageManagerInPackageJson(packageManager);
103
103
 
104
104
  // Tidy package.json file so any changed fields are sorted as a
105
105
  // package manager would expect.
@@ -6,7 +6,7 @@ import {
6
6
  hasNpmDependenciesToUpdate,
7
7
  getPackageJsonUpdatesAsText,
8
8
  updateNpmScripts,
9
- writePackageManager,
9
+ writePackageManagerInPackageJson,
10
10
  } from '../utils/utils.npm';
11
11
  import { getPackageManagerWithFallback } from '../utils/utils.packageManager';
12
12
 
@@ -67,9 +67,9 @@ export const update = async () => {
67
67
  printMessage(TEXT.updateNpmScriptsAborted);
68
68
  }
69
69
 
70
- // Guarantee that the package manager property is set in the package.json file
70
+ // Guarantee that the package manager property is set in the package.json file if it is missing
71
71
  const packageManager = getPackageManagerWithFallback();
72
- writePackageManager(packageManager);
72
+ writePackageManagerInPackageJson(packageManager);
73
73
 
74
74
  // 4. Summary
75
75
  // -------------
@@ -4,6 +4,7 @@ import semver from 'semver';
4
4
  import { readJsonFile } from './utils.files';
5
5
  import { renderTemplateFromFile, getTemplateData } from './utils.templates';
6
6
  import { GRAFANA_FE_PACKAGES, TEMPLATE_PATHS } from '../constants';
7
+ import { PackageManager } from './utils.packageManager';
7
8
 
8
9
  type UpdateSummary = Record<string, { prev: string | null; next: string | null }>;
9
10
 
@@ -237,10 +238,10 @@ export function updateNpmScripts() {
237
238
  writePackageJson(packageJson);
238
239
  }
239
240
 
240
- export function writePackageManager({ packageManager, version }: { packageManager: string; version: string }) {
241
+ export function writePackageManagerInPackageJson({ packageManagerName, packageManagerVersion }: PackageManager) {
241
242
  const packageJson = getPackageJson();
242
243
  if (!packageJson.packageManager) {
243
- packageJson.packageManager = `${packageManager}@${version}`;
244
+ packageJson.packageManager = `${packageManagerName}@${packageManagerVersion}`;
244
245
  writePackageJson(packageJson);
245
246
  }
246
247
  }
@@ -7,19 +7,24 @@ const NPM_LOCKFILE = 'package-lock.json';
7
7
  const PNPM_LOCKFILE = 'pnpm-lock.yaml';
8
8
  const YARN_LOCKFILE = 'yarn.lock';
9
9
  const SUPPORTED_PACKAGE_MANAGERS = ['npm', 'yarn', 'pnpm'];
10
- const LEGACY_PACKAGE_MANAGER = { packageManager: 'yarn', version: '1.22.19' };
10
+ const DEFAULT_PACKAGE_MANAGER = { packageManagerName: 'yarn', packageManagerVersion: '1.22.19' };
11
11
 
12
- export function getPackageManagerFromUserAgent() {
12
+ export type PackageManager = {
13
+ packageManagerName: string;
14
+ packageManagerVersion: string;
15
+ };
16
+
17
+ export function getPackageManagerFromUserAgent(): PackageManager {
13
18
  const agent = process.env.npm_config_user_agent;
14
19
 
15
- const [packageManager, versionWithText] = agent.split('/');
20
+ const [name, versionWithText] = agent.split('/');
16
21
  const [version] = versionWithText.split(' ');
17
22
 
18
- if (SUPPORTED_PACKAGE_MANAGERS.includes(packageManager)) {
19
- return { packageManager, version: version.trimEnd() };
23
+ if (SUPPORTED_PACKAGE_MANAGERS.includes(name)) {
24
+ return { packageManagerName: name, packageManagerVersion: version.trimEnd() };
20
25
  }
21
26
 
22
- return LEGACY_PACKAGE_MANAGER;
27
+ return DEFAULT_PACKAGE_MANAGER;
23
28
  }
24
29
 
25
30
  export function getPackageManagerWithFallback() {
@@ -33,11 +38,11 @@ export function getPackageManagerWithFallback() {
33
38
  return packageManagerFromLockFile;
34
39
  }
35
40
 
36
- return LEGACY_PACKAGE_MANAGER;
41
+ return DEFAULT_PACKAGE_MANAGER;
37
42
  }
38
43
 
39
- export function getPackageManagerInstallCmd(packageManager: string) {
40
- switch (packageManager) {
44
+ export function getPackageManagerInstallCmd(packageManagerName: string) {
45
+ switch (packageManagerName) {
41
46
  case 'yarn':
42
47
  return 'yarn install --immutable --prefer-offline';
43
48
 
@@ -49,7 +54,7 @@ export function getPackageManagerInstallCmd(packageManager: string) {
49
54
  }
50
55
  }
51
56
 
52
- function getPackageManagerFromLockFile() {
57
+ function getPackageManagerFromLockFile(): PackageManager | undefined {
53
58
  const closestLockfilePath = findUpSync([YARN_LOCKFILE, PNPM_LOCKFILE, NPM_LOCKFILE]);
54
59
  if (!Boolean(closestLockfilePath)) {
55
60
  return undefined;
@@ -62,38 +67,38 @@ function getPackageManagerFromLockFile() {
62
67
  const npmVersionCommand = spawnSync('npm', ['--version'], {
63
68
  shell: true,
64
69
  });
65
- const version = npmVersionCommand.stdout.toString().trimEnd();
66
- return { packageManager: 'npm', version };
70
+ const packageManagerVersion = npmVersionCommand.stdout.toString().trimEnd();
71
+ return { packageManagerName: 'npm', packageManagerVersion };
67
72
  }
68
73
 
69
74
  if (closestLockfile === PNPM_LOCKFILE) {
70
75
  const pnpmVersionCommand = spawnSync('pnpm', ['--version'], {
71
76
  shell: true,
72
77
  });
73
- const version = pnpmVersionCommand.stdout.toString().trimEnd();
74
- return { packageManager: 'pnpm', version };
78
+ const packageManagerVersion = pnpmVersionCommand.stdout.toString().trimEnd();
79
+ return { packageManagerName: 'pnpm', packageManagerVersion };
75
80
  }
76
81
 
77
82
  if (closestLockfile === YARN_LOCKFILE) {
78
83
  const yarnVersionCommand = spawnSync('yarn', ['--version'], {
79
84
  shell: true,
80
85
  });
81
- const version = yarnVersionCommand.stdout.toString().trimEnd();
82
- return { packageManager: 'yarn', version };
86
+ const packageManagerVersion = yarnVersionCommand.stdout.toString().trimEnd();
87
+ return { packageManagerName: 'yarn', packageManagerVersion };
83
88
  }
84
89
 
85
90
  return undefined;
86
91
  } catch (error) {
87
- console.error('Failed to find package manager from lock file');
92
+ console.error('Failed to find package manager from lock file. Have you installed dependencies?');
88
93
  throw Error(error);
89
94
  }
90
95
  }
91
96
 
92
- function getPackageManagerFromPackageJson() {
97
+ function getPackageManagerFromPackageJson(): PackageManager | undefined {
93
98
  const packageJson = getPackageJson();
94
99
  if (packageJson.hasOwnProperty('packageManager')) {
95
- const [packageManager, version] = packageJson.packageManager.split('@');
96
- return { packageManager, version };
100
+ const [packageManagerName, packageManagerVersion] = packageJson.packageManager.split('@');
101
+ return { packageManagerName, packageManagerVersion };
97
102
  }
98
103
 
99
104
  return undefined;
@@ -64,7 +64,7 @@ export function renderTemplateFromFile(templateFile: string, data?: any) {
64
64
 
65
65
  export function getTemplateData() {
66
66
  const pluginJson = getPluginJson();
67
- const { packageManager, version: packageManagerVersion } = getPackageManagerWithFallback();
67
+ const { packageManagerName, packageManagerVersion } = getPackageManagerWithFallback();
68
68
 
69
69
  return {
70
70
  ...EXTRA_TEMPLATE_VARIABLES,
@@ -74,7 +74,7 @@ export function getTemplateData() {
74
74
  hasBackend: Boolean(pluginJson.backend),
75
75
  orgName: pluginJson.info?.author?.name,
76
76
  pluginType: pluginJson.type,
77
- packageManager,
77
+ packageManagerName,
78
78
  packageManagerVersion,
79
79
  };
80
80
  }
@@ -3,53 +3,53 @@
3
3
  1. Install dependencies
4
4
 
5
5
  ```bash
6
- yarn install
6
+ {{ packageManagerName }} run install
7
7
  ```
8
8
 
9
9
  2. Build plugin in development mode and run in watch mode
10
10
 
11
11
  ```bash
12
- yarn dev
12
+ {{ packageManagerName }} run dev
13
13
  ```
14
14
 
15
15
  3. Build plugin in production mode
16
16
 
17
17
  ```bash
18
- yarn build
18
+ {{ packageManagerName }} run build
19
19
  ```
20
20
 
21
21
  4. Run the tests (using Jest)
22
22
 
23
23
  ```bash
24
24
  # Runs the tests and watches for changes, requires git init first
25
- yarn test
26
-
25
+ {{ packageManagerName }} run test
26
+
27
27
  # Exits after running all the tests
28
- yarn test:ci
28
+ {{ packageManagerName }} run test:ci
29
29
  ```
30
30
 
31
31
  5. Spin up a Grafana instance and run the plugin inside it (using Docker)
32
32
 
33
33
  ```bash
34
- yarn server
34
+ {{ packageManagerName }} run server
35
35
  ```
36
36
 
37
37
  6. Run the E2E tests (using Cypress)
38
38
 
39
39
  ```bash
40
- # Spins up a Grafana instance first that we tests against
41
- yarn server
42
-
40
+ # Spins up a Grafana instance first that we tests against
41
+ {{ packageManagerName }} run server
42
+
43
43
  # Starts the tests
44
- yarn e2e
44
+ {{ packageManagerName }} run e2e
45
45
  ```
46
46
 
47
47
  7. Run the linter
48
48
 
49
49
  ```bash
50
- yarn lint
51
-
50
+ {{ packageManagerName }} run lint
51
+
52
52
  # or
53
53
 
54
- yarn lint:fix
54
+ {{ packageManagerName }} run lint:fix
55
55
  ```
@@ -12,6 +12,7 @@ const nodeModulesToTransform = (moduleNames) => `node_modules\/(?!(${moduleNames
12
12
 
13
13
  // Array of known nested grafana package dependencies that only bundle an ESM version
14
14
  const grafanaESModules = [
15
+ '.pnpm', // Support using pnpm symlinked packages
15
16
  'd3',
16
17
  'd3-color',
17
18
  'd3-force',
@@ -1,11 +1,9 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
3
  import util from 'util';
4
- import glob from 'glob';
4
+ import { glob } from 'glob';
5
5
  import { SOURCE_DIR } from './constants';
6
6
 
7
- const globAsync = util.promisify(glob);
8
-
9
7
  export function getPackageJson() {
10
8
  return require(path.resolve(process.cwd(), 'package.json'));
11
9
  }
@@ -21,11 +19,11 @@ export function hasReadme() {
21
19
  // Support bundling nested plugins by finding all plugin.json files in src directory
22
20
  // then checking for a sibling module.[jt]sx? file.
23
21
  export async function getEntries(): Promise<Record<string, string>> {
24
- const pluginsJson = await globAsync('**/src/**/plugin.json', { absolute: true });
22
+ const pluginsJson = await glob('**/src/**/plugin.json', { absolute: true });
25
23
 
26
24
  const plugins = await Promise.all(pluginsJson.map((pluginJson) => {
27
25
  const folder = path.dirname(pluginJson);
28
- return globAsync(`${folder}/module.{ts,tsx,js,jsx}`, { absolute: true });
26
+ return glob(`${folder}/module.{ts,tsx,js,jsx}`, { absolute: true });
29
27
  })
30
28
  );
31
29
 
@@ -1,3 +1,14 @@
1
+ # This file is required for PNPM
2
+
3
+ # PNPM 8 changed the default resolution mode to "lowest-direct" which is not how we expect resolutions to work
4
+ resolution-mode="highest"
5
+
6
+ # Make sure the default patterns are still included (https://pnpm.io/npmrc#public-hoist-pattern)
7
+ public-hoist-pattern[]="*eslint*"
8
+ public-hoist-pattern[]="*prettier*"
9
+
10
+ # Hoist all types packages to the root for better TS support
11
+ public-hoist-pattern[]="@types/*"
12
+
1
13
  # @grafana/e2e expects cypress to exist in the root of the node_modules directory
2
- # pnpm will put it in node_modules/.pnpm by default
3
- public-hoist-pattern[]=*cypress*
14
+ public-hoist-pattern[]="*cypress*"
@@ -9,9 +9,9 @@
9
9
  "test:ci": "jest --passWithNoTests --maxWorkers 4",
10
10
  "typecheck": "tsc --noEmit",
11
11
  "lint": "eslint --cache --ignore-path ./.gitignore --ext .js,.jsx,.ts,.tsx .",
12
- "lint:fix": "{{ packageManager }} run lint --fix",
13
- "e2e": "{{ packageManager }} exec cypress install && {{ packageManager }} exec grafana-e2e run",
14
- "e2e:update": "{{ packageManager }} exec cypress install && {{ packageManager }} exec grafana-e2e run --update-screenshots",
12
+ "lint:fix": "{{ packageManagerName }} run lint --fix",
13
+ "e2e": "{{ packageManagerName }} exec cypress install && {{ packageManagerName }} exec grafana-e2e run",
14
+ "e2e:update": "{{ packageManagerName }} exec cypress install && {{ packageManagerName }} exec grafana-e2e run --update-screenshots",
15
15
  "server": "docker-compose up --build",
16
16
  "sign": "npx --yes @grafana/sign-plugin@latest"
17
17
  },
@@ -23,23 +23,22 @@
23
23
  "@grafana/e2e-selectors": "{{ grafanaVersion }}",
24
24
  "@grafana/eslint-config": "^5.1.0",
25
25
  "@grafana/tsconfig": "^1.2.0-rc1",
26
- "@swc/core": "^1.2.144",
27
- "@swc/helpers": "^0.4.12",
26
+ "@swc/core": "^1.3.51",
27
+ "@swc/helpers": "^0.5.0",
28
28
  "@swc/jest": "^0.2.23",
29
29
  "@testing-library/jest-dom": "^5.16.2",
30
30
  "@testing-library/react": "^12.1.4",
31
- "@types/glob": "^8.0.0",
32
31
  "@types/jest": "^29.2.2",
33
32
  "@types/lodash": "^4.14.188",
33
+ "@types/node": "^18.11.9",
34
34
  "@types/react": "17.0.42",
35
35
  "@types/react-dom": "17.0.14",{{#if_eq pluginType "app"}}
36
36
  "@types/react-router-dom": "^5.3.3",{{/if_eq}}
37
- "@types/node": "^18.11.9",
38
37
  "copy-webpack-plugin": "^11.0.0",
39
38
  "css-loader": "^6.7.1",
40
39
  "eslint-webpack-plugin": "^3.1.1",
41
40
  "fork-ts-checker-webpack-plugin": "^7.2.0",
42
- "glob": "^8.0.3",
41
+ "glob": "^10.0.0",
43
42
  "identity-obj-proxy": "3.0.0",
44
43
  "jest": "^29.3.1",
45
44
  "jest-environment-jsdom": "^29.3.1",
@@ -49,8 +48,8 @@
49
48
  "sass-loader": "13.2.0",
50
49
  "style-loader": "3.3.1",
51
50
  "swc-loader": "^0.2.3",
52
- "tsconfig-paths": "^4.1.0",
53
51
  "ts-node": "^10.5.0",
52
+ "tsconfig-paths": "^4.1.0",
54
53
  "typescript": "^4.4.0",
55
54
  "webpack": "^5.69.1",
56
55
  "webpack-cli": "^4.9.2",
@@ -66,8 +65,9 @@
66
65
  "@grafana/ui": "{{ grafanaVersion }}",
67
66
  "react": "17.0.2",
68
67
  "react-dom": "17.0.2",{{#if_eq pluginType "app"}}
69
- "react-router-dom": "^5.2.0",{{/if_eq}}
68
+ "react-router-dom": "^5.2.0",
69
+ "rxjs": "7.5.7",{{/if_eq}}
70
70
  "tslib": "2.5.0"
71
71
  },
72
- "packageManager": "{{ packageManager }}@{{ packageManagerVersion }}"
72
+ "packageManager": "{{ packageManagerName }}@{{ packageManagerVersion }}"
73
73
  }
@@ -16,7 +16,7 @@ jobs:
16
16
  runs-on: ubuntu-latest
17
17
  steps:
18
18
  - uses: actions/checkout@v3
19
- {{#if_eq packageManager "pnpm"}}
19
+ {{#if_eq packageManagerName "pnpm"}}
20
20
  # pnpm action uses the packageManager field in package.json to
21
21
  # understand which version to install.
22
22
  - uses: pnpm/action-setup@v2
@@ -25,24 +25,25 @@ jobs:
25
25
  uses: actions/setup-node@v3
26
26
  with:
27
27
  node-version: '16'
28
- cache: '{{ packageManager }}'
28
+ cache: '{{ packageManagerName }}'
29
+
29
30
  - name: Install dependencies
30
31
  run: {{ packageManagerInstallCmd }}
31
32
 
32
33
  - name: Check types
33
- run: {{ packageManager }} run typecheck
34
+ run: {{ packageManagerName }} run typecheck
34
35
  - name: Lint
35
- run: {{ packageManager }} run lint
36
+ run: {{ packageManagerName }} run lint
36
37
  - name: Unit tests
37
- run: {{ packageManager }} run test:ci
38
+ run: {{ packageManagerName }} run test:ci
38
39
  - name: Build frontend
39
- run: {{ packageManager }} run build
40
+ run: {{ packageManagerName }} run build
40
41
 
41
42
  - name: Start grafana docker
42
43
  run: docker-compose up -d
43
44
 
44
45
  - name: Run e2e tests
45
- run: {{ packageManager }} run e2e
46
+ run: {{ packageManagerName }} run e2e
46
47
 
47
48
  - name: Stop grafana docker
48
49
  run: docker-compose down
@@ -12,16 +12,17 @@ jobs:
12
12
  env:
13
13
  GRAFANA_API_KEY: $\{{ secrets.GRAFANA_API_KEY }} # Requires a Grafana API key from Grafana.com.
14
14
  steps:
15
- - uses: actions/checkout@v3{{#if_eq packageManager "pnpm"}}
15
+ - uses: actions/checkout@v3
16
+ {{#if_eq packageManagerName "pnpm"}}
17
+ # pnpm action uses the packageManager field in package.json to
18
+ # understand which version to install.
16
19
  - uses: pnpm/action-setup@v2
17
- with:
18
- version: 7.x.x{{/if_eq}}
19
-
20
+ {{/if_eq}}
20
21
  - name: Setup Node.js environment
21
22
  uses: actions/setup-node@v3
22
23
  with:
23
24
  node-version: '16'
24
- cache: '{{ packageManager }}'
25
+ cache: '{{ packageManagerName }}'
25
26
 
26
27
  - name: Setup Go environment
27
28
  uses: actions/setup-go@v3
@@ -32,7 +33,7 @@ jobs:
32
33
  run: {{ packageManagerInstallCmd }}
33
34
 
34
35
  - name: Build and test frontend
35
- run: {{ packageManager }} run build
36
+ run: {{ packageManagerName }} run build
36
37
 
37
38
  - name: Check for backend
38
39
  id: check-for-backend
@@ -63,7 +64,7 @@ jobs:
63
64
  if: $\{{ env.GRAFANA_API_KEY == '' }}
64
65
 
65
66
  - name: Sign plugin
66
- run: {{ packageManager }} run sign
67
+ run: {{ packageManagerName }} run sign
67
68
  if: $\{{ env.GRAFANA_API_KEY != '' }}
68
69
 
69
70
  - name: Get plugin metadata
@@ -6,13 +6,19 @@ jobs:
6
6
  runs-on: ubuntu-latest
7
7
  steps:
8
8
  - uses: actions/checkout@v3
9
- - uses: actions/setup-node@v3
9
+ {{#if_eq packageManagerName "pnpm"}}
10
+ # pnpm action uses the packageManager field in package.json to
11
+ # understand which version to install.
12
+ - uses: pnpm/action-setup@v2
13
+ {{/if_eq}}
14
+ - name: Setup Node.js environment
15
+ uses: actions/setup-node@v3
10
16
  with:
11
17
  node-version: '16'
12
- cache: '{{ packageManager }}'
18
+ cache: '{{ packageManagerName }}'
13
19
  - name: Install dependencies
14
20
  run: {{ packageManagerInstallCmd }}
15
21
  - name: Build plugin
16
- run: {{ packageManager }} run build
22
+ run: {{ packageManagerName }} run build
17
23
  - name: Compatibility check
18
24
  run: npx @grafana/levitate@latest is-compatible --path src/module.ts --target @grafana/data,@grafana/ui,@grafana/runtime