generator-easy-ui5 3.8.1 → 3.9.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/README.md CHANGED
@@ -12,23 +12,25 @@ Easy UI5 (`easy-ui5`) 💙 is a [Yeoman](http://yeoman.io/) generator which enab
12
12
 
13
13
  This generator has been created to simplify the creation of your UI5 prototypes. Now you can scaffold simple UI5 projects from the shell/terminal of your choice. The current best practices (such as [async](https://blogs.sap.com/2018/12/18/ui5ers-buzz-41-best-practices-for-async-loading-in-ui5/)) are already baked into our templates so you don't have to worry about the definition of the metadata files.
14
14
 
15
- The purpose of the `project` subgenerator is to guide you on your first steps with [SAPUI5](https://sapui5.hana.ondemand.com/) and [SAP BTP](https://www.sap.com/products/business-technology-platform.html) deployments. Once you are familiar with those technologies, you might want to tweak the projects to adapt them for productive use-cases (such as continuous deployment pipelines and full i18n).
15
+ The purpose of the (preinstalled) `project generator` is to guide you on your first steps with [SAPUI5](https://sapui5.hana.ondemand.com/) and [SAP BTP](https://www.sap.com/products/business-technology-platform.html) deployments. Once you are familiar with those technologies, you might want to tweak the projects to adapt them for productive use-cases (such as continuous deployment pipelines and full i18n).
16
16
 
17
- > :warning: Starting with Easy UI5 v3, all templates will be outsource to repositories in the [UI5 Community](https://github.com/ui5-community/). This project is from now on a shell that will offer all generators hosted on that GitHub org. Easy UI5 will download and install these repositories when needed.
17
+ > Note: This project was formerly located at the [SAP GitHub organization](https://github.com/SAP). Starting with easy-ui5 v3, all templates were outsourced to repositories in the [UI5 Community](https://github.com/ui5-community/). To highlight easy-ui5 is also a fully community driven project, the project was moved to the [UI5 Community](https://github.com/ui5-community/), too. Still SAP employees take care of managing incoming feature requests and bug reports.
18
18
  >
19
- > By default, it will download the repository [generator-ui5-project](https://github.com/ui5-community/generator-ui5-project/) which contains the templates that were previously integrated in Easy UI5 < 3.
19
+ > By default, it will download the repository [generator-ui5-project](https://github.com/ui5-community/generator-ui5-project/) which contains the templates that were previously integrated in easy-ui5 < 3.
20
20
 
21
21
  ## Requirements
22
22
 
23
- - Get [Node.js](https://nodejs.org/en/download/) (:warning: **version 18 or higher**)
23
+ - Get [Node.js](https://nodejs.org/en/download/) (:warning: **version 20 or higher**).
24
24
 
25
25
  ## Download and Installation
26
26
 
27
- 1. Install the generator
27
+ 1. Install the generator:
28
+
28
29
  ```sh
29
30
  npm install -g yo generator-easy-ui5
30
31
  ```
31
- 2. Verify your installation to see if Yeoman has been installed correctly
32
+
33
+ 2. Verify your installation to see if Yeoman has been installed correctly:
32
34
  ```sh
33
35
  yo
34
36
  ```
@@ -38,12 +40,15 @@ The purpose of the `project` subgenerator is to guide you on your first steps wi
38
40
 
39
41
  > Create your first UI5 App within a few seconds!
40
42
 
41
- 1. Scaffold your UI5 project
43
+ 1. Scaffold your UI5 project:
44
+
42
45
  ```
43
46
  yo easy-ui5 project
44
47
  ```
45
- 2. Answer the prompts to create your new project
46
- 3. Run it locally
48
+
49
+ 2. Answer the prompts to create your new project.
50
+
51
+ 3. Run it locally:
47
52
  ```
48
53
  cd <your project directory>
49
54
  npm start # or "yarn start"
@@ -51,63 +56,64 @@ The purpose of the `project` subgenerator is to guide you on your first steps wi
51
56
 
52
57
  ## Target platforms
53
58
 
54
- During the prompting phase, the generator will ask on which target platform your app should run. Currently, the following options are available:
59
+ During the prompting phase, the project generator will ask on which target platform your app should run. Currently, the following options are available:
55
60
 
56
61
  - Static webserver
57
- - SAP BTP
58
- - SAP HANA XS Advanced
62
+ - Application Router
63
+ - Application Frontend Service
64
+ - SAP HTML5 Application Repository
65
+ - SAP Build Work Zone, standard edition
59
66
  - SAP NetWeaver
60
67
 
61
- > Have a look at [this plugin project](https://github.com/ui5-community/generator-ui5-project/) for more usage instruction and information about the available subcommands.
68
+ > Have a look at the [project generator](https://github.com/ui5-community/generator-ui5-project/) for more usage instruction and information about its available subgenerators.
62
69
 
63
70
  ## More generators
64
71
 
65
72
  And this is just the start!
66
73
 
67
- We made Easy UI5 extensible, so that the entire [UI5 Community](https://github.com/ui5-community/) can build additional plugins to scaffold any UI5-related development activity.
74
+ We made easy-ui5 extensible, so that the entire [UI5 Community](https://github.com/ui5-community/) can build additional plugins to scaffold any UI5-related development activity.
68
75
 
69
- By default, this generator comes with the [project-creation-plugin](https://github.com/ui5-community/generator-ui5-project) but there are many others as well:
76
+ By default, this generator comes with the [project generator](https://github.com/ui5-community/generator-ui5-project) but there are many others as well:
70
77
 
71
- - Create new UI5 libraries [[ui5-community/generator-ui5-library]](https://github.com/ui5-community/generator-ui5-library)
72
- - More are coming!
73
- <!-- - Create new UI5 custom controls
74
- - Create middlewares for the UI5 tooling
75
- - Create tasks for the UI5 tooling
76
- - Create a WDI5 test suite -->
78
+ - [[ui5-community/generator-ui5-ts-app]](https://github.com/ui5-community/generator-ui5-ts-app)
79
+ - [[ui5-community/generator-ui5-ts-app-fcl]](https://github.com/ui5-community/generator-ui5-ts-app-fcl)
80
+ - [[ui5-community/generator-ui5-app]](https://github.com/ui5-community/generator-ui5-app)
81
+ - [[ui5-community/generator-ui5-flp-plugin]](https://github.com/ui5-community/generator-ui5-flp-plugin)
82
+ - [[ui5-community/generator-ui5-library]](https://github.com/ui5-community/generator-ui5-library)
83
+ - [[ui5-community/generator-ui5-ts-library]](https://github.com/ui5-community/generator-ui5-ts-library)
84
+ - [[ui5-community/generator-ui5-wdi5]](https://github.com/ui5-community/generator-ui5-wdi5)
85
+ - [[ui5-community/generator-ui5-add-extension]](https://github.com/ui5-community/generator-ui5-add-extension)
86
+ - [[ui5-community/generator-ui5-library-webc]](https://github.com/ui5-community/generator-ui5-library-webc)
77
87
 
78
- To download and use any of the plugins above, run the following command
88
+ To download and use any of the plugins above, run the following command:
79
89
 
80
90
  ```sh
81
- yo easy-ui5 [project|library] # this is the name of the repositorty without the "generator-ui5-" prefix
91
+ yo easy-ui5 [project|ts-app|...] # this is the name of the repository without the "generator-ui5-" prefix
82
92
  ```
83
93
 
84
- <!-- Are you missing a generator in this list and are you willing to provide one to the entire UI5 community? Great! [This blog posts](TODO INSERT LINK HERE) contains everything you need to know to get started! -->
85
-
86
94
  ## Calling generators
87
95
 
88
- Run the following command to see all subgenerators of a given plugin
96
+ Run the following command to see all subgenerators of a given generator:
89
97
 
90
98
  ```sh
91
- yo easy-ui5 [project|library] --list
99
+ yo easy-ui5 [project|ts-app|...] --list
92
100
  ```
93
101
 
94
- Once you decided on the subgenerator, run:
95
-
96
- Run the following command to see all subgenerators of a given plugin
102
+ Once you decided on the generator, run:
97
103
 
98
104
  ```sh
99
- yo easy-ui5 [project|library] <sub-generator-id>
105
+ yo easy-ui5 [project|ts-app|...]
100
106
  ```
101
107
 
102
108
  ## Proxy settings
103
109
 
104
- If you are running Easy UI5 behind a coporate proxy, just use the default proxy environment variables for Node.js to configure your corporate proxy:
110
+ If you are running easy-ui5 behind a coporate proxy, just use the default proxy environment variables for Node.js to configure your corporate proxy:
105
111
 
106
112
  - `HTTP_PROXY`: Specify the value to use as the HTTP proxy for all connections, e.g., `HTTP_PROXY="http://proxy.mycompany.com:8080/"`.
107
113
  - `HTTPS_PROXY`: Specify the value to use as the HTTPS proxy for all connections, e.g., `HTTPS_PROXY="http://proxy.mycompany.com:8080/"`.
108
114
  - `NO_PROXY`: Define the hosts that should bypass the proxy, e.g., `NO_PROXY="localhost,.mycompany.com,192.168.6.254:80"`.
109
115
 
110
- In addition, Easy UI5 also supports proxy configuration from the `.npmrc` configuration:
116
+ In addition, easy-ui5 also supports proxy configuration from the `.npmrc` configuration:
111
117
 
112
118
  ```text
113
119
  http-proxy=http://proxy.mycompany.com:8080/
@@ -131,17 +137,17 @@ Please use the GitHub bug tracking system to post questions, bug reports or to c
131
137
 
132
138
  ## Contributing
133
139
 
134
- We welcome any type of contribution (code contributions, pull requests, issues) to this easy-ui5 generator equally.
140
+ We welcome any type of contribution (code contributions, pull requests, issues) to this project equally.
135
141
 
136
- Please follow our instructions if you would like to [contribute](https://github.com/SAP/generator-easy-ui5/blob/master/CONTRIBUTING.md).
142
+ Please follow our instructions if you would like to [contribute](https://github.com/ui5-community/generator-easy-ui5/blob/master/CONTRIBUTING.md).
137
143
 
138
144
  [npm-image]: https://img.shields.io/npm/v/generator-easy-ui5.svg
139
145
  [npm-url]: https://www.npmjs.com/package/generator-easy-ui5
140
- [test-image]: https://github.com/SAP/generator-easy-ui5/actions/workflows/main.yml/badge.svg
141
- [test-url]: https://github.com/SAP/generator-easy-ui5/actions/workflows/main.yml
142
- [librariesio-image]: https://img.shields.io/librariesio/github/SAP/generator-easy-ui5
143
- [repo-url]: https://github.com/SAP/generator-easy-ui5
146
+ [test-image]: https://github.com/ui5-community/generator-easy-ui5/actions/workflows/main.yml/badge.svg
147
+ [test-url]: https://github.com/ui5-community/generator-easy-ui5/actions/workflows/main.yml
148
+ [librariesio-image]: https://img.shields.io/librariesio/github/ui5-community/generator-easy-ui5
149
+ [repo-url]: https://github.com/ui5-community/generator-easy-ui5
144
150
  [license-image]: https://img.shields.io/npm/l/generator-easy-ui5.svg
145
- [license-url]: https://github.com/SAP/generator-easy-ui5/blob/master/LICENSE
146
- [reuse-image]: https://api.reuse.software/badge/github.com/SAP/generator-easy-ui5/
147
- [reuse-url]: https://api.reuse.software/info/github.com/SAP/generator-easy-ui5/
151
+ [license-url]: https://github.com/ui5-community/generator-easy-ui5/blob/master/LICENSE
152
+ [reuse-image]: https://api.reuse.software/badge/github.com/ui5-community/generator-easy-ui5/
153
+ [reuse-url]: https://api.reuse.software/info/github.com/ui5-community/generator-easy-ui5/
@@ -0,0 +1,19 @@
1
+ export const generatorArguments = {
2
+ generator: {
3
+ type: String,
4
+ required: false,
5
+ description: "Name of the generator to invoke (without the \x1b[33mgenerator-ui5-\x1b[0m prefix)",
6
+ },
7
+ subcommand: {
8
+ type: String,
9
+ required: false,
10
+ description: "Name of the subcommand to invoke (without the \x1b[33>mgenerator:\x1b[0m prefix)",
11
+ },
12
+ };
13
+
14
+ export default function defineGeneratorArguments(generator) {
15
+ Object.keys(generatorArguments).forEach((argName) => {
16
+ // register the argument for being displayed in the help
17
+ generator.argument(argName, generatorArguments[argName]);
18
+ });
19
+ }
@@ -0,0 +1,119 @@
1
+ import path from "path";
2
+ import os from "os";
3
+ import getNPMConfig from "./getNPMConfig.js";
4
+
5
+ // the command line options of the generator
6
+ export const generatorOptions = {
7
+ pluginsHome: {
8
+ type: String,
9
+ description: "Home directory of the plugin generators",
10
+ default: path.join(os.homedir(), ".npm", "_generator-easy-ui5", "plugin-generators"),
11
+ hide: true, // shouldn't be needed
12
+ npmConfig: true,
13
+ },
14
+ plugins: {
15
+ type: Boolean,
16
+ alias: "p",
17
+ description: "List detailed information about installed plugin generators",
18
+ },
19
+ pluginsWithDevDeps: {
20
+ type: Boolean,
21
+ alias: "dev",
22
+ description: "Installs the plugin generators with dev dependencies (compat mode)",
23
+ },
24
+ ghBaseUrl: {
25
+ type: String,
26
+ description: "Base URL for the Octokit API (defaults to https://api.github.com if undefined)",
27
+ hide: true, // shouldn't be needed
28
+ npmConfig: true,
29
+ },
30
+ ghAuthToken: {
31
+ type: String,
32
+ description: "GitHub authToken to optionally access private generator repositories",
33
+ npmConfig: true,
34
+ },
35
+ ghOrg: {
36
+ type: String,
37
+ description: "GitHub organization to lookup for available generators",
38
+ default: "ui5-community",
39
+ hide: true, // we don't want to recommend to use this option
40
+ },
41
+ ghThreshold: {
42
+ type: Number,
43
+ default: 100,
44
+ hide: true, // shouldn't be needed
45
+ },
46
+ subGeneratorPrefix: {
47
+ type: String,
48
+ description: "Prefix used for the lookup of the available generators",
49
+ default: "generator-ui5-",
50
+ hide: true, // we don't want to recommend to use this option
51
+ },
52
+ addGhBaseUrl: {
53
+ type: String,
54
+ description: "Base URL for the Octokit API for the additional generators (defaults to https://api.github.com if undefined)",
55
+ hide: true, // shouldn't be needed
56
+ npmConfig: true,
57
+ },
58
+ addGhOrg: {
59
+ type: String,
60
+ description: "GitHub organization to lookup for additional available generators",
61
+ hide: true, // we don't want to recommend to use this option
62
+ npmConfig: true,
63
+ },
64
+ addSubGeneratorPrefix: {
65
+ type: String,
66
+ description: "Prefix used for the lookup of the additional available generators",
67
+ default: "generator-",
68
+ hide: true, // we don't want to recommend to use this option
69
+ npmConfig: true,
70
+ },
71
+ embed: {
72
+ type: Boolean,
73
+ description: "Embeds the selected plugin generator",
74
+ hide: true, // shouldn't be needed
75
+ },
76
+ list: {
77
+ type: Boolean,
78
+ description: "List the available subcommands of the generator",
79
+ },
80
+ skipUpdate: {
81
+ type: Boolean,
82
+ description: "Skip the update of the plugin generator",
83
+ },
84
+ forceUpdate: {
85
+ type: Boolean,
86
+ description: "Force the update of the plugin generator",
87
+ },
88
+ offline: {
89
+ type: Boolean,
90
+ alias: "o",
91
+ description: "Running easy-ui5 in offline mode",
92
+ },
93
+ verbose: {
94
+ type: Boolean,
95
+ description: "Enable detailed logging",
96
+ },
97
+ next: {
98
+ type: Boolean,
99
+ description: "Preview the next mode to consume subgenerators from bestofui5.org",
100
+ },
101
+ skipNested: {
102
+ type: Boolean,
103
+ description: "Skips the nested generators and runs only the first subgenerator",
104
+ },
105
+ };
106
+
107
+ export default function defineGeneratorOptions(generator) {
108
+ Object.keys(generatorOptions).forEach((optionName) => {
109
+ const initialValue = generator.options[optionName];
110
+ // register the option for being displayed in the help
111
+ generator.option(optionName, generatorOptions[optionName]);
112
+ const defaultedValue = generator.options[optionName];
113
+ if (generatorOptions[optionName].npmConfig) {
114
+ // if a value is set, use the set value (parameter has higher precedence than npm config)
115
+ // => generator.option(...) applies the default value to generator.options[...] used as last resort
116
+ generator.options[optionName] = initialValue || getNPMConfig(optionName) || defaultedValue;
117
+ }
118
+ });
119
+ }
@@ -0,0 +1,16 @@
1
+ import getNPMConfig from "./getNPMConfig.js";
2
+
3
+ // apply proxy settings to GLOBAL_AGENT to support the proxy configuration for node-fetch using the GLOBAL_AGENT
4
+ // ==> the configuration is derived from the environment variables ([GLOBAL_AGENT_](HTTP|HTTPS|NO)_PROXY) and the npm config ((http|https|no)-proxy)
5
+ // ==> empty values will allow to override the more general proxy settings and make the proxy value undefined
6
+ let HTTP_PROXY, HTTPS_PROXY, NO_PROXY;
7
+ if (global?.GLOBAL_AGENT) {
8
+ HTTP_PROXY = process.env.GLOBAL_AGENT_HTTP_PROXY ?? process.env.HTTP_PROXY ?? process.env.http_proxy ?? getNPMConfig("http-proxy", "") ?? getNPMConfig("proxy", "");
9
+ global.GLOBAL_AGENT.HTTP_PROXY = HTTP_PROXY = HTTP_PROXY || global.GLOBAL_AGENT.HTTP_PROXY;
10
+ HTTPS_PROXY = process.env.GLOBAL_AGENT_HTTPS_PROXY ?? process.env.HTTPS_PROXY ?? process.env.https_proxy ?? getNPMConfig("https-proxy", "") ?? getNPMConfig("proxy", "");
11
+ global.GLOBAL_AGENT.HTTPS_PROXY = HTTPS_PROXY = HTTPS_PROXY || global.GLOBAL_AGENT.HTTPS_PROXY;
12
+ NO_PROXY = process.env.GLOBAL_AGENT_NO_PROXY ?? process.env.NO_PROXY ?? process.env.no_proxy ?? getNPMConfig("no-proxy", "");
13
+ global.GLOBAL_AGENT.NO_PROXY = NO_PROXY = NO_PROXY || global.GLOBAL_AGENT.NO_PROXY;
14
+ }
15
+
16
+ export { HTTP_PROXY, HTTPS_PROXY, NO_PROXY };
@@ -0,0 +1,12 @@
1
+ import libnpmconfig from "libnpmconfig";
2
+
3
+ // helper to retrieve config entries from npm
4
+ // --> npm config set easy-ui5_addGhOrg XYZ
5
+ let npmConfig;
6
+
7
+ export default function getNPMConfig(configName, prefix = "easy-ui5_") {
8
+ if (!npmConfig) {
9
+ npmConfig = libnpmconfig.read();
10
+ }
11
+ return npmConfig && npmConfig[`${prefix}${configName}`];
12
+ }
@@ -1,186 +1,36 @@
1
1
  import Generator from "yeoman-generator";
2
2
 
3
+ import defineGeneratorArguments from "./defineGeneratorArguments.js";
4
+ import defineGeneratorOptions, { generatorOptions } from "./defineGeneratorOptions.js";
5
+ import { HTTP_PROXY, HTTPS_PROXY, NO_PROXY } from "./detectProxySettings.js";
6
+
3
7
  import path from "path";
4
8
  import fs from "fs";
5
- import os from "os";
6
9
  import url from "url";
7
10
 
8
11
  import { glob } from "glob";
9
12
  import chalk from "chalk";
10
13
  import yosay from "yosay";
11
- import libnpmconfig from "libnpmconfig";
14
+ import nodeFetch from "node-fetch";
12
15
  import AdmZip from "adm-zip";
16
+
13
17
  import { request } from "@octokit/request";
14
18
  import { Octokit } from "@octokit/rest";
15
19
  import { throttling } from "@octokit/plugin-throttling";
16
20
  const MyOctokit = Octokit.plugin(throttling);
17
- import spawn from "cross-spawn";
18
- import nodeFetch from "node-fetch";
19
21
 
20
22
  const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
21
23
 
22
- // helper to retrieve config entries from npm
23
- // --> npm config set easy-ui5_addGhOrg XYZ
24
- let npmConfig;
25
- const getNPMConfig = (configName, prefix = "easy-ui5_") => {
26
- if (!npmConfig) {
27
- npmConfig = libnpmconfig.read();
28
- }
29
- return npmConfig && npmConfig[`${prefix}${configName}`];
30
- };
31
-
32
- // apply proxy settings to GLOBAL_AGENT to support the proxy configuration for node-fetch using the GLOBAL_AGENT
33
- // ==> the configuration is derived from the environment variables ([GLOBAL_AGENT_](HTTP|HTTPS|NO)_PROXY) and the npm config ((http|https|no)-proxy)
34
- // ==> empty values will allow to override the more general proxy settings and make the proxy value undefined
35
- let HTTP_PROXY, HTTPS_PROXY, NO_PROXY;
36
- if (global?.GLOBAL_AGENT) {
37
- HTTP_PROXY = process.env.GLOBAL_AGENT_HTTP_PROXY ?? process.env.HTTP_PROXY ?? process.env.http_proxy ?? getNPMConfig("http-proxy", "") ?? getNPMConfig("proxy", "");
38
- global.GLOBAL_AGENT.HTTP_PROXY = HTTP_PROXY = HTTP_PROXY || global.GLOBAL_AGENT.HTTP_PROXY;
39
- HTTPS_PROXY = process.env.GLOBAL_AGENT_HTTPS_PROXY ?? process.env.HTTPS_PROXY ?? process.env.https_proxy ?? getNPMConfig("https-proxy", "") ?? getNPMConfig("proxy", "");
40
- global.GLOBAL_AGENT.HTTPS_PROXY = HTTPS_PROXY = HTTPS_PROXY || global.GLOBAL_AGENT.HTTPS_PROXY;
41
- NO_PROXY = process.env.GLOBAL_AGENT_NO_PROXY ?? process.env.NO_PROXY ?? process.env.no_proxy ?? getNPMConfig("no-proxy", "");
42
- global.GLOBAL_AGENT.NO_PROXY = NO_PROXY = NO_PROXY || global.GLOBAL_AGENT.NO_PROXY;
43
- }
44
-
45
- // the command line options of the generator
46
- const generatorOptions = {
47
- pluginsHome: {
48
- type: String,
49
- description: "Home directory of the plugin generators",
50
- default: path.join(os.homedir(), ".npm", "_generator-easy-ui5", "plugin-generators"),
51
- hide: true, // shouldn't be needed
52
- npmConfig: true,
53
- },
54
- plugins: {
55
- type: Boolean,
56
- alias: "p",
57
- description: "List detailed information about installed plugin generators",
58
- },
59
- pluginsWithDevDeps: {
60
- type: Boolean,
61
- alias: "dev",
62
- description: "Installs the plugin generators with dev dependencies (compat mode)",
63
- },
64
- ghBaseUrl: {
65
- type: String,
66
- description: "Base URL for the Octokit API (defaults to https://api.github.com if undefined)",
67
- hide: true, // shouldn't be needed
68
- npmConfig: true,
69
- },
70
- ghAuthToken: {
71
- type: String,
72
- description: "GitHub authToken to optionally access private generator repositories",
73
- npmConfig: true,
74
- },
75
- ghOrg: {
76
- type: String,
77
- description: "GitHub organization to lookup for available generators",
78
- default: "ui5-community",
79
- hide: true, // we don't want to recommend to use this option
80
- },
81
- ghThreshold: {
82
- type: Number,
83
- default: 100,
84
- hide: true, // shouldn't be needed
85
- },
86
- subGeneratorPrefix: {
87
- type: String,
88
- description: "Prefix used for the lookup of the available generators",
89
- default: "generator-ui5-",
90
- hide: true, // we don't want to recommend to use this option
91
- },
92
- addGhBaseUrl: {
93
- type: String,
94
- description: "Base URL for the Octokit API for the additional generators (defaults to https://api.github.com if undefined)",
95
- hide: true, // shouldn't be needed
96
- npmConfig: true,
97
- },
98
- addGhOrg: {
99
- type: String,
100
- description: "GitHub organization to lookup for additional available generators",
101
- hide: true, // we don't want to recommend to use this option
102
- npmConfig: true,
103
- },
104
- addSubGeneratorPrefix: {
105
- type: String,
106
- description: "Prefix used for the lookup of the additional available generators",
107
- default: "generator-",
108
- hide: true, // we don't want to recommend to use this option
109
- npmConfig: true,
110
- },
111
- embed: {
112
- type: Boolean,
113
- description: "Embeds the selected plugin generator",
114
- hide: true, // shouldn't be needed
115
- },
116
- list: {
117
- type: Boolean,
118
- description: "List the available subcommands of the generator",
119
- },
120
- skipUpdate: {
121
- type: Boolean,
122
- description: "Skip the update of the plugin generator",
123
- },
124
- forceUpdate: {
125
- type: Boolean,
126
- description: "Force the update of the plugin generator",
127
- },
128
- offline: {
129
- type: Boolean,
130
- alias: "o",
131
- description: "Running easy-ui5 in offline mode",
132
- },
133
- verbose: {
134
- type: Boolean,
135
- description: "Enable detailed logging",
136
- },
137
- next: {
138
- type: Boolean,
139
- description: "Preview the next mode to consume subgenerators from bestofui5.org",
140
- },
141
- skipNested: {
142
- type: Boolean,
143
- description: "Skips the nested generators and runs only the first subgenerator",
144
- },
145
- };
146
-
147
- const generatorArgs = {
148
- generator: {
149
- type: String,
150
- required: false,
151
- description: `Name of the generator to invoke (without the ${chalk.yellow("generator-ui5-")} prefix)`,
152
- },
153
- subcommand: {
154
- type: String,
155
- required: false,
156
- description: `Name of the subcommand to invoke (without the ${chalk.yellow("generator:")} prefix)`,
157
- },
158
- };
159
-
160
24
  // The Easy UI5 Generator!
161
- export default class extends Generator {
25
+ export default class EasyUI5Generator extends Generator {
162
26
  constructor(args, opts) {
163
27
  super(args, opts, {
164
28
  // disable the Yeoman 5 package-manager logic (auto install)!
165
29
  customInstallTask: "disabled",
166
30
  });
167
31
 
168
- Object.keys(generatorArgs).forEach((argName) => {
169
- // register the argument for being displayed in the help
170
- this.argument(argName, generatorArgs[argName]);
171
- });
172
-
173
- Object.keys(generatorOptions).forEach((optionName) => {
174
- const initialValue = this.options[optionName];
175
- // register the option for being displayed in the help
176
- this.option(optionName, generatorOptions[optionName]);
177
- const defaultedValue = this.options[optionName];
178
- if (generatorOptions[optionName].npmConfig) {
179
- // if a value is set, use the set value (parameter has higher precedence than npm config)
180
- // => this.option(...) applies the default value to this.options[...] used as last resort
181
- this.options[optionName] = initialValue || getNPMConfig(optionName) || defaultedValue;
182
- }
183
- });
32
+ defineGeneratorArguments(this);
33
+ defineGeneratorOptions(this);
184
34
  }
185
35
 
186
36
  _showBusy(statusText) {
@@ -206,32 +56,30 @@ export default class extends Generator {
206
56
  }
207
57
 
208
58
  async _npmInstall(dir, withDevDeps) {
209
- return new Promise(
210
- function (resolve, reject) {
211
- spawn("npm", ["install", "--no-progress", "--ignore-engines", "--ignore-scripts"], {
212
- stdio: this.config.verbose ? "inherit" : "ignore",
213
- cwd: dir,
214
- env: {
215
- ...process.env,
216
- NO_UPDATE_NOTIFIER: true,
217
- NODE_ENV: withDevDeps ? undefined : "production", // do not install devDependencies!
218
- },
59
+ return new Promise((resolve, reject) => {
60
+ this.spawnCommand("npm", ["install", "--no-progress", "--ignore-engines", "--ignore-scripts"], {
61
+ stdio: this.config.verbose ? "inherit" : "ignore",
62
+ cwd: dir,
63
+ env: {
64
+ ...process.env,
65
+ NO_UPDATE_NOTIFIER: true,
66
+ NODE_ENV: withDevDeps ? undefined : "production", // do not install devDependencies!
67
+ },
68
+ })
69
+ .on("exit", (code) => {
70
+ resolve(code);
219
71
  })
220
- .on("exit", function (code) {
221
- resolve(code);
222
- })
223
- .on("error", function (err) {
224
- reject(err);
225
- });
226
- }.bind(this)
227
- );
72
+ .on("error", (err) => {
73
+ reject(err);
74
+ });
75
+ });
228
76
  }
229
77
 
230
78
  _unzip(pathOrBuffer, targetPath, zipInternalPath /* used for plugin generators from GitHub (e.g. TS tutorial) */) {
231
79
  const zip = new AdmZip(pathOrBuffer);
232
80
  const zipEntries = zip.getEntries();
233
81
  zipEntries.forEach((entry) => {
234
- const match = !entry.isDirectory && entry.entryName.match(/[^\/]+(\/.+)/);
82
+ const match = !entry.isDirectory && entry.entryName.match(/[^/]+(\/.+)/);
235
83
  let entryPath;
236
84
  if (zipInternalPath && match && match[1].startsWith(zipInternalPath)) {
237
85
  entryPath = path.dirname(match[1].substring(zipInternalPath.length));
@@ -262,10 +110,11 @@ export default class extends Generator {
262
110
  async _installGenerator({ octokit, generator, generatorPath }) {
263
111
  // lookup the default path of the generator if not set
264
112
  if (!generator.branch) {
113
+ const { org: owner, name: repo, dir, branch } = generator;
265
114
  try {
266
115
  const repoInfo = await octokit.repos.get({
267
- owner: generator.org,
268
- repo: generator.name,
116
+ owner,
117
+ repo,
269
118
  });
270
119
  generator.branch = repoInfo.data.default_branch;
271
120
  } catch (e) {
@@ -288,7 +137,7 @@ export default class extends Generator {
288
137
  commitSHA = reqBranch.data.commit.sha;
289
138
  } catch (ex) {
290
139
  console.error(
291
- chalk.red(`Failed to retrieve the branch "${generator.branch}" for repository "${generator.name}" for "${generator.org}" organization! Run with --verbose for details!\n(Hint: ${e.message})`)
140
+ chalk.red(`Failed to retrieve the branch "${generator.branch}" for repository "${generator.name}" for "${generator.org}" organization! Run with --verbose for details!\n(Hint: ${ex.message})`),
292
141
  );
293
142
  if (this.options.verbose) {
294
143
  console.error(chalk.red(ex.message));
@@ -426,7 +275,7 @@ export default class extends Generator {
426
275
  if (options.request.retryCount === 0) {
427
276
  // only retries once
428
277
  this.log(
429
- `Retrying after ${retryAfter} seconds. Alternatively, you can cancel this operation and supply an auth token with the \`--ghAuthToken\` option. For more details, run \`yo easy-ui5 --help\`. `
278
+ `Retrying after ${retryAfter} seconds. Alternatively, you can cancel this operation and supply an auth token with the \`--ghAuthToken\` option. For more details, run \`yo easy-ui5 --help\`. `,
430
279
  );
431
280
  return true;
432
281
  }
@@ -470,7 +319,7 @@ export default class extends Generator {
470
319
  };
471
320
 
472
321
  // helper to retrieve the available repositories for a GH user
473
- const listGeneratorsForUser = async (ghUser, subGeneratorPrefix) => {
322
+ const listGeneratorsForUser = async (ghUser, subGeneratorPrefix, threshold) => {
474
323
  const response = await octokit.repos.listForUser({
475
324
  username: ghUser,
476
325
  sort: "name",
@@ -488,13 +337,13 @@ export default class extends Generator {
488
337
  // > yo easy-ui5 SAP-samples/ui5-typescript-tutorial#1.0
489
338
  // > yo easy-ui5 SAP-samples/ui5-typescript-tutorial\!/generator
490
339
  // > yo easy-ui5 SAP-samples/ui5-typescript-tutorial\!/generator#1.0
491
- const reGenerator = /([^\/]+)\/([^\!\#]+)(?:\!([^\#]+))?(?:\#(.+))?/;
340
+ const reGenerator = /([^/]+)\/([^!#]+)(?:!([^#]+))?(?:#(.+))?/;
492
341
  const matchGenerator = reGenerator.exec(this.options.generator);
493
342
  if (matchGenerator) {
494
343
  // derive and path the generator information from command line
495
344
  const [owner, repo, dir = "/generator", branch] = matchGenerator.slice(1);
496
345
  // the plugin path is derived from the owner, repo, dir and branch
497
- const pluginPath = `_/${owner}/${repo}${dir.replace(/[\/\\]/g, "_")}${branch ? `#${branch.replace(/[\/\\]/g, "_")}` : ""}`;
346
+ const pluginPath = `_/${owner}/${repo}${dir.replace(/[/\\]/g, "_")}${branch ? `#${branch.replace(/[/\\]/g, "_")}` : ""}`;
498
347
  generator = {
499
348
  org: owner,
500
349
  name: repo,
@@ -647,7 +496,7 @@ export default class extends Generator {
647
496
  // do not execute the plugin generator during the setup/embed mode
648
497
  if (!this.options.embed) {
649
498
  // filter the local options and the help command
650
- const opts = Object.keys(this._options).filter((optionName) => !(generatorOptions.hasOwnProperty(optionName) || optionName === "help"));
499
+ const opts = Object.keys(this._options).filter((optionName) => !(Object.prototype.hasOwnProperty.call(generatorOptions, optionName) || optionName === "help"));
651
500
 
652
501
  // create the env for the plugin generator
653
502
  let env = this.env; // in case of Yeoman UI the env is injected!
@@ -660,16 +509,16 @@ export default class extends Generator {
660
509
  let subGenerators = await this._getGeneratorMetadata({ env, generatorPath });
661
510
 
662
511
  // helper to derive the generator from the namespace
663
- function deriveGenerator(namespace, defaultValue) {
512
+ const deriveGenerator = (namespace, defaultValue) => {
664
513
  const match = namespace.match(/([^:]+):.+/);
665
514
  return match ? match[1] : defaultValue === undefined ? namespace : defaultValue;
666
- }
515
+ };
667
516
 
668
517
  // helper to derive the subcommand from the namespace
669
- function deriveSubcommand(namespace, defaultValue) {
518
+ const deriveSubcommand = (namespace, defaultValue) => {
670
519
  const match = namespace.match(/^[^:]+:(.+)$/);
671
520
  return match ? match[1] : defaultValue === undefined ? namespace : defaultValue;
672
- }
521
+ };
673
522
 
674
523
  // list the available subgenerators in the console (as help)
675
524
  if (this.options.list) {
@@ -688,7 +537,7 @@ export default class extends Generator {
688
537
  line += ` # ${subGenerator.displayName}`;
689
538
  }
690
539
  return `${output}\n${line}`;
691
- }, `Subcommands (${subGenerators.length}):`)
540
+ }, `Subcommands (${subGenerators.length}):`),
692
541
  );
693
542
  return;
694
543
  }
@@ -783,7 +632,7 @@ export default class extends Generator {
783
632
  this.log(`The nested generator "${nestedGeneratorInfo.org}/${nestedGeneratorInfo.name}" has no subgenerator "${subcommand || "default"}"! Ignoring execution...`);
784
633
  }
785
634
  }
786
- }) || []
635
+ }) || [],
787
636
  );
788
637
  };
789
638
 
@@ -808,26 +657,38 @@ export default class extends Generator {
808
657
  });
809
658
  };
810
659
 
660
+ if (this.options.verbose) {
661
+ this.log(`Running generators in "${generatorPath}"...`);
662
+ }
663
+
811
664
  // chain the execution of the generators
812
665
  let chain = Promise.resolve();
813
666
  for (const subGen of subGensToRun) {
814
- chain = chain.then(
815
- function () {
816
- // we need to use env.run and not composeWith
817
- // to ensure that subgenerators can have different
818
- // dependencies than the root generator
819
- return env.run(subGen, {
820
- verbose: this.options.verbose,
821
- embedded: true,
822
- destinationRoot: this.destinationRoot(),
823
- });
824
- }.bind(this)
825
- );
667
+ chain = chain.then(() => {
668
+ // we need to use env.run and not composeWith
669
+ // to ensure that subgenerators can have different
670
+ // dependencies than the root generator
671
+ return env.run(subGen, {
672
+ verbose: this.options.verbose,
673
+ embedded: true,
674
+ destinationRoot: this.destinationRoot(),
675
+ });
676
+ });
826
677
  }
827
678
 
828
- if (this.options.verbose) {
829
- this.log(`Running generators in "${generatorPath}"...`);
830
- }
679
+ // check whether repo should be initialized or not
680
+ /* TODO
681
+ chain.then(async () => {
682
+ this.initrepo = await this.prompt([
683
+ {
684
+ type: "confirm",
685
+ name: "initrepo",
686
+ message: "Would you like to initialize a local git repository for this project?",
687
+ default: true,
688
+ },
689
+ ]);
690
+ });
691
+ */
831
692
  } else {
832
693
  this.log(`The generator ${chalk.red(this.options.generator)} has no visible subgenerators!`);
833
694
  }
@@ -854,4 +715,18 @@ export default class extends Generator {
854
715
  }
855
716
  }
856
717
  }
718
+
719
+ end() {
720
+ if (this.config.get("initrepo")) {
721
+ this.spawnCommandSync("git", ["init", "--quiet"], {
722
+ cwd: this.destinationPath(),
723
+ });
724
+ this.spawnCommandSync("git", ["add", "."], {
725
+ cwd: this.destinationPath(),
726
+ });
727
+ this.spawnCommandSync("git", ["commit", "--quiet", "--allow-empty", "-m", "Initial commit"], {
728
+ cwd: this.destinationPath(),
729
+ });
730
+ }
731
+ }
857
732
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "generator-easy-ui5",
3
- "version": "3.8.1",
3
+ "version": "3.9.0",
4
4
  "description": "Generator for UI5-based project",
5
5
  "main": "generators/app/index.js",
6
6
  "type": "module",
@@ -9,10 +9,10 @@
9
9
  "plugins"
10
10
  ],
11
11
  "engines": {
12
- "node": ">=18"
12
+ "node": ">=20"
13
13
  },
14
14
  "scripts": {
15
- "prepublishOnly": "npx yo@4.3.1 ./ project --embed",
15
+ "prepublishOnly": "npx yo@5.1.0 ./generators/app/index.js project --embed",
16
16
  "start": "yo easy-ui5 project",
17
17
  "test": "mocha",
18
18
  "test:subgen:list": "yo easy-ui5 project --list",
@@ -24,13 +24,13 @@
24
24
  "lint:staged": "lint-staged",
25
25
  "format": "prettier --write .",
26
26
  "format:staged": "pretty-quick --staged --verbose",
27
- "prepare": "node ./.husky/skip.js || husky install",
27
+ "prepare": "node ./.husky/skip.js || husky",
28
28
  "hooks:commit-msg": "commitlint -e",
29
- "hooks:pre-commit": "npm-run-all --sequential format:staged lint:staged"
29
+ "hooks:pre-commit": "npm run format:staged && npm run lint:staged"
30
30
  },
31
31
  "repository": {
32
32
  "type": "git",
33
- "url": "git+https://github.com/SAP/generator-easy-ui5.git"
33
+ "url": "git+https://github.com/ui5-community/generator-easy-ui5.git"
34
34
  },
35
35
  "keywords": [
36
36
  "yeoman-generator",
@@ -44,37 +44,38 @@
44
44
  "author": "SAP",
45
45
  "license": "Apache-2.0",
46
46
  "bugs": {
47
- "url": "https://github.com/SAP/generator-easy-ui5/issues"
47
+ "url": "https://github.com/ui5-community/generator-easy-ui5/issues"
48
48
  },
49
- "homepage": "https://github.com/SAP/generator-easy-ui5#readme",
49
+ "homepage": "https://github.com/ui5-community/generator-easy-ui5#readme",
50
50
  "dependencies": {
51
- "@octokit/plugin-throttling": "^8.1.3",
52
- "@octokit/rest": "^20.0.2",
53
- "adm-zip": "^0.5.10",
54
- "chalk": "^5.3.0",
51
+ "@octokit/plugin-throttling": "^11.0.3",
52
+ "@octokit/rest": "^22.0.1",
53
+ "adm-zip": "^0.5.16",
54
+ "chalk": "^5.6.2",
55
55
  "colors": "^1.4.0",
56
- "glob": "^10.3.10",
56
+ "glob": "^13.0.0",
57
57
  "libnpmconfig": "^1.2.1",
58
58
  "node-fetch": "^3.3.2",
59
- "rimraf": "^5.0.5",
60
- "yeoman-environment": "^3.19.3",
61
- "yeoman-generator": "^5.10.0",
62
- "yosay": "^2.0.2"
59
+ "rimraf": "^6.1.2",
60
+ "yeoman-environment": "^5.1.2",
61
+ "yeoman-generator": "^7.5.1",
62
+ "yosay": "^3.0.0"
63
63
  },
64
64
  "devDependencies": {
65
- "@commitlint/cli": "^18.4.3",
66
- "@commitlint/config-conventional": "^18.4.3",
67
- "conventional-changelog-cli": "^4.1.0",
65
+ "@commitlint/cli": "^20.2.0",
66
+ "@commitlint/config-conventional": "^20.2.0",
67
+ "conventional-changelog-cli": "^5.0.0",
68
68
  "cz-conventional-changelog": "^3.3.0",
69
- "eslint": "^8.54.0",
70
- "husky": "^8.0.3",
71
- "lint-staged": "^15.1.0",
72
- "mocha": "^10.2.0",
69
+ "eslint": "^9.39.2",
70
+ "fs-extra": "^11.3.3",
71
+ "husky": "^9.1.7",
72
+ "lint-staged": "^16.2.7",
73
+ "mocha": "^11.7.5",
73
74
  "npm-run-all": "^4.1.5",
74
- "prettier": "^2.8.8",
75
- "pretty-quick": "^3.1.3",
75
+ "prettier": "^3.7.4",
76
+ "pretty-quick": "^4.2.2",
76
77
  "yeoman-assert": "^3.1.1",
77
- "yeoman-test": "^7.4.0"
78
+ "yeoman-test": "^11.2.0"
78
79
  },
79
80
  "config": {
80
81
  "commitizen": {
Binary file