@rancher/create-extension 0.1.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/app/app.package.json +14 -0
- package/app/files/.eslintignore +16 -0
- package/app/files/.eslintrc.js +175 -0
- package/app/files/.github/workflows/build-extension-catalog.yml +24 -0
- package/app/files/.github/workflows/build-extension-charts.yml +22 -0
- package/app/files/.gitignore +70 -0
- package/app/files/.gitlab-ci.yml +14 -0
- package/app/files/.vscode/settings.json +21 -0
- package/app/files/babel.config.js +1 -0
- package/app/files/tsconfig.json +42 -0
- package/app/files/vue.config.js +6 -0
- package/app/init +158 -0
- package/app/package.json +25 -0
- package/init +146 -0
- package/package.json +25 -0
- package/pkg/files/babel.config.js +1 -0
- package/pkg/files/index.ts +14 -0
- package/pkg/files/tsconfig.json +53 -0
- package/pkg/files/vue.config.js +1 -0
- package/pkg/init +220 -0
- package/pkg/package.json +19 -0
- package/pkg/pkg.package.json +21 -0
- package/pkg/vue-shim.ts +4 -0
- package/update/init +61 -0
- package/update/package.json +20 -0
- package/update/upgrade +56 -0
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
root: true,
|
|
3
|
+
env: {
|
|
4
|
+
browser: true,
|
|
5
|
+
node: true
|
|
6
|
+
},
|
|
7
|
+
globals: { NodeJS: true, Timer: true },
|
|
8
|
+
extends: [
|
|
9
|
+
'standard',
|
|
10
|
+
'eslint:recommended',
|
|
11
|
+
'plugin:@typescript-eslint/recommended',
|
|
12
|
+
'@vue/standard',
|
|
13
|
+
'@vue/typescript/recommended',
|
|
14
|
+
'plugin:vue/recommended',
|
|
15
|
+
'plugin:cypress/recommended',
|
|
16
|
+
],
|
|
17
|
+
// add your custom rules here
|
|
18
|
+
rules: {
|
|
19
|
+
'dot-notation': 'off',
|
|
20
|
+
'generator-star-spacing': 'off',
|
|
21
|
+
'guard-for-in': 'off',
|
|
22
|
+
'linebreak-style': 'off',
|
|
23
|
+
'new-cap': 'off',
|
|
24
|
+
'no-empty': 'off',
|
|
25
|
+
'no-extra-boolean-cast': 'off',
|
|
26
|
+
'no-new': 'off',
|
|
27
|
+
'no-plusplus': 'off',
|
|
28
|
+
'no-useless-escape': 'off',
|
|
29
|
+
'semi-spacing': 'off',
|
|
30
|
+
'space-in-parens': 'off',
|
|
31
|
+
strict: 'off',
|
|
32
|
+
'unicorn/no-new-buffer': 'off',
|
|
33
|
+
'vue/html-self-closing': 'off',
|
|
34
|
+
'vue/no-unused-components': 'warn',
|
|
35
|
+
'vue/no-v-html': 'error',
|
|
36
|
+
'wrap-iife': 'off',
|
|
37
|
+
|
|
38
|
+
'array-bracket-spacing': 'warn',
|
|
39
|
+
'arrow-parens': 'warn',
|
|
40
|
+
'arrow-spacing': ['warn', { before: true, after: true }],
|
|
41
|
+
'block-spacing': ['warn', 'always'],
|
|
42
|
+
'brace-style': ['warn', '1tbs'],
|
|
43
|
+
'comma-dangle': ['warn', 'only-multiline'],
|
|
44
|
+
'comma-spacing': 'warn',
|
|
45
|
+
curly: 'warn',
|
|
46
|
+
eqeqeq: 'warn',
|
|
47
|
+
'func-call-spacing': ['warn', 'never'],
|
|
48
|
+
'implicit-arrow-linebreak': 'warn',
|
|
49
|
+
indent: ['warn', 2],
|
|
50
|
+
'keyword-spacing': 'warn',
|
|
51
|
+
'lines-between-class-members': ['warn', 'always', { exceptAfterSingleLine: true }],
|
|
52
|
+
'multiline-ternary': ['warn', 'never'],
|
|
53
|
+
'newline-per-chained-call': ['warn', { ignoreChainWithDepth: 4 }],
|
|
54
|
+
'no-caller': 'warn',
|
|
55
|
+
'no-cond-assign': ['warn', 'except-parens'],
|
|
56
|
+
'no-console': 'warn',
|
|
57
|
+
'no-debugger': 'warn',
|
|
58
|
+
'no-eq-null': 'warn',
|
|
59
|
+
'no-eval': 'warn',
|
|
60
|
+
'no-trailing-spaces': 'warn',
|
|
61
|
+
'no-undef': 'warn',
|
|
62
|
+
'no-unused-vars': 'warn',
|
|
63
|
+
'no-whitespace-before-property': 'warn',
|
|
64
|
+
'object-curly-spacing': ['warn', 'always'],
|
|
65
|
+
'object-property-newline': 'warn',
|
|
66
|
+
'object-shorthand': 'warn',
|
|
67
|
+
'padded-blocks': ['warn', 'never'],
|
|
68
|
+
'prefer-arrow-callback': 'warn',
|
|
69
|
+
'prefer-template': 'warn',
|
|
70
|
+
'quote-props': 'warn',
|
|
71
|
+
'rest-spread-spacing': 'warn',
|
|
72
|
+
semi: ['warn', 'always'],
|
|
73
|
+
'space-before-function-paren': ['warn', 'never'],
|
|
74
|
+
'space-infix-ops': 'warn',
|
|
75
|
+
'spaced-comment': 'warn',
|
|
76
|
+
'switch-colon-spacing': 'warn',
|
|
77
|
+
'template-curly-spacing': ['warn', 'always'],
|
|
78
|
+
'yield-star-spacing': ['warn', 'both'],
|
|
79
|
+
|
|
80
|
+
'key-spacing': ['warn', {
|
|
81
|
+
align: {
|
|
82
|
+
beforeColon: false,
|
|
83
|
+
afterColon: true,
|
|
84
|
+
on: 'value',
|
|
85
|
+
mode: 'minimum'
|
|
86
|
+
},
|
|
87
|
+
multiLine: {
|
|
88
|
+
beforeColon: false,
|
|
89
|
+
afterColon: true
|
|
90
|
+
},
|
|
91
|
+
}],
|
|
92
|
+
|
|
93
|
+
'object-curly-newline': ['warn', {
|
|
94
|
+
ObjectExpression: {
|
|
95
|
+
multiline: true,
|
|
96
|
+
minProperties: 3
|
|
97
|
+
},
|
|
98
|
+
ObjectPattern: {
|
|
99
|
+
multiline: true,
|
|
100
|
+
minProperties: 4
|
|
101
|
+
},
|
|
102
|
+
ImportDeclaration: {
|
|
103
|
+
multiline: true,
|
|
104
|
+
minProperties: 5
|
|
105
|
+
},
|
|
106
|
+
ExportDeclaration: {
|
|
107
|
+
multiline: true,
|
|
108
|
+
minProperties: 3
|
|
109
|
+
}
|
|
110
|
+
}],
|
|
111
|
+
|
|
112
|
+
'padding-line-between-statements': [
|
|
113
|
+
'warn',
|
|
114
|
+
{
|
|
115
|
+
blankLine: 'always',
|
|
116
|
+
prev: '*',
|
|
117
|
+
next: 'return',
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
blankLine: 'always',
|
|
121
|
+
prev: 'function',
|
|
122
|
+
next: 'function',
|
|
123
|
+
},
|
|
124
|
+
// This configuration would require blank lines after every sequence of variable declarations
|
|
125
|
+
{
|
|
126
|
+
blankLine: 'always',
|
|
127
|
+
prev: ['const', 'let', 'var'],
|
|
128
|
+
next: '*'
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
blankLine: 'any',
|
|
132
|
+
prev: ['const', 'let', 'var'],
|
|
133
|
+
next: ['const', 'let', 'var']
|
|
134
|
+
}
|
|
135
|
+
],
|
|
136
|
+
|
|
137
|
+
quotes: [
|
|
138
|
+
'warn',
|
|
139
|
+
'single',
|
|
140
|
+
{
|
|
141
|
+
avoidEscape: true,
|
|
142
|
+
allowTemplateLiterals: true
|
|
143
|
+
},
|
|
144
|
+
],
|
|
145
|
+
|
|
146
|
+
'space-unary-ops': [
|
|
147
|
+
'warn',
|
|
148
|
+
{
|
|
149
|
+
words: true,
|
|
150
|
+
nonwords: false,
|
|
151
|
+
}
|
|
152
|
+
],
|
|
153
|
+
|
|
154
|
+
// FIXME: The following is disabled due to new linter and old JS code. These should all be enabled and underlying issues fixed
|
|
155
|
+
'vue/order-in-components': 'off',
|
|
156
|
+
'vue/no-lone-template': 'off',
|
|
157
|
+
'vue/v-slot-style': 'off',
|
|
158
|
+
'vue/component-tags-order': 'off',
|
|
159
|
+
'vue/no-mutating-props': 'off',
|
|
160
|
+
'@typescript-eslint/no-unused-vars': 'off',
|
|
161
|
+
'array-callback-return': 'off',
|
|
162
|
+
},
|
|
163
|
+
overrides: [
|
|
164
|
+
{
|
|
165
|
+
files: ['*.js'],
|
|
166
|
+
rules: {
|
|
167
|
+
// FIXME: The following is disabled due to new linter and old JS code. These should all be enabled and underlying issues fixed
|
|
168
|
+
'prefer-regex-literals': 'off',
|
|
169
|
+
'vue/component-definition-name-casing': 'off',
|
|
170
|
+
'no-unreachable-loop': 'off',
|
|
171
|
+
'computed-property-spacing': 'off',
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
]
|
|
175
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
name: Build and Release Extension Catalog
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
release:
|
|
6
|
+
types: [released]
|
|
7
|
+
|
|
8
|
+
defaults:
|
|
9
|
+
run:
|
|
10
|
+
shell: bash
|
|
11
|
+
working-directory: ./
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
build-extension-catalog:
|
|
15
|
+
uses: rancher/dashboard/.github/workflows/build-extension-catalog.yml@master
|
|
16
|
+
permissions:
|
|
17
|
+
actions: write
|
|
18
|
+
contents: read
|
|
19
|
+
packages: write
|
|
20
|
+
with:
|
|
21
|
+
registry_target: ghcr.io
|
|
22
|
+
registry_user: ${{ github.actor }}
|
|
23
|
+
secrets:
|
|
24
|
+
registry_token: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
name: Build and Release Extension Charts
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
release:
|
|
6
|
+
types: [released]
|
|
7
|
+
|
|
8
|
+
defaults:
|
|
9
|
+
run:
|
|
10
|
+
shell: bash
|
|
11
|
+
working-directory: ./
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
build-extension-charts:
|
|
15
|
+
uses: rancher/dashboard/.github/workflows/build-extension-charts.yml@master
|
|
16
|
+
permissions:
|
|
17
|
+
actions: write
|
|
18
|
+
contents: write
|
|
19
|
+
deployments: write
|
|
20
|
+
pages: write
|
|
21
|
+
with:
|
|
22
|
+
target_branch: gh-pages
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# compiled output
|
|
2
|
+
/dist
|
|
3
|
+
/tmp
|
|
4
|
+
/out-tsc
|
|
5
|
+
|
|
6
|
+
# Runtime data
|
|
7
|
+
pids
|
|
8
|
+
*.pid
|
|
9
|
+
*.seed
|
|
10
|
+
*.pid.lock
|
|
11
|
+
|
|
12
|
+
# Directory for instrumented libs generated by jscoverage/JSCover
|
|
13
|
+
lib-cov
|
|
14
|
+
|
|
15
|
+
# Coverage directory used by tools like istanbul
|
|
16
|
+
coverage
|
|
17
|
+
|
|
18
|
+
# nyc test coverage
|
|
19
|
+
.nyc_output
|
|
20
|
+
|
|
21
|
+
# IDEs and editors
|
|
22
|
+
.idea
|
|
23
|
+
.project
|
|
24
|
+
.classpath
|
|
25
|
+
.c9/
|
|
26
|
+
*.launch
|
|
27
|
+
.settings/
|
|
28
|
+
*.sublime-workspace
|
|
29
|
+
|
|
30
|
+
# IDE - VSCode
|
|
31
|
+
.vscode/*
|
|
32
|
+
!.vscode/settings.json
|
|
33
|
+
!.vscode/tasks.json
|
|
34
|
+
!.vscode/launch.json
|
|
35
|
+
!.vscode/extensions.json
|
|
36
|
+
|
|
37
|
+
# misc
|
|
38
|
+
.sass-cache
|
|
39
|
+
connect.lock
|
|
40
|
+
typings
|
|
41
|
+
|
|
42
|
+
# Logs
|
|
43
|
+
logs
|
|
44
|
+
*.log
|
|
45
|
+
npm-debug.log*
|
|
46
|
+
yarn-debug.log*
|
|
47
|
+
yarn-error.log*
|
|
48
|
+
|
|
49
|
+
# Dependency directories
|
|
50
|
+
node_modules/
|
|
51
|
+
jspm_packages/
|
|
52
|
+
|
|
53
|
+
# Optional npm cache directory
|
|
54
|
+
.npm
|
|
55
|
+
|
|
56
|
+
# Optional eslint cache
|
|
57
|
+
.eslintcache
|
|
58
|
+
|
|
59
|
+
# Optional REPL history
|
|
60
|
+
.node_repl_history
|
|
61
|
+
|
|
62
|
+
# Yarn Integrity file
|
|
63
|
+
.yarn-integrity
|
|
64
|
+
|
|
65
|
+
# dotenv environment variables file
|
|
66
|
+
.env
|
|
67
|
+
|
|
68
|
+
# System Files
|
|
69
|
+
.DS_Store
|
|
70
|
+
Thumbs.db
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
image: registry.suse.com/bci/bci-base:latest
|
|
2
|
+
|
|
3
|
+
stages:
|
|
4
|
+
- check_version
|
|
5
|
+
- build_catalog
|
|
6
|
+
|
|
7
|
+
variables:
|
|
8
|
+
REGISTRY: $CI_REGISTRY
|
|
9
|
+
REGISTRY_USER: $CI_REGISTRY_USER
|
|
10
|
+
REGISTRY_PASSWORD: $CI_REGISTRY_PASSWORD
|
|
11
|
+
IMAGE_NAMESPACE: $CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME
|
|
12
|
+
|
|
13
|
+
include:
|
|
14
|
+
- remote: 'https://raw.githubusercontent.com/rancher/dashboard/master/shell/scripts/.gitlab/workflows/build-extension-catalog.gitlab-ci.yml'
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"files.exclude": {
|
|
3
|
+
".ackrc": true,
|
|
4
|
+
".dockerignore": true,
|
|
5
|
+
".drone.yml": true,
|
|
6
|
+
".editorconfig": true,
|
|
7
|
+
".eslintcache": true,
|
|
8
|
+
".eslintignore": true,
|
|
9
|
+
".eslintrc.js": true,
|
|
10
|
+
".gitignore": true,
|
|
11
|
+
".nyc_output": true,
|
|
12
|
+
".vscode": true,
|
|
13
|
+
"LICENSE": true,
|
|
14
|
+
"node_modules": true,
|
|
15
|
+
"babel.config.js": true,
|
|
16
|
+
"jsconfig.json": true,
|
|
17
|
+
"yarn-error.log": true,
|
|
18
|
+
"pkg/**/.shell": true,
|
|
19
|
+
"pkg/**/node_modules": true,
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require('@rancher/shell/babel.config.js');
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2018",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "Node",
|
|
6
|
+
"lib": [
|
|
7
|
+
"ESNext",
|
|
8
|
+
"ESNext.AsyncIterable",
|
|
9
|
+
"DOM"
|
|
10
|
+
],
|
|
11
|
+
"esModuleInterop": true,
|
|
12
|
+
"allowJs": true,
|
|
13
|
+
"sourceMap": true,
|
|
14
|
+
"strict": true,
|
|
15
|
+
"noEmit": true,
|
|
16
|
+
"baseUrl": ".",
|
|
17
|
+
"paths": {
|
|
18
|
+
"~/*": [
|
|
19
|
+
"./*"
|
|
20
|
+
],
|
|
21
|
+
"@/*": [
|
|
22
|
+
"./*"
|
|
23
|
+
],
|
|
24
|
+
"@shell/*": [
|
|
25
|
+
"./node_modules/@rancher/shell/*"
|
|
26
|
+
]
|
|
27
|
+
},
|
|
28
|
+
"typeRoots": [
|
|
29
|
+
"./node_modules",
|
|
30
|
+
"./node_modules/@rancher/shell/types"
|
|
31
|
+
],
|
|
32
|
+
"types": [
|
|
33
|
+
"@types/node",
|
|
34
|
+
"cypress",
|
|
35
|
+
"rancher",
|
|
36
|
+
"shell"
|
|
37
|
+
]
|
|
38
|
+
},
|
|
39
|
+
"exclude": [
|
|
40
|
+
"node_modules"
|
|
41
|
+
]
|
|
42
|
+
}
|
package/app/init
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/* eslint-disable no-console */
|
|
3
|
+
|
|
4
|
+
const { execSync } = require('child_process');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const fs = require('fs-extra');
|
|
7
|
+
|
|
8
|
+
const targets = {
|
|
9
|
+
dev: 'NODE_ENV=dev ./node_modules/.bin/vue-cli-service serve',
|
|
10
|
+
build: './node_modules/.bin/vue-cli-service build',
|
|
11
|
+
clean: './node_modules/@rancher/shell/scripts/clean'
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const files = [
|
|
15
|
+
'tsconfig.json',
|
|
16
|
+
'vue.config.js',
|
|
17
|
+
'.gitignore',
|
|
18
|
+
'.eslintignore',
|
|
19
|
+
'.eslintrc.js',
|
|
20
|
+
'babel.config.js',
|
|
21
|
+
'.vscode/settings.json'
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
console.log('');
|
|
25
|
+
console.log('Creating Skeleton Application');
|
|
26
|
+
|
|
27
|
+
const args = process.argv;
|
|
28
|
+
let appFolder = path.resolve('.');
|
|
29
|
+
|
|
30
|
+
if ( args.length > 2 ) {
|
|
31
|
+
const name = args[2];
|
|
32
|
+
const folder = path.resolve('.');
|
|
33
|
+
|
|
34
|
+
appFolder = path.join(folder, name);
|
|
35
|
+
console.log(` Creating application folder: ${ appFolder }`);
|
|
36
|
+
fs.ensureDirSync(appFolder);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
let addGitlabWorkflow = false;
|
|
40
|
+
let addWorkflowFolder = true;
|
|
41
|
+
|
|
42
|
+
// Check for Gitlab integration option
|
|
43
|
+
if ( args.length > 3 ) {
|
|
44
|
+
for (let i = 3; i < args.length; i++) {
|
|
45
|
+
switch (args[i]) {
|
|
46
|
+
case '-l':
|
|
47
|
+
addGitlabWorkflow = true;
|
|
48
|
+
break;
|
|
49
|
+
case '--skip-workflow':
|
|
50
|
+
case '-w':
|
|
51
|
+
addWorkflowFolder = false;
|
|
52
|
+
break;
|
|
53
|
+
default:
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if ( addGitlabWorkflow ) {
|
|
60
|
+
files.push('.gitlab-ci.yml');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
let setName = false;
|
|
64
|
+
|
|
65
|
+
// Check that there is a package file
|
|
66
|
+
if (!fs.existsSync(path.join(appFolder, './package.json'))) {
|
|
67
|
+
console.log(' Adding package.json');
|
|
68
|
+
fs.copySync(path.join(__dirname, 'app.package.json'), path.join(appFolder, 'package.json'));
|
|
69
|
+
setName = true;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const rawdata = fs.readFileSync(path.join(appFolder, 'package.json'));
|
|
73
|
+
const pkg = JSON.parse(rawdata);
|
|
74
|
+
|
|
75
|
+
if (!pkg.scripts) {
|
|
76
|
+
pkg.scripts = {};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (setName) {
|
|
80
|
+
const dirName = path.basename(appFolder);
|
|
81
|
+
|
|
82
|
+
pkg.name = dirName;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
Object.keys(targets).forEach((target) => {
|
|
86
|
+
if (!pkg.scripts[target]) {
|
|
87
|
+
pkg.scripts[target] = targets[target];
|
|
88
|
+
console.log(` Adding script '${ target }' to package.json`);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// Add dependencies
|
|
93
|
+
// Use the same shell version as this app creator
|
|
94
|
+
|
|
95
|
+
const creatorPkgData = fs.readFileSync(path.join(__dirname, 'package.json'));
|
|
96
|
+
const creatorPkg = JSON.parse(creatorPkgData);
|
|
97
|
+
|
|
98
|
+
// Fetch the latest version of @rancher/shell
|
|
99
|
+
const shellVersion = execSync('npm view @rancher/shell version').toString().trim();
|
|
100
|
+
|
|
101
|
+
// Set the latest version of @rancher/shell in the dependencies
|
|
102
|
+
pkg.dependencies['@rancher/shell'] = `^${ shellVersion }`;
|
|
103
|
+
|
|
104
|
+
// Rest of dependencies are in the _pkgs property of package.json - copy then across
|
|
105
|
+
if (creatorPkg._pkgs) {
|
|
106
|
+
Object.keys(creatorPkg._pkgs).forEach((pkgName) => {
|
|
107
|
+
pkg.dependencies[pkgName] = creatorPkg._pkgs[pkgName];
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
fs.writeFileSync(path.join(appFolder, 'package.json'), JSON.stringify(pkg, null, 2));
|
|
112
|
+
|
|
113
|
+
// Add workflow folder if needed
|
|
114
|
+
if ( addWorkflowFolder ) {
|
|
115
|
+
// Point to the workflow directory inside the skeleton application
|
|
116
|
+
const workflowDir = path.join(appFolder, '.github/workflows');
|
|
117
|
+
|
|
118
|
+
if ( !fs.existsSync(workflowDir) ) {
|
|
119
|
+
console.log(' Creating folder: .github/workflows');
|
|
120
|
+
fs.mkdirSync(workflowDir, { recursive: true });
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const workflowFiles = [
|
|
124
|
+
'build-extension-catalog.yml',
|
|
125
|
+
'build-extension-charts.yml'
|
|
126
|
+
];
|
|
127
|
+
|
|
128
|
+
workflowFiles.forEach((fileName) => {
|
|
129
|
+
const dest = path.join(workflowDir, fileName); // Destination in the skeleton application
|
|
130
|
+
const src = path.join(__dirname, 'files/.github/workflows', fileName); // Source in the package
|
|
131
|
+
|
|
132
|
+
if ( !fs.existsSync(dest) ) {
|
|
133
|
+
console.log(` Adding file ${ fileName } to root workflows`);
|
|
134
|
+
fs.copySync(src, dest);
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Copy base files
|
|
140
|
+
files.forEach((file) => {
|
|
141
|
+
const src = path.join(__dirname, 'files', file);
|
|
142
|
+
const dest = path.join(appFolder, file);
|
|
143
|
+
|
|
144
|
+
if (!fs.existsSync(dest)) {
|
|
145
|
+
console.log(` Adding file: ${ file }`);
|
|
146
|
+
|
|
147
|
+
const folder = path.dirname(dest);
|
|
148
|
+
|
|
149
|
+
fs.ensureDirSync(folder);
|
|
150
|
+
|
|
151
|
+
// Create the folder if needed
|
|
152
|
+
fs.copySync(src, dest);
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
console.log('Skeleton Application creation complete.\n');
|
|
157
|
+
|
|
158
|
+
/* eslint-enable no-console */
|
package/app/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rancher/create-app",
|
|
3
|
+
"description": "Rancher UI Application generator",
|
|
4
|
+
"version": "0.0.0",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"author": "SUSE",
|
|
7
|
+
"private": false,
|
|
8
|
+
"bin": "./init",
|
|
9
|
+
"files": [
|
|
10
|
+
"**/*.*",
|
|
11
|
+
"init"
|
|
12
|
+
],
|
|
13
|
+
"engines": {
|
|
14
|
+
"node": ">=12"
|
|
15
|
+
},
|
|
16
|
+
"_requires": [
|
|
17
|
+
"core-js",
|
|
18
|
+
"css-loader",
|
|
19
|
+
"@types/lodash",
|
|
20
|
+
"@rancher/components"
|
|
21
|
+
],
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"fs-extra": "^10.0.0"
|
|
24
|
+
}
|
|
25
|
+
}
|
package/init
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/* eslint-disable no-console */
|
|
3
|
+
|
|
4
|
+
const { execSync } = require('child_process');
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
|
|
8
|
+
const args = process.argv.slice(2);
|
|
9
|
+
let extensionName = '';
|
|
10
|
+
let appName = '';
|
|
11
|
+
let updateOnly = false;
|
|
12
|
+
let skeletonOnly = false;
|
|
13
|
+
let ignoreShellDepCheck = false;
|
|
14
|
+
|
|
15
|
+
args.forEach((arg, index) => {
|
|
16
|
+
switch (arg) {
|
|
17
|
+
case '--update':
|
|
18
|
+
case '-u':
|
|
19
|
+
updateOnly = true;
|
|
20
|
+
break;
|
|
21
|
+
case '--app-name':
|
|
22
|
+
case '-a':
|
|
23
|
+
if ( args[index + 1] && !args[index + 1].startsWith('-') ) {
|
|
24
|
+
appName = args[index + 1];
|
|
25
|
+
} else {
|
|
26
|
+
console.error('Error: Missing value for --app-name or -a option.');
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
break;
|
|
30
|
+
case '--skeleton-only':
|
|
31
|
+
case '-s':
|
|
32
|
+
skeletonOnly = true;
|
|
33
|
+
break;
|
|
34
|
+
case '-i':
|
|
35
|
+
ignoreShellDepCheck = true;
|
|
36
|
+
break;
|
|
37
|
+
default:
|
|
38
|
+
if ( !arg.startsWith('-') && extensionName === '' ) {
|
|
39
|
+
extensionName = arg;
|
|
40
|
+
appName = appName || extensionName;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
if ( !extensionName && !updateOnly && !skeletonOnly ) {
|
|
46
|
+
console.error('Please provide an extension name.');
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const basePath = process.cwd();
|
|
51
|
+
let skeletonPath;
|
|
52
|
+
let isInsideSkeleton = false;
|
|
53
|
+
let directoryExists = false;
|
|
54
|
+
|
|
55
|
+
// Check if we are inside a skeleton application by looking for package.json
|
|
56
|
+
if ( fs.existsSync(path.join(basePath, 'package.json')) ) {
|
|
57
|
+
// Check for @rancher/shell dependency
|
|
58
|
+
const packageJsonPath = path.join(basePath, 'package.json');
|
|
59
|
+
const packageJson = require(packageJsonPath);
|
|
60
|
+
|
|
61
|
+
if ( !ignoreShellDepCheck && (!packageJson.dependencies || !packageJson.dependencies['@rancher/shell']) ) {
|
|
62
|
+
throw new Error('@rancher/shell dependency is missing in package.json.');
|
|
63
|
+
} else {
|
|
64
|
+
isInsideSkeleton = true;
|
|
65
|
+
skeletonPath = basePath;
|
|
66
|
+
}
|
|
67
|
+
} else {
|
|
68
|
+
// If not inside a skeleton, check if a directory with the appName already exists
|
|
69
|
+
skeletonPath = path.join(basePath, appName);
|
|
70
|
+
|
|
71
|
+
if ( fs.existsSync(skeletonPath) ) {
|
|
72
|
+
directoryExists = true;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const pkgPath = path.join(skeletonPath, 'pkg', extensionName);
|
|
77
|
+
const updatePath = path.join(__dirname, 'update');
|
|
78
|
+
|
|
79
|
+
const skeletonExists = fs.existsSync(skeletonPath);
|
|
80
|
+
const pkgExists = fs.existsSync(pkgPath);
|
|
81
|
+
|
|
82
|
+
try {
|
|
83
|
+
if ( updateOnly ) {
|
|
84
|
+
// Run the update script directly
|
|
85
|
+
console.log('Updating applications...');
|
|
86
|
+
execSync(`node ${ path.join(updatePath, 'init') }`, { stdio: 'inherit' });
|
|
87
|
+
|
|
88
|
+
console.log('Update completed successfully.');
|
|
89
|
+
process.exit(0);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// If the directory exists but we're not inside a skeleton, we should exit to prevent overwriting
|
|
93
|
+
if ( directoryExists && !isInsideSkeleton ) {
|
|
94
|
+
throw new Error(`A directory named "${ appName }" already exists. Aborting.`);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Create skeleton application if it doesn't exist
|
|
98
|
+
if ( !isInsideSkeleton && !skeletonExists ) {
|
|
99
|
+
console.log(`Creating skeleton application: ${ appName }...`);
|
|
100
|
+
// Pass all arguments to the app/init script
|
|
101
|
+
execSync(`node ${ path.join(__dirname, 'app', 'init') } ${ appName } ${ args.join(' ') }`, { stdio: 'inherit' });
|
|
102
|
+
|
|
103
|
+
// Ensure the skeleton path directory is created before attempting to change directory
|
|
104
|
+
if ( !fs.existsSync(skeletonPath) ) {
|
|
105
|
+
throw new Error(`Failed to create skeleton application directory: ${ skeletonPath }`);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Change working directory to the newly created skeleton app
|
|
109
|
+
process.chdir(skeletonPath);
|
|
110
|
+
} else if ( isInsideSkeleton ) {
|
|
111
|
+
// If skeleton exists, ensure the working directory is set correctly
|
|
112
|
+
process.chdir(skeletonPath);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if ( skeletonOnly ) {
|
|
116
|
+
console.log('Skeleton application created successfully. No additional packages will be installed.');
|
|
117
|
+
process.exit(0);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if ( pkgExists ) {
|
|
121
|
+
throw new Error(`A package directory for "${ extensionName }" already exists.`);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Check for package existence and create it if necessary
|
|
125
|
+
if ( !pkgExists ) {
|
|
126
|
+
console.log(`Creating package: ${ extensionName }...`);
|
|
127
|
+
execSync(`node ${ path.join(__dirname, 'pkg', 'init') } ${ extensionName } ${ args.join(' ') }`, { stdio: 'inherit' });
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if ( args.includes('--update') || args.includes('-u') ) {
|
|
131
|
+
// Run the update script
|
|
132
|
+
console.log('Updating applications...');
|
|
133
|
+
execSync(`node ${ path.join(updatePath, 'init') } ${ extensionName }`, { stdio: 'inherit' });
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
console.log('Extension created successfully.');
|
|
137
|
+
|
|
138
|
+
if ( skeletonOnly || !isInsideSkeleton ) {
|
|
139
|
+
console.log(`To begin, run: \n\n\tcd ${ appName } && yarn install\n`);
|
|
140
|
+
}
|
|
141
|
+
} catch (error) {
|
|
142
|
+
console.error('Error creating extension:', error);
|
|
143
|
+
process.exit(1);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/* eslint-enable no-console */
|
package/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rancher/create-extension",
|
|
3
|
+
"description": "Rancher UI Extension generator",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"author": "SUSE",
|
|
7
|
+
"private": false,
|
|
8
|
+
"bin": "./init",
|
|
9
|
+
"files": [
|
|
10
|
+
"**/*",
|
|
11
|
+
"init"
|
|
12
|
+
],
|
|
13
|
+
"engines": {
|
|
14
|
+
"node": ">=12"
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"fs-extra": "^10.0.0"
|
|
18
|
+
},
|
|
19
|
+
"_pkgs": {
|
|
20
|
+
"core-js": "3.21.1",
|
|
21
|
+
"css-loader": "6.7.3",
|
|
22
|
+
"@types/lodash": "4.14.184",
|
|
23
|
+
"@rancher/components": "0.2.1-alpha.0"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require('./.shell/pkg/babel.config.js');
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { importTypes } from '@rancher/auto-import';
|
|
2
|
+
import { IPlugin } from '@shell/core/types';
|
|
3
|
+
|
|
4
|
+
// Init the package
|
|
5
|
+
export default function(plugin: IPlugin): void {
|
|
6
|
+
// Auto-import model, detail, edit from the folders
|
|
7
|
+
importTypes(plugin);
|
|
8
|
+
|
|
9
|
+
// Provide plugin metadata from package.json
|
|
10
|
+
plugin.metadata = require('./package.json');
|
|
11
|
+
|
|
12
|
+
// Load a product
|
|
13
|
+
// plugin.addProduct(require('./product'));
|
|
14
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"allowJs": true,
|
|
4
|
+
"target": "esnext",
|
|
5
|
+
"module": "esnext",
|
|
6
|
+
"strict": true,
|
|
7
|
+
"jsx": "preserve",
|
|
8
|
+
"importHelpers": true,
|
|
9
|
+
"moduleResolution": "node",
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"esModuleInterop": true,
|
|
12
|
+
"allowSyntheticDefaultImports": true,
|
|
13
|
+
"sourceMap": true,
|
|
14
|
+
"baseUrl": ".",
|
|
15
|
+
"preserveSymlinks": true,
|
|
16
|
+
"typeRoots": [
|
|
17
|
+
"../../node_modules",
|
|
18
|
+
"../../node_modules/@rancher/shell/types"
|
|
19
|
+
],
|
|
20
|
+
"types": [
|
|
21
|
+
"node",
|
|
22
|
+
"webpack-env",
|
|
23
|
+
"@types/node",
|
|
24
|
+
"@types/jest",
|
|
25
|
+
"@types/lodash",
|
|
26
|
+
"rancher",
|
|
27
|
+
"shell"
|
|
28
|
+
],
|
|
29
|
+
"lib": [
|
|
30
|
+
"esnext",
|
|
31
|
+
"dom",
|
|
32
|
+
"dom.iterable",
|
|
33
|
+
"scripthost"
|
|
34
|
+
],
|
|
35
|
+
"paths": {
|
|
36
|
+
"@shell/*": [
|
|
37
|
+
"../../node_modules/@rancher/shell/*"
|
|
38
|
+
],
|
|
39
|
+
"@components/*": [
|
|
40
|
+
"@rancher/components/*"
|
|
41
|
+
]
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"include": [
|
|
45
|
+
"**/*.ts",
|
|
46
|
+
"**/*.d.ts",
|
|
47
|
+
"**/*.tsx",
|
|
48
|
+
"**/*.vue"
|
|
49
|
+
],
|
|
50
|
+
"exclude": [
|
|
51
|
+
"../../node_modules"
|
|
52
|
+
]
|
|
53
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require('./.shell/pkg/vue.config')(__dirname);
|
package/pkg/init
ADDED
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/* eslint-disable no-console */
|
|
3
|
+
|
|
4
|
+
const { execSync } = require('child_process');
|
|
5
|
+
const fs = require('fs-extra');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const https = require('https');
|
|
8
|
+
|
|
9
|
+
const files = [
|
|
10
|
+
'tsconfig.json',
|
|
11
|
+
'vue.config.js',
|
|
12
|
+
'babel.config.js',
|
|
13
|
+
'index.ts'
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
const topLevelScripts = {
|
|
17
|
+
'build-pkg': './node_modules/@rancher/shell/scripts/build-pkg.sh',
|
|
18
|
+
'serve-pkgs': './node_modules/@rancher/shell/scripts/serve-pkgs',
|
|
19
|
+
'publish-pkgs': './node_modules/@rancher/shell/scripts/extension/publish',
|
|
20
|
+
'parse-tag-name': './node_modules/@rancher/shell/scripts/extension/parse-tag-name'
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const typeFolders = [
|
|
24
|
+
'l10n',
|
|
25
|
+
'models',
|
|
26
|
+
'edit',
|
|
27
|
+
'list',
|
|
28
|
+
'detail'
|
|
29
|
+
];
|
|
30
|
+
|
|
31
|
+
console.log('');
|
|
32
|
+
console.log('Creating Skeleton UI Package');
|
|
33
|
+
|
|
34
|
+
const args = process.argv;
|
|
35
|
+
|
|
36
|
+
const name = args[2];
|
|
37
|
+
const folder = path.resolve('.');
|
|
38
|
+
const pkgFolder = path.join(folder, 'pkg', name);
|
|
39
|
+
|
|
40
|
+
let addTypeFolders = true;
|
|
41
|
+
|
|
42
|
+
if ( args.length > 3 ) {
|
|
43
|
+
for ( let i = 3; i < args.length; i++ ) {
|
|
44
|
+
switch (args[i]) {
|
|
45
|
+
case '--skip-templates':
|
|
46
|
+
case '-t':
|
|
47
|
+
addTypeFolders = false;
|
|
48
|
+
break;
|
|
49
|
+
default:
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const isNodeModulesShell = !fs.existsSync(path.join(folder, 'shell'));
|
|
56
|
+
|
|
57
|
+
if (!isNodeModulesShell) {
|
|
58
|
+
Object.keys(topLevelScripts).forEach((script) => {
|
|
59
|
+
topLevelScripts[script] = topLevelScripts[script].replace('./node_modules/@rancher/shell', './shell');
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
console.log(` Creating package folder: ${ pkgFolder }`);
|
|
64
|
+
|
|
65
|
+
fs.ensureDirSync(pkgFolder);
|
|
66
|
+
|
|
67
|
+
console.log(' Creating package.json');
|
|
68
|
+
fs.copySync(path.join(__dirname, 'pkg.package.json'), path.join(pkgFolder, 'package.json'));
|
|
69
|
+
|
|
70
|
+
const rawdata = fs.readFileSync(path.join(pkgFolder, 'package.json'));
|
|
71
|
+
const pkg = JSON.parse(rawdata);
|
|
72
|
+
|
|
73
|
+
pkg.name = name;
|
|
74
|
+
pkg.description = `${ name } plugin`;
|
|
75
|
+
|
|
76
|
+
// Add annotation for the latest Rancher version by default
|
|
77
|
+
function fetchLatestVersion() {
|
|
78
|
+
console.log(' Fetching latest Rancher Version');
|
|
79
|
+
const options = { headers: { 'User-Agent': 'nodejs' } };
|
|
80
|
+
|
|
81
|
+
https.get('https://api.github.com/repos/rancher/rancher/releases/latest', options, (res) => {
|
|
82
|
+
const { statusCode } = res;
|
|
83
|
+
const contentType = res.headers['content-type'];
|
|
84
|
+
|
|
85
|
+
let error;
|
|
86
|
+
|
|
87
|
+
if ( statusCode !== 200 ) {
|
|
88
|
+
error = new Error(' Request Failed.\n' +
|
|
89
|
+
` Status Code: ${ statusCode }`);
|
|
90
|
+
} else if ( !/^application\/json/.test(contentType) ) {
|
|
91
|
+
error = new Error(' Invalid content-type.\n' +
|
|
92
|
+
` Expected application/json but received ${ contentType }`);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if ( error ) {
|
|
96
|
+
console.log(error.message);
|
|
97
|
+
|
|
98
|
+
res.resume();
|
|
99
|
+
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
res.setEncoding('utf8');
|
|
104
|
+
let rawData = '';
|
|
105
|
+
|
|
106
|
+
res.on('data', (chunk) => {
|
|
107
|
+
rawData += chunk;
|
|
108
|
+
});
|
|
109
|
+
res.on('end', () => {
|
|
110
|
+
try {
|
|
111
|
+
const release = JSON.parse(rawData);
|
|
112
|
+
|
|
113
|
+
if ( release.tag_name ) {
|
|
114
|
+
console.log(` Adding rancher-version annotation '>= ${ release.tag_name }' to package.json`);
|
|
115
|
+
|
|
116
|
+
pkg.rancher = { annotations: { 'catalog.cattle.io/rancher-version': `>= ${ release.tag_name }` } };
|
|
117
|
+
|
|
118
|
+
// Fetch the latest version of @rancher/shell
|
|
119
|
+
const latestShellVersion = execSync('npm view @rancher/shell version').toString().trim() || null;
|
|
120
|
+
|
|
121
|
+
if (!latestShellVersion) {
|
|
122
|
+
console.log('Could not get a shell version from npm, skipping adding catalog.cattle.io/ui-extensions-version annotation to package.json');
|
|
123
|
+
} else {
|
|
124
|
+
const splitShellVersion = latestShellVersion.split('.');
|
|
125
|
+
const majorVersion = splitShellVersion[0];
|
|
126
|
+
const minorVersion = splitShellVersion[1];
|
|
127
|
+
const parsedShellVersion = `${ majorVersion }.${ minorVersion }.0`;
|
|
128
|
+
|
|
129
|
+
console.log(` Adding catalog.cattle.io/ui-extensions-version '>= ${ parsedShellVersion }' to package.json`);
|
|
130
|
+
|
|
131
|
+
pkg.rancher.annotations['catalog.cattle.io/ui-extensions-version'] = `>= ${ parsedShellVersion }`;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
writePackageJson();
|
|
135
|
+
}
|
|
136
|
+
} catch (e) {
|
|
137
|
+
console.log(' Error parsing release data', e);
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
}).on('error', (e) => {
|
|
141
|
+
console.log(' Error fetching latest Rancher Version', e);
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
fetchLatestVersion();
|
|
146
|
+
writePackageJson();
|
|
147
|
+
|
|
148
|
+
function writePackageJson() {
|
|
149
|
+
fs.writeFileSync(path.join(pkgFolder, 'package.json'), JSON.stringify(pkg, null, 2));
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Create type folders if needed
|
|
153
|
+
if (addTypeFolders) {
|
|
154
|
+
typeFolders.forEach((dir) => {
|
|
155
|
+
const dest = path.join(path.join(pkgFolder, dir));
|
|
156
|
+
|
|
157
|
+
if (!fs.existsSync(dest)) {
|
|
158
|
+
console.log(` Creating folder: ${ dir }`);
|
|
159
|
+
fs.mkdirSync(dest);
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Copy base files
|
|
165
|
+
files.forEach((file) => {
|
|
166
|
+
const src = path.join(__dirname, 'files', file);
|
|
167
|
+
const dest = path.join(path.join(pkgFolder, file));
|
|
168
|
+
|
|
169
|
+
if (!fs.existsSync(dest)) {
|
|
170
|
+
console.log(` Adding file: ${ file }`);
|
|
171
|
+
fs.copySync(src, dest);
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
const topLevelRawdata = fs.readFileSync(path.join(folder, 'package.json'));
|
|
176
|
+
const topLevelPkg = JSON.parse(topLevelRawdata);
|
|
177
|
+
let updated = false;
|
|
178
|
+
|
|
179
|
+
Object.keys(topLevelScripts).forEach((target) => {
|
|
180
|
+
if (!topLevelPkg.scripts[target]) {
|
|
181
|
+
topLevelPkg.scripts[target] = topLevelScripts[target];
|
|
182
|
+
console.log(` Adding script '${ target }' to top-level package.json`);
|
|
183
|
+
updated = true;
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
if (updated) {
|
|
188
|
+
fs.writeFileSync(path.join(folder, 'package.json'), JSON.stringify(topLevelPkg, null, 2));
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Update tsconfig if needed
|
|
192
|
+
if (!isNodeModulesShell) {
|
|
193
|
+
const tsconfig = require(path.join(pkgFolder, 'tsconfig.json'));
|
|
194
|
+
|
|
195
|
+
tsconfig.include = updateArray(tsconfig.include);
|
|
196
|
+
|
|
197
|
+
Object.keys(tsconfig.compilerOptions.paths).forEach((p) => {
|
|
198
|
+
tsconfig.compilerOptions.paths[p] = updateArray(tsconfig.compilerOptions.paths[p]);
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
// Update typeRoots
|
|
202
|
+
tsconfig.compilerOptions.typeRoots = updateArray(tsconfig.compilerOptions.typeRoots);
|
|
203
|
+
|
|
204
|
+
fs.writeFileSync(path.join(pkgFolder, 'tsconfig.json'), JSON.stringify(tsconfig, null, 2));
|
|
205
|
+
console.log(' Updated tsconfig.json for shell folder location');
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
console.log('');
|
|
209
|
+
|
|
210
|
+
function updateArray(data) {
|
|
211
|
+
const updated = [];
|
|
212
|
+
|
|
213
|
+
data.forEach((inc) => {
|
|
214
|
+
updated.push(inc.replace('../../node_modules/@rancher/shell', '../../shell'));
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
return updated;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/* eslint-enable no-console */
|
package/pkg/package.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rancher/create-pkg",
|
|
3
|
+
"description": "Rancher UI Package generator",
|
|
4
|
+
"version": "0.0.1",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"author": "SUSE",
|
|
7
|
+
"private": false,
|
|
8
|
+
"bin": "./init",
|
|
9
|
+
"files": [
|
|
10
|
+
"**/*.*",
|
|
11
|
+
"init"
|
|
12
|
+
],
|
|
13
|
+
"engines": {
|
|
14
|
+
"node": ">=12"
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"fs-extra": "^10.0.0"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "NAME",
|
|
3
|
+
"description": "NAME plugin",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"private": false,
|
|
6
|
+
"rancher": true,
|
|
7
|
+
"scripts": {},
|
|
8
|
+
"engines": {
|
|
9
|
+
"node": ">=12"
|
|
10
|
+
},
|
|
11
|
+
"devDependencies": {
|
|
12
|
+
"@vue/cli-plugin-babel": "4.5.18",
|
|
13
|
+
"@vue/cli-service": "4.5.18",
|
|
14
|
+
"@vue/cli-plugin-typescript": "4.5.18"
|
|
15
|
+
},
|
|
16
|
+
"browserslist": [
|
|
17
|
+
"> 1%",
|
|
18
|
+
"last 2 versions",
|
|
19
|
+
"not dead"
|
|
20
|
+
]
|
|
21
|
+
}
|
package/pkg/vue-shim.ts
ADDED
package/update/init
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const fs = require('fs-extra');
|
|
5
|
+
const { spawnSync } = require('child_process');
|
|
6
|
+
|
|
7
|
+
const scriptFolder = path.resolve(__dirname, '..');
|
|
8
|
+
const dest = path.resolve('.');
|
|
9
|
+
|
|
10
|
+
// Remove first two args
|
|
11
|
+
const args = process.argv;
|
|
12
|
+
|
|
13
|
+
args.splice(0, 2);
|
|
14
|
+
|
|
15
|
+
const res = spawnSync(path.join(__dirname, 'upgrade'), args, {
|
|
16
|
+
cwd: dest,
|
|
17
|
+
shell: false,
|
|
18
|
+
stdio: ['ignore', process.stdout, process.stderr],
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
if (res.status !== 0) {
|
|
22
|
+
process.exit(res.status);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Read the existing package.json
|
|
26
|
+
let rawdata = fs.readFileSync(path.join(dest, 'package.json'));
|
|
27
|
+
const appPackage = JSON.parse(rawdata);
|
|
28
|
+
|
|
29
|
+
// Read the package.json from the app creator
|
|
30
|
+
rawdata = fs.readFileSync(path.join(scriptFolder, 'app', 'package.json'));
|
|
31
|
+
const latestPackage = JSON.parse(rawdata);
|
|
32
|
+
|
|
33
|
+
// Read the package.json from the upgrade creator
|
|
34
|
+
rawdata = fs.readFileSync(path.join(scriptFolder, 'package.json'));
|
|
35
|
+
const upgradePackage = JSON.parse(rawdata);
|
|
36
|
+
|
|
37
|
+
// Update dependency versions to match the latest from the creator
|
|
38
|
+
if ( latestPackage.dependencies ) {
|
|
39
|
+
Object.keys(latestPackage.dependencies).forEach((key) => {
|
|
40
|
+
appPackage.dependencies[key] = latestPackage.dependencies[key];
|
|
41
|
+
});
|
|
42
|
+
} else {
|
|
43
|
+
console.warn('No dependencies found in latestPackage.'); // eslint-disable-line no-console
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Add in the webpack resolution
|
|
47
|
+
appPackage.resolutions = appPackage.resolutions || {};
|
|
48
|
+
appPackage.resolutions['**/webpack'] = '4';
|
|
49
|
+
|
|
50
|
+
// Update the version of @rancher/shell
|
|
51
|
+
const shellVersion = upgradePackage.version;
|
|
52
|
+
|
|
53
|
+
appPackage.dependencies['@rancher/shell'] = shellVersion;
|
|
54
|
+
|
|
55
|
+
fs.writeFileSync(path.join(dest, 'package.json'), `${ JSON.stringify(appPackage, null, 2) }\n`);
|
|
56
|
+
|
|
57
|
+
spawnSync(`yarn`, ['install'], {
|
|
58
|
+
cwd: dest,
|
|
59
|
+
shell: false,
|
|
60
|
+
stdio: ['ignore', process.stdout, process.stderr],
|
|
61
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rancher/create-update",
|
|
3
|
+
"description": "Rancher UI Update helper",
|
|
4
|
+
"version": "0.0.0",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"author": "SUSE",
|
|
7
|
+
"private": false,
|
|
8
|
+
"bin": "./init",
|
|
9
|
+
"files": [
|
|
10
|
+
"**/*.*",
|
|
11
|
+
"init",
|
|
12
|
+
"upgrade"
|
|
13
|
+
],
|
|
14
|
+
"engines": {
|
|
15
|
+
"node": ">=12"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"fs-extra": "^10.0.0"
|
|
19
|
+
}
|
|
20
|
+
}
|
package/update/upgrade
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#!/usr/bin/env sh
|
|
2
|
+
|
|
3
|
+
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )"/.. &> /dev/null && pwd )
|
|
4
|
+
|
|
5
|
+
echo "Upgrading Rancher Shell"
|
|
6
|
+
|
|
7
|
+
# Get the version number from the package.json file
|
|
8
|
+
VERSION=$(node -p -e "require('${SCRIPT_DIR}/package.json').version")
|
|
9
|
+
|
|
10
|
+
echo "Updating to version: ${VERSION}"
|
|
11
|
+
echo ""
|
|
12
|
+
|
|
13
|
+
FORCE="false"
|
|
14
|
+
|
|
15
|
+
if [ "$1" == "-f" ]; then
|
|
16
|
+
FORCE="true"
|
|
17
|
+
fi
|
|
18
|
+
|
|
19
|
+
# Check for a clean git repository
|
|
20
|
+
if [ ! -d ".git" ] && [ "${FORCE}" == "false" ]; then
|
|
21
|
+
echo "Not runnning in a git repository. Re-run with -f to ignore this check"
|
|
22
|
+
echo "Note: This action will update your files - running in a git repository will ensure you have visibility over changes made"
|
|
23
|
+
exit 1
|
|
24
|
+
fi
|
|
25
|
+
|
|
26
|
+
if [[ $(git diff --stat) != '' ]] && [ "${FORCE}" == "false" ]; then
|
|
27
|
+
echo "Git repository is not clean. Re-run with -f to ignore this check"
|
|
28
|
+
echo "Note: This action will update your files - running in a clean git repository will ensure you have visibility over changes made"
|
|
29
|
+
exit 1
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
# Check this is a Rancher Extension
|
|
33
|
+
if [ ! -f "./package.json" ]; then
|
|
34
|
+
echo "Can't find package.json - check you're running from the correct folder"
|
|
35
|
+
exit 1
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
HAS_SHELL=$(grep "\"@rancher/shell\"" package.json -c )
|
|
39
|
+
if [ "${HAS_SHELL}" != "1" ]; then
|
|
40
|
+
echo "package.json does not reference @rancher/shell - check you're running from the correct folder"
|
|
41
|
+
exit 1
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
# Copy files for the top-level folder (from the app creator)
|
|
45
|
+
rsync ${SCRIPT_DIR}/app/files/* .
|
|
46
|
+
|
|
47
|
+
# Go through each folder in the pkg folder and update their files
|
|
48
|
+
for pkg in ./pkg/*
|
|
49
|
+
do
|
|
50
|
+
if [ -d "${pkg}" ]; then
|
|
51
|
+
pkgName=$(basename $pkg)
|
|
52
|
+
echo "Updating package ${pkgName}"
|
|
53
|
+
|
|
54
|
+
cp ${SCRIPT_DIR}/pkg/files/* ${pkg}
|
|
55
|
+
fi
|
|
56
|
+
done
|