Skip to content

Commit 3bef4ef

Browse files
authored
plugin sdk upgrade (#43)
1 parent 2bdcd1a commit 3bef4ef

30 files changed

+5434
-3237
lines changed

.config/.cprc.json

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"version": "4.7.0"
3+
}

.config/.eslintrc

+16-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,25 @@
11
/*
22
* ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️
33
*
4-
* In order to extend the configuration follow the steps in .config/README.md
4+
* In order to extend the configuration follow the steps in
5+
* https://grafana.com/developers/plugin-tools/create-a-plugin/extend-a-plugin/extend-configurations#extend-the-eslint-config
56
*/
6-
{
7+
{
78
"extends": ["@grafana/eslint-config"],
89
"root": true,
910
"rules": {
1011
"react/prop-types": "off"
11-
}
12+
},
13+
"overrides": [
14+
{
15+
"plugins": ["deprecation"],
16+
"files": ["src/**/*.{ts,tsx}"],
17+
"rules": {
18+
"deprecation/deprecation": "warn"
19+
},
20+
"parserOptions": {
21+
"project": "./tsconfig.json"
22+
}
23+
}
24+
]
1225
}

.config/.prettierrc.js

+9-9
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
*/
66

77
module.exports = {
8-
"endOfLine": "auto",
9-
"printWidth": 120,
10-
"trailingComma": "es5",
11-
"semi": true,
12-
"jsxSingleQuote": false,
13-
"singleQuote": true,
14-
"useTabs": false,
15-
"tabWidth": 2
16-
};
8+
endOfLine: 'auto',
9+
printWidth: 120,
10+
trailingComma: 'es5',
11+
semi: true,
12+
jsxSingleQuote: false,
13+
singleQuote: true,
14+
useTabs: false,
15+
tabWidth: 2,
16+
};

.config/Dockerfile

+63-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
ARG grafana_version=latest
2+
ARG grafana_image=grafana-enterprise
23

3-
FROM grafana/grafana:${grafana_version}
4+
FROM grafana/${grafana_image}:${grafana_version}
5+
6+
ARG development=true
7+
8+
ARG GO_VERSION=1.21.6
9+
ARG GO_ARCH=amd64
10+
11+
ENV DEV "${development}"
412

513
# Make it as simple as possible to access the grafana instance for development purposes
614
# Do NOT enable these settings in a public facing / production grafana instance
@@ -10,6 +18,58 @@ ENV GF_AUTH_BASIC_ENABLED "false"
1018
# Set development mode so plugins can be loaded without the need to sign
1119
ENV GF_DEFAULT_APP_MODE "development"
1220

13-
# Inject livereload script into grafana index.html
21+
22+
LABEL maintainer="Grafana Labs <[email protected]>"
23+
24+
ENV GF_PATHS_HOME="/usr/share/grafana"
25+
WORKDIR $GF_PATHS_HOME
26+
1427
USER root
15-
RUN sed -i 's/<\/body><\/html>/<script src=\"http:\/\/localhost:35729\/livereload.js\"><\/script><\/body><\/html>/g' /usr/share/grafana/public/views/index.html
28+
29+
# Installing supervisor and inotify-tools
30+
RUN if [ "${development}" = "true" ]; then \
31+
if grep -i -q alpine /etc/issue; then \
32+
apk add supervisor inotify-tools git; \
33+
elif grep -i -q ubuntu /etc/issue; then \
34+
DEBIAN_FRONTEND=noninteractive && \
35+
apt-get update && \
36+
apt-get install -y supervisor inotify-tools git && \
37+
rm -rf /var/lib/apt/lists/*; \
38+
else \
39+
echo 'ERROR: Unsupported base image' && /bin/false; \
40+
fi \
41+
fi
42+
43+
COPY supervisord/supervisord.conf /etc/supervisor.d/supervisord.ini
44+
COPY supervisord/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
45+
46+
47+
# Installing Go
48+
RUN if [ "${development}" = "true" ]; then \
49+
curl -O -L https://golang.org/dl/go${GO_VERSION}.linux-${GO_ARCH}.tar.gz && \
50+
rm -rf /usr/local/go && \
51+
tar -C /usr/local -xzf go${GO_VERSION}.linux-${GO_ARCH}.tar.gz && \
52+
echo "export PATH=$PATH:/usr/local/go/bin:~/go/bin" >> ~/.bashrc && \
53+
rm -f go${GO_VERSION}.linux-${GO_ARCH}.tar.gz; \
54+
fi
55+
56+
# Installing delve for debugging
57+
RUN if [ "${development}" = "true" ]; then \
58+
/usr/local/go/bin/go install github.com/go-delve/delve/cmd/dlv@latest; \
59+
fi
60+
61+
# Installing mage for plugin (re)building
62+
RUN if [ "${development}" = "true" ]; then \
63+
git clone https://github.com/magefile/mage; \
64+
cd mage; \
65+
export PATH=$PATH:/usr/local/go/bin; \
66+
go run bootstrap.go; \
67+
fi
68+
69+
# Inject livereload script into grafana index.html
70+
RUN sed -i 's|</body>|<script src="http://localhost:35729/livereload.js"></script></body>|g' /usr/share/grafana/public/views/index.html
71+
72+
73+
COPY entrypoint.sh /entrypoint.sh
74+
RUN chmod +x /entrypoint.sh
75+
ENTRYPOINT ["/entrypoint.sh"]

.config/README.md

+25-2
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,11 @@ set up the Jest DOM for the testing library and to apply some polyfills. ([link
5656

5757
#### ESM errors with Jest
5858

59-
A common issue found with the current jest config involves importing an npm package which only offers an ESM build. These packages cause jest to error with `SyntaxError: Cannot use import statement outside a module`. To work around this we provide a list of known packages to pass to the `[transformIgnorePatterns](https://jestjs.io/docs/configuration#transformignorepatterns-arraystring)` jest configuration property. If need be this can be extended in the following way:
59+
A common issue with the current jest config involves importing an npm package that only offers an ESM build. These packages cause jest to error with `SyntaxError: Cannot use import statement outside a module`. To work around this, we provide a list of known packages to pass to the `[transformIgnorePatterns](https://jestjs.io/docs/configuration#transformignorepatterns-arraystring)` jest configuration property. If need be, this can be extended in the following way:
6060

6161
```javascript
6262
process.env.TZ = 'UTC';
63-
const { grafanaESModules, nodeModulesToTransform } = require('./jest/utils');
63+
const { grafanaESModules, nodeModulesToTransform } = require('./config/jest/utils');
6464

6565
module.exports = {
6666
// Jest configuration provided by Grafana
@@ -139,3 +139,26 @@ We need to update the `scripts` in the `package.json` to use the extended Webpac
139139
-"dev": "webpack -w -c ./.config/webpack/webpack.config.ts --env development",
140140
+"dev": "webpack -w -c ./webpack.config.ts --env development",
141141
```
142+
143+
### Configure grafana image to use when running docker
144+
145+
By default, `grafana-enterprise` will be used as the docker image for all docker related commands. If you want to override this behavior, simply alter the `docker-compose.yaml` by adding the following build arg `grafana_image`.
146+
147+
**Example:**
148+
149+
```yaml
150+
version: '3.7'
151+
152+
services:
153+
grafana:
154+
container_name: 'myorg-basic-app'
155+
build:
156+
context: ./.config
157+
args:
158+
grafana_version: ${GRAFANA_VERSION:-9.1.2}
159+
grafana_image: ${GRAFANA_IMAGE:-grafana}
160+
```
161+
162+
In this example, we assign the environment variable `GRAFANA_IMAGE` to the build arg `grafana_image` with a default value of `grafana`. This will allow you to set the value while running the docker-compose commands, which might be convenient in some scenarios.
163+
164+
---

.config/entrypoint.sh

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/bin/sh
2+
3+
if [ "${DEV}" = "false" ]; then
4+
echo "Starting test mode"
5+
exec /run.sh
6+
fi
7+
8+
echo "Starting development mode"
9+
10+
if grep -i -q alpine /etc/issue; then
11+
exec /usr/bin/supervisord -c /etc/supervisord.conf
12+
elif grep -i -q ubuntu /etc/issue; then
13+
exec /usr/bin/supervisord -c /etc/supervisor/supervisord.conf
14+
else
15+
echo 'ERROR: Unsupported base image'
16+
exit 1
17+
fi
18+

.config/jest-setup.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
/*
22
* ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️
33
*
4-
* In order to extend the configuration follow the steps in .config/README.md
4+
* In order to extend the configuration follow the steps in
5+
* https://grafana.com/developers/plugin-tools/create-a-plugin/extend-a-plugin/extend-configurations#extend-the-jest-config
56
*/
67

78
import '@testing-library/jest-dom';

.config/jest.config.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
/*
22
* ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️
33
*
4-
* In order to extend the configuration follow the steps in .config/README.md
4+
* In order to extend the configuration follow the steps in
5+
* https://grafana.com/developers/plugin-tools/create-a-plugin/extend-a-plugin/extend-configurations#extend-the-jest-config
56
*/
67

78
const path = require('path');
@@ -24,7 +25,7 @@ module.exports = {
2425
'^.+\\.(t|j)sx?$': [
2526
'@swc/jest',
2627
{
27-
sourceMaps: true,
28+
sourceMaps: 'inline',
2829
jsc: {
2930
parser: {
3031
syntax: 'typescript',

.config/jest/utils.js

+16-4
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,24 @@
88
* This utility function is useful in combination with jest `transformIgnorePatterns` config
99
* to transform specific packages (e.g.ES modules) in a projects node_modules folder.
1010
*/
11-
const nodeModulesToTransform = (moduleNames) => `node_modules\/(?!(${moduleNames.join('|')})\/)`;
11+
const nodeModulesToTransform = (moduleNames) => `node_modules\/(?!.*(${moduleNames.join('|')})\/.*)`;
1212

1313
// Array of known nested grafana package dependencies that only bundle an ESM version
14-
const grafanaESModules = ['ol', 'react-colorful', 'uuid'];
14+
const grafanaESModules = [
15+
'.pnpm', // Support using pnpm symlinked packages
16+
'@grafana/schema',
17+
'd3',
18+
'd3-color',
19+
'd3-force',
20+
'd3-interpolate',
21+
'd3-scale-chromatic',
22+
'ol',
23+
'react-colorful',
24+
'rxjs',
25+
'uuid',
26+
];
1527

1628
module.exports = {
1729
nodeModulesToTransform,
18-
grafanaESModules
19-
}
30+
grafanaESModules,
31+
};

.config/supervisord/supervisord.conf

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
[supervisord]
2+
nodaemon=true
3+
user=root
4+
5+
[program:grafana]
6+
user=root
7+
directory=/var/lib/grafana
8+
command=bash -c 'while [ ! -f /root/parseable-parseable-datasource/dist/gpx_parseable* ]; do sleep 1; done; /run.sh'
9+
stdout_logfile=/dev/fd/1
10+
stdout_logfile_maxbytes=0
11+
redirect_stderr=true
12+
killasgroup=true
13+
stopasgroup=true
14+
autostart=true
15+
16+
[program:delve]
17+
user=root
18+
command=/bin/bash -c 'pid=""; while [ -z "$pid" ]; do pid=$(pgrep -f gpx_parseable); done; /root/go/bin/dlv attach --api-version=2 --headless --continue --accept-multiclient --listen=:2345 $pid'
19+
stdout_logfile=/dev/fd/1
20+
stdout_logfile_maxbytes=0
21+
redirect_stderr=true
22+
killasgroup=false
23+
stopasgroup=false
24+
autostart=true
25+
autorestart=true
26+
27+
[program:build-watcher]
28+
user=root
29+
command=/bin/bash -c 'while inotifywait -e modify,create,delete -r /var/lib/grafana/plugins/parseable-parseable-datasource; do echo "Change detected, restarting delve...";supervisorctl restart delve; done'
30+
stdout_logfile=/dev/fd/1
31+
stdout_logfile_maxbytes=0
32+
redirect_stderr=true
33+
killasgroup=true
34+
stopasgroup=true
35+
autostart=true
36+
37+
[program:mage-watcher]
38+
user=root
39+
environment=PATH="/usr/local/go/bin:/root/go/bin:%(ENV_PATH)s"
40+
directory=/root/parseable-parseable-datasource
41+
command=/bin/bash -c 'git config --global --add safe.directory /root/parseable-parseable-datasource && mage -v watch'
42+
stdout_logfile=/dev/fd/1
43+
stdout_logfile_maxbytes=0
44+
redirect_stderr=true
45+
killasgroup=true
46+
stopasgroup=true
47+
autostart=true

.config/tsconfig.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
/*
22
* ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️
33
*
4-
* In order to extend the configuration follow the steps in .config/README.md
4+
* In order to extend the configuration follow the steps in
5+
* https://grafana.com/developers/plugin-tools/create-a-plugin/extend-a-plugin/extend-configurations#extend-the-typescript-config
56
*/
6-
{
7+
{
78
"compilerOptions": {
89
"alwaysStrict": true,
910
"declaration": false,

.config/webpack/utils.ts

+36-20
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,58 @@
11
import fs from 'fs';
2+
import process from 'process';
3+
import os from 'os';
24
import path from 'path';
3-
import util from 'util';
4-
import glob from 'glob';
5+
import { glob } from 'glob';
56
import { SOURCE_DIR } from './constants';
67

7-
const globAsync = util.promisify(glob);
8+
export function isWSL() {
9+
if (process.platform !== 'linux') {
10+
return false;
11+
}
12+
13+
if (os.release().toLowerCase().includes('microsoft')) {
14+
return true;
15+
}
16+
17+
try {
18+
return fs.readFileSync('/proc/version', 'utf8').toLowerCase().includes('microsoft');
19+
} catch {
20+
return false;
21+
}
22+
}
823

924
export function getPackageJson() {
1025
return require(path.resolve(process.cwd(), 'package.json'));
1126
}
1227

13-
export function getPluginId() {
14-
const { id } = require(path.resolve(process.cwd(), `${SOURCE_DIR}/plugin.json`));
15-
16-
return id;
28+
export function getPluginJson() {
29+
return require(path.resolve(process.cwd(), `${SOURCE_DIR}/plugin.json`));
1730
}
1831

1932
export function hasReadme() {
2033
return fs.existsSync(path.resolve(process.cwd(), SOURCE_DIR, 'README.md'));
2134
}
2235

36+
// Support bundling nested plugins by finding all plugin.json files in src directory
37+
// then checking for a sibling module.[jt]sx? file.
2338
export async function getEntries(): Promise<Record<string, string>> {
24-
const parent = '..';
25-
const pluginsJson = await globAsync('**/src/**/plugin.json');
26-
27-
const plugins = await Promise.all(pluginsJson.map(pluginJson => {
28-
const folder = path.dirname(pluginJson);
29-
return globAsync(`${folder}/module.{ts,tsx,js}`);
30-
}));
39+
const pluginsJson = await glob('**/src/**/plugin.json', { absolute: true });
40+
41+
const plugins = await Promise.all(
42+
pluginsJson.map((pluginJson) => {
43+
const folder = path.dirname(pluginJson);
44+
return glob(`${folder}/module.{ts,tsx,js,jsx}`, { absolute: true });
45+
})
46+
);
3147

3248
return plugins.reduce((result, modules) => {
3349
return modules.reduce((result, module) => {
34-
const pluginPath = path.resolve(path.dirname(module), parent);
35-
const pluginName = path.basename(pluginPath);
36-
const entryName = plugins.length > 1 ? `${pluginName}/module` : 'module';
37-
38-
result[entryName] = path.join(parent, module);
50+
const pluginPath = path.dirname(module);
51+
const pluginName = path.relative(process.cwd(), pluginPath).replace(/src\/?/i, '');
52+
const entryName = pluginName === '' ? 'module' : `${pluginName}/module`;
53+
54+
result[entryName] = module;
3955
return result;
4056
}, result);
4157
}, {});
42-
}
58+
}

0 commit comments

Comments
 (0)