evophp 1.1.0 → 1.1.1
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 +106 -83
- package/bin/evophp.js +3 -2
- package/commands/help.js +38 -37
- package/commands/install.js +34 -15
- package/commands/new.js +88 -37
- package/package.json +1 -1
- package/utils/git.js +43 -11
- package/utils/github.js +49 -0
- package/utils/helpers.js +32 -1
package/README.md
CHANGED
|
@@ -1,152 +1,175 @@
|
|
|
1
1
|
# EvoPHP CLI - Comprehensive Guide
|
|
2
2
|
|
|
3
3
|
## Overview
|
|
4
|
+
|
|
4
5
|
EvoPHP CLI is a command-line interface designed to simplify the development and management of projects, plugins, and themes within the EvoPHP ecosystem. With intuitive commands and shorthands, developers can quickly set up projects, manage dependencies, and handle plugin/theme creation and installation with ease.
|
|
5
6
|
|
|
6
7
|
---
|
|
7
8
|
|
|
8
9
|
## Table of Contents
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
10
|
+
|
|
11
|
+
* [Installation](#installation)
|
|
12
|
+
* [All Commands](#all-commands)
|
|
13
|
+
|
|
14
|
+
* [Initialization](#initialization)
|
|
15
|
+
* [Plugin/Theme Creation](#plugintheme-creation)
|
|
16
|
+
* [Plugin/Theme Installation](#plugintheme-installation)
|
|
17
|
+
* [Plugin/Theme Uninstallation](#plugintheme-uninstallation)
|
|
18
|
+
* [Dependency Management](#dependency-management)
|
|
19
|
+
* [Authentication & PAT Storage](#authentication--pat-storage)
|
|
20
|
+
* [Further Documentation](#further-documentation)
|
|
18
21
|
|
|
19
22
|
---
|
|
20
23
|
|
|
21
24
|
## Installation
|
|
22
25
|
|
|
23
26
|
### Prerequisites
|
|
27
|
+
|
|
24
28
|
Ensure the following are installed on your system:
|
|
25
|
-
|
|
26
|
-
|
|
29
|
+
|
|
30
|
+
* **Node.js**: Verify with `node -v` and `npm -v`
|
|
31
|
+
* **Composer**: Required for PHP dependencies
|
|
27
32
|
|
|
28
33
|
### Install EvoPHP
|
|
29
|
-
|
|
34
|
+
|
|
30
35
|
```bash
|
|
31
36
|
npm install -g evophp
|
|
32
37
|
```
|
|
33
38
|
|
|
34
|
-
This
|
|
39
|
+
This makes the `evophp` CLI available globally.
|
|
35
40
|
|
|
36
41
|
---
|
|
37
42
|
|
|
38
43
|
## All Commands
|
|
39
44
|
|
|
40
45
|
### Initialization
|
|
46
|
+
|
|
41
47
|
```bash
|
|
42
|
-
evophp init
|
|
48
|
+
evophp init [project-name]
|
|
43
49
|
```
|
|
44
|
-
|
|
45
|
-
|
|
50
|
+
|
|
51
|
+
* Initializes a new EvoPHP project.
|
|
52
|
+
* Examples:
|
|
53
|
+
|
|
46
54
|
```bash
|
|
47
55
|
evophp init
|
|
48
|
-
evophp init
|
|
56
|
+
evophp init my-project
|
|
49
57
|
```
|
|
50
58
|
|
|
51
59
|
---
|
|
52
60
|
|
|
53
61
|
### Plugin/Theme Creation
|
|
62
|
+
|
|
54
63
|
```bash
|
|
55
|
-
evophp
|
|
64
|
+
evophp new plugin <name>
|
|
65
|
+
evophp new theme <name>
|
|
66
|
+
evophp n plugin <name>
|
|
67
|
+
evophp n theme <name>
|
|
56
68
|
```
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
+
|
|
70
|
+
* Creates a new plugin or theme from a template.
|
|
71
|
+
|
|
72
|
+
* Supports:
|
|
73
|
+
|
|
74
|
+
* Just `<name>` → Uses your GitHub account (token required)
|
|
75
|
+
* `<author>/<name>` → Creates in the specified GitHub account
|
|
76
|
+
|
|
77
|
+
* Examples:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
evophp new plugin MyPlugin # Uses your GitHub
|
|
81
|
+
evophp n plugin johndoe/BlogEnhancer # Uses johndoe's GitHub
|
|
82
|
+
```
|
|
69
83
|
|
|
70
84
|
---
|
|
71
85
|
|
|
72
86
|
### Plugin/Theme Installation
|
|
87
|
+
|
|
73
88
|
```bash
|
|
74
|
-
evophp
|
|
89
|
+
evophp install plugin <name>
|
|
90
|
+
evophp install theme <name>
|
|
91
|
+
evophp i plugin <name>
|
|
92
|
+
evophp i theme <name>
|
|
75
93
|
```
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
94
|
+
|
|
95
|
+
* Installs a plugin or theme from GitHub into your project.
|
|
96
|
+
|
|
97
|
+
* Supports:
|
|
98
|
+
|
|
99
|
+
* Just `<name>` → Clones from your GitHub account (token required)
|
|
100
|
+
* `<author>/<name>` → Clones from public GitHub repo (no token required)
|
|
101
|
+
|
|
102
|
+
* Examples:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
evophp install plugin MyPlugin
|
|
106
|
+
evophp i theme johndoe/EvoTheme
|
|
107
|
+
```
|
|
88
108
|
|
|
89
109
|
---
|
|
90
110
|
|
|
91
111
|
### Plugin/Theme Uninstallation
|
|
112
|
+
|
|
92
113
|
```bash
|
|
93
|
-
evophp
|
|
114
|
+
evophp uninstall plugin <name>
|
|
115
|
+
evophp uninstall theme <name>
|
|
116
|
+
evophp u plugin <name>
|
|
117
|
+
evophp u theme <name>
|
|
94
118
|
```
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
evophp uninstall theme example-theme
|
|
105
|
-
evophp u theme example-theme
|
|
106
|
-
```
|
|
119
|
+
|
|
120
|
+
* Removes the installed plugin or theme from the project.
|
|
121
|
+
|
|
122
|
+
* Examples:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
evophp uninstall plugin MyPlugin
|
|
126
|
+
evophp u theme EvoTheme
|
|
127
|
+
```
|
|
107
128
|
|
|
108
129
|
---
|
|
109
130
|
|
|
110
131
|
### Dependency Management
|
|
132
|
+
|
|
111
133
|
```bash
|
|
112
|
-
evophp
|
|
134
|
+
evophp install-dependencies <plugin-name>
|
|
135
|
+
evophp d <plugin-name>
|
|
113
136
|
```
|
|
114
|
-
- Install npm production dependencies.
|
|
115
|
-
- Examples:
|
|
116
|
-
```bash
|
|
117
|
-
evophp install-dependencies example-plugin
|
|
118
|
-
evophp d example-plugin
|
|
119
|
-
```
|
|
120
137
|
|
|
121
|
-
|
|
138
|
+
* Adds or installs plugin dependencies.
|
|
139
|
+
|
|
140
|
+
#### Production (npm):
|
|
141
|
+
|
|
122
142
|
```bash
|
|
123
|
-
evophp d
|
|
143
|
+
evophp d MyPlugin
|
|
124
144
|
```
|
|
125
|
-
- Install npm development dependencies.
|
|
126
|
-
- Examples:
|
|
127
|
-
```bash
|
|
128
|
-
evophp install-dependencies example-plugin --dev
|
|
129
|
-
evophp d example-plugin --dev
|
|
130
|
-
```
|
|
131
145
|
|
|
132
|
-
####
|
|
146
|
+
#### Development (npm):
|
|
147
|
+
|
|
133
148
|
```bash
|
|
134
|
-
evophp d
|
|
149
|
+
evophp d MyPlugin --dev
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
#### PHP (Composer):
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
evophp d MyPlugin --composer
|
|
135
156
|
```
|
|
136
|
-
- Install composer dependencies.
|
|
137
|
-
- Examples:
|
|
138
|
-
```bash
|
|
139
|
-
evophp install-dependencies example-plugin --composer
|
|
140
|
-
evophp d example-plugin --composer
|
|
141
|
-
```
|
|
142
157
|
|
|
143
158
|
---
|
|
144
159
|
|
|
145
|
-
##
|
|
146
|
-
|
|
147
|
-
|
|
160
|
+
## Authentication & PAT Storage
|
|
161
|
+
|
|
162
|
+
When using a command with just `<name>` (e.g. `evophp new plugin MyPlugin`), EvoPHP CLI will:
|
|
163
|
+
|
|
164
|
+
* Prompt you for a **GitHub Personal Access Token** (PAT) the first time
|
|
165
|
+
* Automatically store it in `.env.development` for future use
|
|
166
|
+
* Use that token to fetch your GitHub username and manage private/public repos
|
|
167
|
+
|
|
168
|
+
> To change your token later, simply edit or delete `.env.development`.
|
|
148
169
|
|
|
149
170
|
---
|
|
150
171
|
|
|
151
172
|
## Further Documentation
|
|
152
|
-
|
|
173
|
+
|
|
174
|
+
More advanced use cases, templates, and configuration details coming soon at:
|
|
175
|
+
📘 [Official EvoPHP Documentation](#)
|
package/bin/evophp.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
const yargs = require("yargs
|
|
3
|
+
const yargs = require("yargs");
|
|
4
4
|
const { hideBin } = require("yargs/helpers");
|
|
5
5
|
|
|
6
6
|
yargs(hideBin(process.argv))
|
|
7
|
-
.command(require("../commands/new"))
|
|
8
7
|
.command(require("../commands/init"))
|
|
8
|
+
.command(require("../commands/new"))
|
|
9
|
+
.command(require("../commands/install"))
|
|
9
10
|
.command(require("../commands/uninstall"))
|
|
10
11
|
.command(require("../commands/dependencies"))
|
|
11
12
|
.command(require("../commands/help"))
|
package/commands/help.js
CHANGED
|
@@ -9,52 +9,53 @@ module.exports = {
|
|
|
9
9
|
EvoPHP CLI - Help Guide
|
|
10
10
|
==========================================
|
|
11
11
|
|
|
12
|
-
Initialization:
|
|
13
|
-
evophp init [project-name]
|
|
12
|
+
📦 Initialization:
|
|
13
|
+
evophp init [project-name]
|
|
14
14
|
→ Initialize a new Evolution PHP project.
|
|
15
15
|
→ Aliases: none
|
|
16
|
-
→ Example: evophp init my-project
|
|
16
|
+
→ Example: evophp init my-coop-project
|
|
17
17
|
|
|
18
|
-
Plugin
|
|
19
|
-
evophp new plugin <
|
|
20
|
-
evophp
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
→
|
|
18
|
+
🛠️ Plugin & Theme Creation:
|
|
19
|
+
evophp new plugin <name>
|
|
20
|
+
evophp new theme <name>
|
|
21
|
+
evophp n plugin <name>
|
|
22
|
+
evophp n theme <name>
|
|
23
|
+
→ Create a plugin or theme from template repo.
|
|
24
|
+
→ Supports:
|
|
25
|
+
• just <name> → uses your GitHub account
|
|
26
|
+
• author/name → uses any GitHub account
|
|
24
27
|
|
|
25
|
-
|
|
26
|
-
evophp
|
|
27
|
-
|
|
28
|
+
⬇️ Plugin & Theme Installation:
|
|
29
|
+
evophp install plugin <name>
|
|
30
|
+
evophp install plugin author/name
|
|
31
|
+
evophp i theme <name>
|
|
32
|
+
evophp i theme author/name
|
|
33
|
+
→ Install a plugin or theme from GitHub into your project.
|
|
34
|
+
→ Format options:
|
|
35
|
+
• just <name> → installs from your GitHub account
|
|
36
|
+
• author/name → installs from public GitHub repo
|
|
28
37
|
|
|
29
|
-
Plugin
|
|
30
|
-
evophp
|
|
31
|
-
evophp
|
|
32
|
-
|
|
33
|
-
|
|
38
|
+
🗑️ Plugin & Theme Uninstallation:
|
|
39
|
+
evophp uninstall plugin <name>
|
|
40
|
+
evophp uninstall theme <name>
|
|
41
|
+
evophp u plugin <name>
|
|
42
|
+
evophp u theme <name>
|
|
43
|
+
→ Remove an installed plugin or theme and update config.
|
|
34
44
|
|
|
35
|
-
|
|
36
|
-
evophp i theme <author>/<name>
|
|
37
|
-
→ Install a theme from GitHub.
|
|
38
|
-
|
|
39
|
-
Plugin/Theme Uninstallation:
|
|
40
|
-
evophp uninstall plugin <name>
|
|
41
|
-
evophp u plugin <name>
|
|
42
|
-
→ Remove installed plugin.
|
|
43
|
-
→ Aliases: uninstall → u
|
|
44
|
-
|
|
45
|
-
evophp uninstall theme <name>
|
|
46
|
-
evophp u theme <name>
|
|
47
|
-
→ Remove installed theme.
|
|
48
|
-
|
|
49
|
-
Dependency Management:
|
|
45
|
+
🔧 Dependency Management:
|
|
50
46
|
evophp install-dependencies <plugin>
|
|
51
47
|
evophp d <plugin> [--dev|--composer]
|
|
52
|
-
→ Add and install dependencies
|
|
53
|
-
→
|
|
54
|
-
|
|
48
|
+
→ Add and install dependencies for a plugin:
|
|
49
|
+
--dev → JavaScript development dependencies
|
|
50
|
+
--composer → PHP dependencies via Composer
|
|
55
51
|
→ Aliases: install-dependencies → d
|
|
56
52
|
|
|
57
|
-
|
|
53
|
+
🔐 GitHub Authentication:
|
|
54
|
+
When installing or creating with just <name>,
|
|
55
|
+
the CLI will prompt for your GitHub PAT and store it
|
|
56
|
+
in .env.development for future runs.
|
|
57
|
+
|
|
58
|
+
❓ General:
|
|
58
59
|
evophp help
|
|
59
60
|
evophp h
|
|
60
61
|
→ Show this help guide.
|
|
@@ -62,7 +63,7 @@ General:
|
|
|
62
63
|
|
|
63
64
|
==========================================
|
|
64
65
|
Tip: Use --help after any command
|
|
65
|
-
for
|
|
66
|
+
for more usage examples.
|
|
66
67
|
==========================================
|
|
67
68
|
`);
|
|
68
69
|
process.exit(0);
|
package/commands/install.js
CHANGED
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
2
|
const fs = require('fs');
|
|
3
3
|
const { execSync } = require('child_process');
|
|
4
|
-
const { readLineAsync,
|
|
4
|
+
const { readLineAsync, mergeConfig, saveToEnv } = require('../utils/helpers');
|
|
5
|
+
const { getUserData } = require('../utils/github');
|
|
5
6
|
const { cloneRepo } = require('../utils/git');
|
|
6
7
|
const { installDependencies } = require('../utils/dependencies');
|
|
7
8
|
const log = require('../utils/logger');
|
|
9
|
+
require("dotenv").config({ path: "./.env.development" });
|
|
8
10
|
|
|
9
11
|
module.exports = {
|
|
10
12
|
command: 'install [type] [name]',
|
|
11
13
|
aliases: ['i'],
|
|
12
14
|
describe: 'Install a plugin or theme',
|
|
15
|
+
|
|
13
16
|
builder: yargs => yargs
|
|
14
17
|
.positional('type', { describe: 'plugin or theme', type: 'string' })
|
|
15
|
-
.positional('name', { describe: 'author/
|
|
18
|
+
.positional('name', { describe: 'name or author/name', type: 'string' }),
|
|
16
19
|
|
|
17
20
|
handler: async ({ type, name }) => {
|
|
18
21
|
try {
|
|
19
|
-
// Prompt if missing
|
|
20
22
|
if (!type || !['plugin', 'theme'].includes(type.toLowerCase())) {
|
|
21
23
|
type = await readLineAsync("What are you installing? (plugin/theme): ");
|
|
22
24
|
type = type.toLowerCase();
|
|
@@ -27,30 +29,46 @@ module.exports = {
|
|
|
27
29
|
}
|
|
28
30
|
|
|
29
31
|
if (!name) {
|
|
30
|
-
name = await readLineAsync(`Enter the ${type} name (e.g., johndoe/
|
|
32
|
+
name = await readLineAsync(`Enter the ${type} name (e.g., myplugin or johndoe/myplugin): `);
|
|
31
33
|
}
|
|
32
34
|
|
|
33
|
-
|
|
35
|
+
let author, pluginName;
|
|
36
|
+
let gitHubToken = process.env.GITHUB_TOKEN;
|
|
37
|
+
|
|
38
|
+
if (name.includes("/")) {
|
|
39
|
+
// Full author/name provided — no auth required
|
|
40
|
+
[author, pluginName] = name.split("/");
|
|
41
|
+
} else {
|
|
42
|
+
// Token required to determine user
|
|
43
|
+
if (!gitHubToken) {
|
|
44
|
+
gitHubToken = await readLineAsync("Enter your GitHub Personal Access Token: ");
|
|
45
|
+
saveToEnv("GITHUB_TOKEN", gitHubToken);
|
|
46
|
+
log.success("GitHub token saved to .env.development");
|
|
47
|
+
}
|
|
48
|
+
const userData = await getUserData(gitHubToken);
|
|
49
|
+
author = userData.login;
|
|
50
|
+
pluginName = name;
|
|
51
|
+
log.info(`Authenticated as ${author}`);
|
|
52
|
+
}
|
|
34
53
|
|
|
35
54
|
const paths = type === 'plugin'
|
|
36
|
-
? [path.join('Public', 'Modules',
|
|
37
|
-
: [path.join('Public', 'Themes',
|
|
55
|
+
? [path.join('Public', 'Modules', pluginName), path.join('EvoJsDev', 'Modules', pluginName)]
|
|
56
|
+
: [path.join('Public', 'Themes', pluginName)];
|
|
38
57
|
|
|
39
|
-
// Check existing
|
|
40
58
|
for (const p of paths) {
|
|
41
59
|
if (fs.existsSync(p)) {
|
|
42
|
-
log.warn(`${type} "${
|
|
60
|
+
log.warn(`${type} "${pluginName}" already exists at ${p}`);
|
|
43
61
|
process.exit(0);
|
|
44
62
|
}
|
|
45
63
|
}
|
|
46
64
|
|
|
47
|
-
log.info(`Installing ${type} "${
|
|
65
|
+
log.info(`Installing ${type} "${pluginName}" from ${author}...`);
|
|
48
66
|
|
|
49
67
|
if (type === 'plugin') {
|
|
50
|
-
await cloneRepo(
|
|
51
|
-
await cloneRepo(
|
|
68
|
+
await cloneRepo(`${author}/${pluginName}`, null, paths[0]);
|
|
69
|
+
await cloneRepo(`${author}/${pluginName}.js`, null, paths[1]);
|
|
52
70
|
|
|
53
|
-
const configFile = path.resolve(`./EvoJsDev/Modules/${
|
|
71
|
+
const configFile = path.resolve(`./EvoJsDev/Modules/${pluginName}/config.json`);
|
|
54
72
|
if (fs.existsSync(configFile)) {
|
|
55
73
|
const pluginConfig = require(configFile);
|
|
56
74
|
mergeConfig(pluginConfig);
|
|
@@ -60,10 +78,11 @@ module.exports = {
|
|
|
60
78
|
await installDependencies(paths[0], 'php');
|
|
61
79
|
|
|
62
80
|
} else if (type === 'theme') {
|
|
63
|
-
await cloneRepo(
|
|
81
|
+
await cloneRepo(`${author}/${pluginName}`, null, paths[0]);
|
|
64
82
|
}
|
|
65
83
|
|
|
66
|
-
log.success(`The ${type} "${
|
|
84
|
+
log.success(`The ${type} "${pluginName}" has been installed successfully.`);
|
|
85
|
+
|
|
67
86
|
} catch (err) {
|
|
68
87
|
log.error(`Install failed: ${err.message}`);
|
|
69
88
|
process.exit(1);
|
package/commands/new.js
CHANGED
|
@@ -1,25 +1,41 @@
|
|
|
1
1
|
const path = require("path");
|
|
2
2
|
const fs = require("fs");
|
|
3
|
-
const { readLineAsync,
|
|
3
|
+
const { readLineAsync, mergeConfig } = require("../utils/helpers");
|
|
4
4
|
const { getUserData, createGitHubRepo } = require("../utils/github");
|
|
5
|
-
const {
|
|
5
|
+
const { cloneRepo } = require("../utils/git");
|
|
6
6
|
const { editFile, renameFile } = require("../utils/edit");
|
|
7
7
|
const { test } = require("../utils/validate");
|
|
8
8
|
const log = require("../utils/logger");
|
|
9
9
|
require("dotenv").config({ path: "./.env.development" });
|
|
10
10
|
|
|
11
11
|
module.exports = {
|
|
12
|
-
command: "new <type> <
|
|
12
|
+
command: "new <type> <name>",
|
|
13
13
|
aliases: ["n"],
|
|
14
14
|
describe: "Create a new plugin or theme from template",
|
|
15
|
-
|
|
15
|
+
|
|
16
|
+
builder: (yargs) =>
|
|
16
17
|
yargs
|
|
17
|
-
.positional("type", {
|
|
18
|
-
|
|
18
|
+
.positional("type", {
|
|
19
|
+
describe: "plugin or theme",
|
|
20
|
+
type: "string",
|
|
21
|
+
})
|
|
22
|
+
.positional("name", {
|
|
23
|
+
describe: "The plugin or theme name (without author)",
|
|
24
|
+
type: "string",
|
|
25
|
+
}),
|
|
19
26
|
|
|
20
27
|
handler: async ({ type, name }) => {
|
|
21
28
|
try {
|
|
22
|
-
|
|
29
|
+
let gitHubToken = process.env.GITHUB_TOKEN;
|
|
30
|
+
|
|
31
|
+
if (!gitHubToken) {
|
|
32
|
+
gitHubToken = await readLineAsync(
|
|
33
|
+
"Enter GitHub Personal Access Token: "
|
|
34
|
+
);
|
|
35
|
+
const { saveToEnv } = require("../utils/helpers");
|
|
36
|
+
saveToEnv("GITHUB_TOKEN", gitHubToken);
|
|
37
|
+
log.success("GitHub token saved to .env.development");
|
|
38
|
+
}
|
|
23
39
|
type = type.toLowerCase();
|
|
24
40
|
|
|
25
41
|
if (!["plugin", "theme"].includes(type)) {
|
|
@@ -27,14 +43,13 @@ module.exports = {
|
|
|
27
43
|
process.exit(1);
|
|
28
44
|
}
|
|
29
45
|
|
|
30
|
-
|
|
46
|
+
// Get authenticated username from token
|
|
31
47
|
const userData = await getUserData(gitHubToken);
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
process.exit(1);
|
|
35
|
-
}
|
|
48
|
+
const author = userData.login;
|
|
49
|
+
const pluginName = name;
|
|
36
50
|
|
|
37
|
-
log.info(`Authenticated as ${
|
|
51
|
+
log.info(`Authenticated as ${author}`);
|
|
52
|
+
log.info(`Creating ${type} "${pluginName}"...`);
|
|
38
53
|
|
|
39
54
|
if (type === "plugin") {
|
|
40
55
|
const entry = await setupPlugin(gitHubToken, author, pluginName);
|
|
@@ -43,12 +58,11 @@ module.exports = {
|
|
|
43
58
|
await setupTheme(gitHubToken, author, pluginName);
|
|
44
59
|
log.success(`Theme "${pluginName}" created`);
|
|
45
60
|
}
|
|
46
|
-
|
|
47
61
|
} catch (err) {
|
|
48
62
|
log.error(`Creation failed: ${err.message}`);
|
|
49
63
|
process.exit(1);
|
|
50
64
|
}
|
|
51
|
-
}
|
|
65
|
+
},
|
|
52
66
|
};
|
|
53
67
|
|
|
54
68
|
async function setupPlugin(token, author, pluginName) {
|
|
@@ -56,32 +70,55 @@ async function setupPlugin(token, author, pluginName) {
|
|
|
56
70
|
const pluginPrefix = entry.replace("Main", "");
|
|
57
71
|
|
|
58
72
|
await editFile(`./Public/Modules/${pluginName}/Routes.php`, {
|
|
59
|
-
pluginName,
|
|
73
|
+
pluginName,
|
|
74
|
+
entry,
|
|
75
|
+
entryURI: entry.toLowerCase(),
|
|
76
|
+
pluginPrefix,
|
|
60
77
|
});
|
|
61
78
|
|
|
62
79
|
const controllerPath = `./Public/Modules/${pluginName}/Controller.php`;
|
|
63
80
|
if (fs.existsSync(controllerPath)) {
|
|
64
81
|
await editFile(controllerPath, { pluginName, pluginPrefix });
|
|
65
|
-
await renameFile(
|
|
66
|
-
|
|
82
|
+
await renameFile(
|
|
83
|
+
controllerPath,
|
|
84
|
+
`./Public/Modules/${pluginName}/${pluginPrefix}Controller.php`
|
|
85
|
+
);
|
|
86
|
+
await renameFile(
|
|
87
|
+
`./Public/Modules/${pluginName}/Views/Entry`,
|
|
88
|
+
`./Public/Modules/${pluginName}/Views/${entry}`
|
|
89
|
+
);
|
|
67
90
|
}
|
|
68
91
|
|
|
69
92
|
return entry;
|
|
70
93
|
}
|
|
71
94
|
|
|
72
95
|
async function setupPluginRepo(token, author, pluginName) {
|
|
73
|
-
await createGitHubRepo(token,
|
|
74
|
-
await
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
96
|
+
await createGitHubRepo(token, "kinsokafor/EvoPlugin", pluginName);
|
|
97
|
+
await cloneRepo(
|
|
98
|
+
author,
|
|
99
|
+
pluginName,
|
|
100
|
+
path.join("Public", "Modules", pluginName)
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
await createGitHubRepo(token, "kinsokafor/EvoPlugin.js", `${pluginName}.js`);
|
|
104
|
+
await cloneRepo(
|
|
105
|
+
author,
|
|
106
|
+
`${pluginName}.js`,
|
|
107
|
+
path.join("EvoJsDev", "Modules", pluginName)
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
const pluginPrefix = await getValidatedInput("Enter Plugin Prefix?", 3, true);
|
|
111
|
+
const entryURI = await getValidatedInput("Entry URI?", 20);
|
|
81
112
|
const entry = pluginPrefix + "Main";
|
|
82
113
|
|
|
83
|
-
await editFile(`./EvoJsDev/Modules/${pluginName}/config.json`, {
|
|
84
|
-
|
|
114
|
+
await editFile(`./EvoJsDev/Modules/${pluginName}/config.json`, {
|
|
115
|
+
pluginName,
|
|
116
|
+
entry,
|
|
117
|
+
});
|
|
118
|
+
await renameFile(
|
|
119
|
+
`./EvoJsDev/Modules/${pluginName}/Entry`,
|
|
120
|
+
`./EvoJsDev/Modules/${pluginName}/${entry}`
|
|
121
|
+
);
|
|
85
122
|
|
|
86
123
|
const configPath = `./EvoJsDev/Modules/${pluginName}/config.json`;
|
|
87
124
|
if (fs.existsSync(configPath)) {
|
|
@@ -93,18 +130,32 @@ async function setupPluginRepo(token, author, pluginName) {
|
|
|
93
130
|
}
|
|
94
131
|
|
|
95
132
|
async function setupTheme(token, author, pluginName) {
|
|
96
|
-
await createGitHubRepo(token,
|
|
97
|
-
await
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
133
|
+
await createGitHubRepo(token, "kinsokafor/EvoTheme", pluginName);
|
|
134
|
+
await cloneRepo(
|
|
135
|
+
author,
|
|
136
|
+
pluginName,
|
|
137
|
+
path.join("Public", "Themes", pluginName)
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
await editFile(`./Public/Themes/${pluginName}/Data/index.data.php`, {
|
|
141
|
+
pluginName,
|
|
142
|
+
});
|
|
143
|
+
await editFile(`./Public/Themes/${pluginName}/Data/login.data.php`, {
|
|
144
|
+
pluginName,
|
|
145
|
+
});
|
|
146
|
+
await editFile(`./Public/Themes/${pluginName}/Views/index.blade.php`, {
|
|
147
|
+
pluginName,
|
|
148
|
+
});
|
|
149
|
+
await editFile(`./Public/Themes/${pluginName}/Views/login.blade.php`, {
|
|
150
|
+
pluginName,
|
|
151
|
+
});
|
|
103
152
|
}
|
|
104
153
|
|
|
105
154
|
async function getValidatedInput(label, maxLength, caps = false) {
|
|
106
155
|
let input = await readLineAsync(label);
|
|
107
|
-
while (!test(input, maxLength))
|
|
156
|
+
while (!test(input, maxLength)) {
|
|
157
|
+
input = await readLineAsync(label);
|
|
158
|
+
}
|
|
108
159
|
input = input.trim().replaceAll(" ", "");
|
|
109
160
|
return caps ? input.toUpperCase() : input.toLowerCase();
|
|
110
|
-
}
|
|
161
|
+
}
|
package/package.json
CHANGED
package/utils/git.js
CHANGED
|
@@ -1,14 +1,46 @@
|
|
|
1
|
-
const { execSync } = require(
|
|
2
|
-
const fs = require(
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
const { execSync } = require("child_process");
|
|
2
|
+
const fs = require("fs");
|
|
3
|
+
const path = require("path");
|
|
4
|
+
const rimraf = require("rimraf");
|
|
5
|
+
const log = require("./logger");
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Clone a GitHub repo into a destination folder.
|
|
9
|
+
* Supports:
|
|
10
|
+
* cloneRepo("author", "repo", "dest")
|
|
11
|
+
* cloneRepo("author/repo", null, "dest")
|
|
12
|
+
*
|
|
13
|
+
* @param {string} authorOrFull - GitHub username OR "author/repo"
|
|
14
|
+
* @param {string|null} repo - Optional repo name if not included in first arg
|
|
15
|
+
* @param {string} dest - Local destination path
|
|
16
|
+
*/
|
|
17
|
+
async function cloneRepo(authorOrFull, repo, dest) {
|
|
18
|
+
let author = "";
|
|
19
|
+
let repoName = "";
|
|
20
|
+
|
|
21
|
+
if (repo === null || repo === undefined) {
|
|
22
|
+
// authorOrFull is in "author/repo" format
|
|
23
|
+
const parts = authorOrFull.split("/");
|
|
24
|
+
if (parts.length !== 2) {
|
|
25
|
+
log.error("Invalid GitHub repo format. Use 'author/repo'.");
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
[author, repoName] = parts;
|
|
29
|
+
} else {
|
|
30
|
+
// Passed separately
|
|
31
|
+
author = authorOrFull;
|
|
32
|
+
repoName = repo;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const cloneUrl = `https://github.com/${author}/${repoName}.git`;
|
|
36
|
+
|
|
37
|
+
if (fs.existsSync(dest)) {
|
|
38
|
+
log.warn(`Deleting existing folder: ${dest}`);
|
|
39
|
+
rimraf.sync(dest);
|
|
9
40
|
}
|
|
10
|
-
|
|
11
|
-
|
|
41
|
+
|
|
42
|
+
log.info(`Cloning ${author}/${repoName} → ${dest}`);
|
|
43
|
+
execSync(`git clone ${cloneUrl} ${dest}`, { stdio: "inherit" });
|
|
12
44
|
}
|
|
13
45
|
|
|
14
|
-
module.exports = { cloneRepo };
|
|
46
|
+
module.exports = { cloneRepo };
|
package/utils/github.js
CHANGED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// utils/github.js
|
|
2
|
+
const axios = require("axios");
|
|
3
|
+
const log = require("./logger");
|
|
4
|
+
|
|
5
|
+
async function getUserData(token) {
|
|
6
|
+
try {
|
|
7
|
+
const res = await axios.get("https://api.github.com/user", {
|
|
8
|
+
headers: {
|
|
9
|
+
Authorization: `token ${token}`,
|
|
10
|
+
Accept: "application/vnd.github.v3+json",
|
|
11
|
+
},
|
|
12
|
+
});
|
|
13
|
+
return res.data;
|
|
14
|
+
} catch (e) {
|
|
15
|
+
log.error("Failed to fetch GitHub user info.");
|
|
16
|
+
throw e;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async function createGitHubRepo(token, templateRepo, pluginName) {
|
|
21
|
+
try {
|
|
22
|
+
const res = await axios.post(
|
|
23
|
+
`https://api.github.com/repos/${templateRepo}/generate`,
|
|
24
|
+
{
|
|
25
|
+
name: pluginName,
|
|
26
|
+
private: true,
|
|
27
|
+
description: `A new ${templateRepo.split("/")[1]} created from template.`,
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
headers: {
|
|
31
|
+
Authorization: `token ${token}`,
|
|
32
|
+
Accept: "application/vnd.github.v3+json",
|
|
33
|
+
},
|
|
34
|
+
}
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
if (res.status === 201) {
|
|
38
|
+
log.success(`Created repo ${pluginName} from ${templateRepo}`);
|
|
39
|
+
} else {
|
|
40
|
+
log.error("Failed to create repo:", res.data);
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
} catch (e) {
|
|
44
|
+
log.error(`GitHub repo creation failed: ${e.message}`);
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
module.exports = { getUserData, createGitHubRepo };
|
package/utils/helpers.js
CHANGED
|
@@ -122,9 +122,40 @@ function addPluginEntry(pluginName, entryName) {
|
|
|
122
122
|
log.success(`Added entry "${entryPath}" to ${pluginName} config.`);
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
+
const fs = require("fs");
|
|
126
|
+
const path = require("path");
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Save a key-value pair to .env.development (creates or updates)
|
|
130
|
+
* @param {string} key
|
|
131
|
+
* @param {string} value
|
|
132
|
+
*/
|
|
133
|
+
function saveToEnv(key, value) {
|
|
134
|
+
const envPath = path.resolve(".env.development");
|
|
135
|
+
|
|
136
|
+
let env = "";
|
|
137
|
+
if (fs.existsSync(envPath)) {
|
|
138
|
+
env = fs.readFileSync(envPath, "utf-8");
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const regex = new RegExp(`^${key}=.*$`, "m");
|
|
142
|
+
const line = `${key}=${value.trim()}`;
|
|
143
|
+
|
|
144
|
+
if (regex.test(env)) {
|
|
145
|
+
// Update existing key
|
|
146
|
+
env = env.replace(regex, line);
|
|
147
|
+
} else {
|
|
148
|
+
// Append new key
|
|
149
|
+
env += (env.endsWith("\n") ? "" : "\n") + line + "\n";
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
fs.writeFileSync(envPath, env, "utf-8");
|
|
153
|
+
}
|
|
154
|
+
|
|
125
155
|
module.exports = {
|
|
126
156
|
readLineAsync,
|
|
127
157
|
splitPluginName,
|
|
128
158
|
mergeConfig,
|
|
129
|
-
addPluginEntry
|
|
159
|
+
addPluginEntry,
|
|
160
|
+
saveToEnv
|
|
130
161
|
};
|