sandstone-cli 0.6.0 → 0.6.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 +31 -30
- package/lib/build/buildProject.d.ts +4 -3
- package/lib/build/buildProject.js +249 -140
- package/lib/commands/build.d.ts +2 -2
- package/lib/commands/build.js +2 -2
- package/lib/commands/create.d.ts +3 -2
- package/lib/commands/create.js +37 -28
- package/lib/commands/watch.d.ts +2 -2
- package/lib/commands/watch.js +8 -6
- package/lib/template/README.md +2 -2
- package/lib/utils.d.ts +1 -0
- package/lib/utils.js +2 -1
- package/oclif.manifest.json +1 -1
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ $ npm install -g sandstone-cli
|
|
|
19
19
|
$ sand COMMAND
|
|
20
20
|
running command...
|
|
21
21
|
$ sand (-v|--version|version)
|
|
22
|
-
sandstone-cli/0.6.
|
|
22
|
+
sandstone-cli/0.6.1 linux-x64 node-v16.19.0
|
|
23
23
|
$ sand --help [COMMAND]
|
|
24
24
|
USAGE
|
|
25
25
|
$ sand COMMAND
|
|
@@ -36,7 +36,7 @@ USAGE
|
|
|
36
36
|
|
|
37
37
|
## `sand build PATH CONFIG-PATH`
|
|
38
38
|
|
|
39
|
-
Build the
|
|
39
|
+
Build the packs. ⛏
|
|
40
40
|
|
|
41
41
|
```
|
|
42
42
|
USAGE
|
|
@@ -47,7 +47,7 @@ ARGUMENTS
|
|
|
47
47
|
CONFIG-PATH [default: .] Path of the sandstone.config.ts folder.
|
|
48
48
|
|
|
49
49
|
OPTIONS
|
|
50
|
-
-d, --dry Do not save the
|
|
50
|
+
-d, --dry Do not save the pack. Mostly useful with `verbose`.
|
|
51
51
|
-h, --help show CLI help
|
|
52
52
|
-p, --production Runs Sandstone in production mode. This sets process.env.SANDSTONE_ENV to "production".
|
|
53
53
|
-v, --verbose Log all resulting resources: functions, advancements...
|
|
@@ -55,23 +55,23 @@ OPTIONS
|
|
|
55
55
|
--autoReload=port Automatically reload your data pack in-game. Requires to open the world to LAN with
|
|
56
56
|
cheats enabled, and to specify the port.
|
|
57
57
|
|
|
58
|
+
--clientPath=clientPath Path of the client folder. Override the value specified in the configuration file.
|
|
59
|
+
|
|
58
60
|
--description=description Description of the data pack. Override the value specified in the configuration file.
|
|
59
61
|
|
|
60
62
|
--formatVersion=formatVersion Pack format version. Override the value specified in the configuration file.
|
|
61
63
|
|
|
62
64
|
--fullTrace Show the full stack trace on errors.
|
|
63
65
|
|
|
64
|
-
--minecraftPath=minecraftPath Path of the .minecraft folder. Override the value specified in the configuration file.
|
|
65
|
-
|
|
66
66
|
--name=name Name of the data pack. Override the value specified in the configuration file.
|
|
67
67
|
|
|
68
68
|
--namespace=namespace The default namespace. Override the value specified in the configuration file.
|
|
69
69
|
|
|
70
|
-
--
|
|
70
|
+
--root Save the data pack & resource pack in the .minecraft/datapacks &
|
|
71
|
+
.minecraft/resource_packs folders. Override the value specified in the configuration
|
|
71
72
|
file.
|
|
72
73
|
|
|
73
|
-
--
|
|
74
|
-
in the configuration file.
|
|
74
|
+
--serverPath=serverPath Path of the server folder. Override the value specified in the configuration file.
|
|
75
75
|
|
|
76
76
|
--strictErrors Stop data pack compilation on type errors.
|
|
77
77
|
|
|
@@ -84,7 +84,7 @@ EXAMPLES
|
|
|
84
84
|
$ sand build --verbose --dry
|
|
85
85
|
```
|
|
86
86
|
|
|
87
|
-
_See code: [src/commands/build.ts](https://github.com/TheMrZZ/sandstone-cli/blob/v0.6.
|
|
87
|
+
_See code: [src/commands/build.ts](https://github.com/TheMrZZ/sandstone-cli/blob/v0.6.1/src/commands/build.ts)_
|
|
88
88
|
|
|
89
89
|
## `sand create PROJECT-NAME`
|
|
90
90
|
|
|
@@ -98,26 +98,27 @@ ARGUMENTS
|
|
|
98
98
|
PROJECT-NAME Name of the project folder. This is not the name of the data pack.
|
|
99
99
|
|
|
100
100
|
OPTIONS
|
|
101
|
-
-
|
|
102
|
-
-
|
|
103
|
-
-
|
|
104
|
-
-
|
|
101
|
+
-c, --client-path=client-path The client path to write packs at.
|
|
102
|
+
-d, --pack-name=pack-name The name of the data pack.
|
|
103
|
+
-h, --help show CLI help
|
|
104
|
+
-n, --namespace=namespace The default namespace that will be used.
|
|
105
105
|
|
|
106
|
-
-r, --save-root
|
|
107
|
-
|
|
106
|
+
-r, --save-root Save the data pack & resource pack in the .minecraft/datapacks &
|
|
107
|
+
.minecraft/resource_packs folders. Not compatible with --world.
|
|
108
108
|
|
|
109
|
-
-
|
|
110
|
-
--custom-path.
|
|
109
|
+
-s, --server-path=server-path The server path to write the server-side packs at. Not compatible with --world.
|
|
111
110
|
|
|
112
|
-
--
|
|
111
|
+
-w, --world=world The world to save the packs in. Not compatible with --save-root or --server
|
|
113
112
|
|
|
114
|
-
--
|
|
113
|
+
--npm Use npm.
|
|
114
|
+
|
|
115
|
+
--yarn Use yarn instead of npm.
|
|
115
116
|
|
|
116
117
|
EXAMPLE
|
|
117
|
-
$ sand create my-
|
|
118
|
+
$ sand create my-pack
|
|
118
119
|
```
|
|
119
120
|
|
|
120
|
-
_See code: [src/commands/create.ts](https://github.com/TheMrZZ/sandstone-cli/blob/v0.6.
|
|
121
|
+
_See code: [src/commands/create.ts](https://github.com/TheMrZZ/sandstone-cli/blob/v0.6.1/src/commands/create.ts)_
|
|
121
122
|
|
|
122
123
|
## `sand help [COMMAND]`
|
|
123
124
|
|
|
@@ -159,11 +160,11 @@ EXAMPLES
|
|
|
159
160
|
$ sand update --cli --sandstone --skip
|
|
160
161
|
```
|
|
161
162
|
|
|
162
|
-
_See code: [src/commands/update.ts](https://github.com/TheMrZZ/sandstone-cli/blob/v0.6.
|
|
163
|
+
_See code: [src/commands/update.ts](https://github.com/TheMrZZ/sandstone-cli/blob/v0.6.1/src/commands/update.ts)_
|
|
163
164
|
|
|
164
165
|
## `sand watch PATH CONFIG-PATH`
|
|
165
166
|
|
|
166
|
-
Build the
|
|
167
|
+
Build the packs, and rebuild them on file change. ⛏
|
|
167
168
|
|
|
168
169
|
```
|
|
169
170
|
USAGE
|
|
@@ -174,7 +175,7 @@ ARGUMENTS
|
|
|
174
175
|
CONFIG-PATH [default: .] Path of the sandstone.config.ts folder.
|
|
175
176
|
|
|
176
177
|
OPTIONS
|
|
177
|
-
-d, --dry Do not save the
|
|
178
|
+
-d, --dry Do not save the pack. Mostly useful with `verbose`.
|
|
178
179
|
-h, --help show CLI help
|
|
179
180
|
-p, --production Runs Sandstone in production mode. This sets process.env.SANDSTONE_ENV to "production".
|
|
180
181
|
-v, --verbose Log all resulting resources: functions, advancements...
|
|
@@ -182,23 +183,23 @@ OPTIONS
|
|
|
182
183
|
--autoReload=port Automatically reload your data pack in-game. Requires to open the world to LAN with
|
|
183
184
|
cheats enabled, and to specify the port.
|
|
184
185
|
|
|
186
|
+
--clientPath=clientPath Path of the client folder. Override the value specified in the configuration file.
|
|
187
|
+
|
|
185
188
|
--description=description Description of the data pack. Override the value specified in the configuration file.
|
|
186
189
|
|
|
187
190
|
--formatVersion=formatVersion Pack format version. Override the value specified in the configuration file.
|
|
188
191
|
|
|
189
192
|
--fullTrace Show the full stack trace on errors.
|
|
190
193
|
|
|
191
|
-
--minecraftPath=minecraftPath Path of the .minecraft folder. Override the value specified in the configuration file.
|
|
192
|
-
|
|
193
194
|
--name=name Name of the data pack. Override the value specified in the configuration file.
|
|
194
195
|
|
|
195
196
|
--namespace=namespace The default namespace. Override the value specified in the configuration file.
|
|
196
197
|
|
|
197
|
-
--
|
|
198
|
+
--root Save the data pack & resource pack in the .minecraft/datapacks &
|
|
199
|
+
.minecraft/resource_packs folders. Override the value specified in the configuration
|
|
198
200
|
file.
|
|
199
201
|
|
|
200
|
-
--
|
|
201
|
-
in the configuration file.
|
|
202
|
+
--serverPath=serverPath Path of the server folder. Override the value specified in the configuration file.
|
|
202
203
|
|
|
203
204
|
--strictErrors Stop data pack compilation on type errors.
|
|
204
205
|
|
|
@@ -211,5 +212,5 @@ EXAMPLES
|
|
|
211
212
|
$ sand watch --verbose --dry
|
|
212
213
|
```
|
|
213
214
|
|
|
214
|
-
_See code: [src/commands/watch.ts](https://github.com/TheMrZZ/sandstone-cli/blob/v0.6.
|
|
215
|
+
_See code: [src/commands/watch.ts](https://github.com/TheMrZZ/sandstone-cli/blob/v0.6.1/src/commands/watch.ts)_
|
|
215
216
|
<!-- commandsstop -->
|
|
@@ -2,8 +2,9 @@ import { ProjectFolders } from '../utils';
|
|
|
2
2
|
export declare type BuildOptions = {
|
|
3
3
|
world?: string;
|
|
4
4
|
root?: boolean;
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
clientPath?: string;
|
|
6
|
+
serverPath?: string;
|
|
7
|
+
ssh?: string;
|
|
7
8
|
namespace?: string;
|
|
8
9
|
name?: string;
|
|
9
10
|
description?: string;
|
|
@@ -22,4 +23,4 @@ export declare type BuildOptions = {
|
|
|
22
23
|
*
|
|
23
24
|
* @param changedFiles The files that changed since the last build.
|
|
24
25
|
*/
|
|
25
|
-
export declare function buildProject(options: BuildOptions, folders: ProjectFolders, changedFiles?: string[]): Promise<void>;
|
|
26
|
+
export declare function buildProject(options: BuildOptions, folders: ProjectFolders, resourceTypes: string[], changedFiles?: string[]): Promise<void>;
|
|
@@ -1,10 +1,30 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
+
}) : function(o, v) {
|
|
12
|
+
o["default"] = v;
|
|
13
|
+
});
|
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
+
if (mod && mod.__esModule) return mod;
|
|
16
|
+
var result = {};
|
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
+
__setModuleDefault(result, mod);
|
|
19
|
+
return result;
|
|
20
|
+
};
|
|
2
21
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
22
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
23
|
};
|
|
5
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
25
|
exports.buildProject = void 0;
|
|
7
26
|
const path_1 = __importDefault(require("path"));
|
|
27
|
+
const os = __importStar(require("os"));
|
|
8
28
|
const crypto_1 = __importDefault(require("crypto"));
|
|
9
29
|
const util_1 = require("util");
|
|
10
30
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
@@ -13,6 +33,7 @@ const klaw_1 = __importDefault(require("klaw"));
|
|
|
13
33
|
const madge_1 = __importDefault(require("madge"));
|
|
14
34
|
const graph_1 = require("./graph");
|
|
15
35
|
const chalk_1 = __importDefault(require("chalk"));
|
|
36
|
+
const adm_zip_1 = __importDefault(require("adm-zip"));
|
|
16
37
|
const pe = new pretty_error_1.default();
|
|
17
38
|
// Return the hash of a string
|
|
18
39
|
function hash(stringToHash) {
|
|
@@ -33,36 +54,9 @@ async function mkDir(dirPath) {
|
|
|
33
54
|
// Directory already exists
|
|
34
55
|
}
|
|
35
56
|
}
|
|
36
|
-
|
|
57
|
+
let cache = {};
|
|
37
58
|
const dependenciesCache = new graph_1.DependencyGraph({});
|
|
38
59
|
const fileResources = new Map();
|
|
39
|
-
/**
|
|
40
|
-
* Recursively removes empty directories from the given directory.
|
|
41
|
-
*
|
|
42
|
-
* If the directory itself is empty, it is also removed.
|
|
43
|
-
*
|
|
44
|
-
* Code taken from: https://gist.github.com/jakub-g/5903dc7e4028133704a4
|
|
45
|
-
*
|
|
46
|
-
* @param {string} directory Path to the directory to clean up
|
|
47
|
-
*/
|
|
48
|
-
async function removeEmptyDirectories(directory) {
|
|
49
|
-
// lstat does not follow symlinks (in contrast to stat)
|
|
50
|
-
const fileStats = await fs_extra_1.default.lstat(directory);
|
|
51
|
-
if (!fileStats.isDirectory()) {
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
let fileNames = await fs_extra_1.default.readdir(directory);
|
|
55
|
-
if (fileNames.length > 0) {
|
|
56
|
-
const recursiveRemovalPromises = fileNames.map((fileName) => removeEmptyDirectories(path_1.default.join(directory, fileName)));
|
|
57
|
-
await Promise.all(recursiveRemovalPromises);
|
|
58
|
-
// re-evaluate fileNames; after deleting subdirectory
|
|
59
|
-
// we may have parent directory empty now
|
|
60
|
-
fileNames = await fs_extra_1.default.readdir(directory);
|
|
61
|
-
}
|
|
62
|
-
if (fileNames.length === 0) {
|
|
63
|
-
await fs_extra_1.default.rmdir(directory);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
60
|
function getNewModules(dependenciesGraph, rawFiles, projectFolder) {
|
|
67
61
|
const rawFilesPath = rawFiles.map(({ path }) => path);
|
|
68
62
|
// Get only the new modules
|
|
@@ -87,34 +81,103 @@ function diffMap(map1, map2) {
|
|
|
87
81
|
function diffResources(tree1, tree2) {
|
|
88
82
|
return tree1.diff(tree2);
|
|
89
83
|
}
|
|
84
|
+
/**
|
|
85
|
+
*
|
|
86
|
+
* @param worldName The name of the world
|
|
87
|
+
* @param minecraftPath The optional location of the .minecraft folder.
|
|
88
|
+
* If left unspecified, the .minecraft will be found automatically.
|
|
89
|
+
*/
|
|
90
|
+
async function getClientWorldPath(worldName, minecraftPath = undefined) {
|
|
91
|
+
let mcPath;
|
|
92
|
+
if (minecraftPath) {
|
|
93
|
+
mcPath = minecraftPath;
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
mcPath = await getClientPath();
|
|
97
|
+
}
|
|
98
|
+
const savesPath = path_1.default.join(mcPath, 'saves');
|
|
99
|
+
const worldPath = path_1.default.join(savesPath, worldName);
|
|
100
|
+
if (!fs_extra_1.default.existsSync(worldPath)) {
|
|
101
|
+
const existingWorlds = (await fs_extra_1.default.readdir(savesPath, { withFileTypes: true })).filter((f) => f.isDirectory).map((f) => f.name);
|
|
102
|
+
throw new Error(`Unable to locate the "${worldPath}" folder. Word ${worldName} does not exists. List of existing worlds: ${JSON.stringify(existingWorlds, null, 2)}`);
|
|
103
|
+
}
|
|
104
|
+
return worldPath;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Get the .minecraft path
|
|
108
|
+
*/
|
|
109
|
+
async function getClientPath() {
|
|
110
|
+
function getMCPath() {
|
|
111
|
+
switch (os.platform()) {
|
|
112
|
+
case 'win32':
|
|
113
|
+
return path_1.default.join(os.homedir(), 'AppData/Roaming/.minecraft');
|
|
114
|
+
case 'darwin':
|
|
115
|
+
return path_1.default.join(os.homedir(), 'Library/Application Support/minecraft');
|
|
116
|
+
case 'linux':
|
|
117
|
+
default:
|
|
118
|
+
return path_1.default.join(os.homedir(), '.minecraft');
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
const mcPath = getMCPath();
|
|
122
|
+
if (!await fs_extra_1.default.stat(mcPath)) {
|
|
123
|
+
throw new Error('Unable to locate the .minecraft folder. Please specify it manually.');
|
|
124
|
+
}
|
|
125
|
+
return mcPath;
|
|
126
|
+
}
|
|
90
127
|
/**
|
|
91
128
|
* Build the project, but might throw errors.
|
|
92
129
|
*
|
|
93
|
-
* @param
|
|
130
|
+
* @param cliOptions The options to build the project with.
|
|
94
131
|
*
|
|
95
132
|
* @param projectFolder The folder of the project. It needs a sandstone.config.ts, and it or one of its parent needs a package.json.
|
|
96
133
|
*/
|
|
97
|
-
async function _buildProject(
|
|
98
|
-
var _a, _b, _c, _d, _e
|
|
134
|
+
async function _buildProject(cliOptions, { absProjectFolder, rootFolder, sandstoneConfigFolder }, resourceTypes, changedFiles) {
|
|
135
|
+
var _a, _b, _c, _d, _e;
|
|
99
136
|
const sandstoneLocation = path_1.default.join(rootFolder, 'node_modules/sandstone/');
|
|
100
137
|
// First, read sandstone.config.ts to get all properties
|
|
101
138
|
const sandstoneConfig = require(path_1.default.join(sandstoneConfigFolder, 'sandstone.config.ts')).default;
|
|
102
139
|
const { saveOptions, scripts } = sandstoneConfig;
|
|
140
|
+
const outputFolder = path_1.default.join(rootFolder, '.sandstone', 'output');
|
|
103
141
|
/// OPTIONS ///
|
|
104
|
-
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
142
|
+
const clientPath = !cliOptions.production ? (cliOptions.clientPath || saveOptions.clientPath || await getClientPath()) : undefined;
|
|
143
|
+
const server = !cliOptions.production && (cliOptions.serverPath || saveOptions.serverPath || cliOptions.ssh || saveOptions.ssh) ? await (async () => {
|
|
144
|
+
if (cliOptions.ssh || saveOptions.ssh) {
|
|
145
|
+
const sshOptions = JSON.stringify(await fs_extra_1.default.readFile(cliOptions.ssh || saveOptions.ssh, 'utf8'));
|
|
146
|
+
// TODO: implement SFTP
|
|
147
|
+
return {
|
|
148
|
+
readFile: async (relativePath, encoding = 'utf8') => { },
|
|
149
|
+
writeFile: async (relativePath, contents) => { },
|
|
150
|
+
remove: async (relativePath) => { },
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
const serverPath = cliOptions.serverPath || saveOptions.serverPath;
|
|
154
|
+
return {
|
|
155
|
+
readFile: async (relativePath, encoding = 'utf8') => await fs_extra_1.default.readFile(path_1.default.join(serverPath, relativePath), encoding),
|
|
156
|
+
writeFile: async (relativePath, contents) => {
|
|
157
|
+
if (contents === undefined) {
|
|
158
|
+
await fs_extra_1.default.unlink(path_1.default.join(serverPath, relativePath));
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
await fs_extra_1.default.writeFile(path_1.default.join(serverPath, relativePath), contents);
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
remove: async (relativePath) => await fs_extra_1.default.remove(path_1.default.join(serverPath, relativePath))
|
|
165
|
+
};
|
|
166
|
+
})() : undefined;
|
|
167
|
+
let worldName = cliOptions.world || saveOptions.world;
|
|
168
|
+
// Make sure the world exists
|
|
169
|
+
if (worldName && !cliOptions.production) {
|
|
170
|
+
await getClientWorldPath(worldName, clientPath);
|
|
171
|
+
}
|
|
172
|
+
const root = cliOptions.root !== undefined ? cliOptions.root : saveOptions.root;
|
|
173
|
+
const packName = (_a = cliOptions.name) !== null && _a !== void 0 ? _a : sandstoneConfig.name;
|
|
174
|
+
if (worldName && root) {
|
|
175
|
+
throw new Error(`Expected only 'world' or 'root'. Got both.`);
|
|
113
176
|
}
|
|
114
177
|
// Important /!\: The below if statements, which set environment variables, must run before importing any Sandstone file.
|
|
115
178
|
// Set the pack ID environment variable
|
|
116
179
|
// Set production/development mode
|
|
117
|
-
if (
|
|
180
|
+
if (cliOptions.production) {
|
|
118
181
|
process.env.SANDSTONE_ENV = 'production';
|
|
119
182
|
}
|
|
120
183
|
else {
|
|
@@ -124,37 +187,33 @@ async function _buildProject(options, { absProjectFolder, rootFolder, sandstoneC
|
|
|
124
187
|
process.env.PACK_UID = sandstoneConfig.packUid;
|
|
125
188
|
}
|
|
126
189
|
// Set the namespace
|
|
127
|
-
const namespace =
|
|
190
|
+
const namespace = cliOptions.namespace || sandstoneConfig.namespace;
|
|
128
191
|
if (namespace) {
|
|
129
192
|
process.env.NAMESPACE = namespace;
|
|
130
193
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
if (
|
|
134
|
-
process.env[
|
|
194
|
+
const { onConflict } = sandstoneConfig;
|
|
195
|
+
if (onConflict) {
|
|
196
|
+
if (onConflict.default) {
|
|
197
|
+
process.env[`GENERAL_CONFLICT_STRATEGY`] = onConflict.default;
|
|
198
|
+
}
|
|
199
|
+
for (const resource of resourceTypes) {
|
|
200
|
+
if (onConflict[resource]) {
|
|
201
|
+
process.env[`${resource.toUpperCase()}_CONFLICT_STRATEGY`] = onConflict[resource];
|
|
202
|
+
}
|
|
135
203
|
}
|
|
136
204
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
setStrategy('mcfunction', onConflict === null || onConflict === void 0 ? void 0 : onConflict.mcFunction);
|
|
142
|
-
setStrategy('predicate', onConflict === null || onConflict === void 0 ? void 0 : onConflict.predicate);
|
|
143
|
-
setStrategy('recipe', onConflict === null || onConflict === void 0 ? void 0 : onConflict.recipe);
|
|
144
|
-
setStrategy('tag', onConflict === null || onConflict === void 0 ? void 0 : onConflict.tag);
|
|
205
|
+
// JSON indentation
|
|
206
|
+
process.env.INDENTATION = saveOptions.indentation;
|
|
207
|
+
// Pack mcmeta
|
|
208
|
+
process.env.PACK_OPTIONS = JSON.stringify(sandstoneConfig.packs);
|
|
145
209
|
// Configure error display
|
|
146
|
-
if (!
|
|
210
|
+
if (!cliOptions.fullTrace) {
|
|
147
211
|
pe.skipNodeFiles();
|
|
148
212
|
}
|
|
149
213
|
/// IMPORTING USER CODE ///
|
|
150
214
|
// The configuration is ready.
|
|
151
215
|
// Now, let's run the beforeAll script
|
|
152
|
-
|
|
153
|
-
const destinationPath = getDestinationPath(dataPackName, { world, asRootDatapack: root, customPath, minecraftPath });
|
|
154
|
-
await ((_c = scripts === null || scripts === void 0 ? void 0 : scripts.beforeAll) === null || _c === void 0 ? void 0 : _c.call(scripts, {
|
|
155
|
-
dataPackName,
|
|
156
|
-
destination: destinationPath,
|
|
157
|
-
}));
|
|
216
|
+
await ((_b = scripts === null || scripts === void 0 ? void 0 : scripts.beforeAll) === null || _b === void 0 ? void 0 : _b.call(scripts));
|
|
158
217
|
// Finally, let's import all .ts & .js files under ./src.
|
|
159
218
|
let error = false;
|
|
160
219
|
// Get the list of all files
|
|
@@ -188,28 +247,17 @@ async function _buildProject(options, { absProjectFolder, rootFolder, sandstoneC
|
|
|
188
247
|
dependenciesCache.merge(dependenciesGraph);
|
|
189
248
|
// Transform resolved dependents into a flat list of files, and sort them by their number of dependencies
|
|
190
249
|
const newModules = getNewModules(dependenciesCache, changedFilesPaths !== null && changedFilesPaths !== void 0 ? changedFilesPaths : rawFiles, absProjectFolder);
|
|
191
|
-
const {
|
|
192
|
-
const { dataPack } = require(sandstoneLocation + '/init');
|
|
250
|
+
const { sandstonePack } = require(sandstoneLocation);
|
|
193
251
|
// If files changed, we need to clean the cache & delete the related resources
|
|
194
252
|
if (changedFiles) {
|
|
195
253
|
for (const node of newModules) {
|
|
196
|
-
// For
|
|
254
|
+
// For each changed file, we need to reset the require cache
|
|
197
255
|
delete require.cache[path_1.default.join(absProjectFolder, node.name)];
|
|
198
256
|
// Then we need to delete all resources the file created
|
|
199
257
|
const oldResources = fileResources.get(node.name);
|
|
200
258
|
if (oldResources) {
|
|
201
|
-
const
|
|
202
|
-
|
|
203
|
-
dataPack.resources.deleteResource(resource.path, resource.resourceType);
|
|
204
|
-
}
|
|
205
|
-
for (const resource of customResources) {
|
|
206
|
-
dataPack.customResources.delete(resource);
|
|
207
|
-
}
|
|
208
|
-
for (const objective of objectives.keys()) {
|
|
209
|
-
dataPack.objectives.delete(objective);
|
|
210
|
-
}
|
|
211
|
-
for (const rootFunction of rootFunctions) {
|
|
212
|
-
dataPack.rootFunctions.delete(rootFunction);
|
|
259
|
+
for (const resource of oldResources.resources) {
|
|
260
|
+
sandstonePack.core.deleteResource(resource.path, resource.resourceType);
|
|
213
261
|
}
|
|
214
262
|
}
|
|
215
263
|
}
|
|
@@ -218,10 +266,8 @@ async function _buildProject(options, { absProjectFolder, rootFolder, sandstoneC
|
|
|
218
266
|
for (const node of newModules) {
|
|
219
267
|
const modulePath = path_1.default.join(absProjectFolder, node.name);
|
|
220
268
|
const currentResources = {
|
|
221
|
-
resources:
|
|
222
|
-
objectives: new
|
|
223
|
-
rootFunctions: new Set([...dataPack.rootFunctions]),
|
|
224
|
-
customResources: new Set([...dataPack.customResources]),
|
|
269
|
+
resources: new Set([...sandstonePack.core.resourceNodes]),
|
|
270
|
+
objectives: new Set([...sandstonePack.objectives.entries()])
|
|
225
271
|
};
|
|
226
272
|
// We have a module, let's require it!
|
|
227
273
|
const filePath = path_1.default.resolve(modulePath);
|
|
@@ -230,10 +276,6 @@ async function _buildProject(options, { absProjectFolder, rootFolder, sandstoneC
|
|
|
230
276
|
if (await fs_extra_1.default.pathExists(filePath)) {
|
|
231
277
|
require(filePath);
|
|
232
278
|
}
|
|
233
|
-
// Generate the mcfunctions
|
|
234
|
-
for (const mcfunction of dataPack.rootFunctions) {
|
|
235
|
-
await mcfunction.generate();
|
|
236
|
-
}
|
|
237
279
|
}
|
|
238
280
|
catch (e) {
|
|
239
281
|
logError(e, node.name);
|
|
@@ -242,10 +284,8 @@ async function _buildProject(options, { absProjectFolder, rootFolder, sandstoneC
|
|
|
242
284
|
// Now, find the resources that were added by this file & store them.
|
|
243
285
|
// This will be used if those files are changed later.
|
|
244
286
|
const newResources = {
|
|
245
|
-
resources: diffResources(
|
|
246
|
-
|
|
247
|
-
rootFunctions: diffSet(dataPack.rootFunctions, currentResources.rootFunctions),
|
|
248
|
-
objectives: diffMap(dataPack.objectives, currentResources.objectives),
|
|
287
|
+
resources: diffResources(sandstonePack.core.resourceNodes, currentResources.resources),
|
|
288
|
+
objectives: diffSet(sandstonePack.objectives, currentResources.objectives),
|
|
249
289
|
};
|
|
250
290
|
fileResources.set(node.name, newResources);
|
|
251
291
|
}
|
|
@@ -255,72 +295,141 @@ async function _buildProject(options, { absProjectFolder, rootFolder, sandstoneC
|
|
|
255
295
|
/// SAVING RESULTS ///
|
|
256
296
|
// Setup the cache if it doesn't exist.
|
|
257
297
|
// This cache is here to avoid writing files on disk when they did not change.
|
|
258
|
-
const newCache = {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
if (cache[absProjectFolder] === undefined) {
|
|
262
|
-
cache[absProjectFolder] = {
|
|
263
|
-
files: {},
|
|
264
|
-
};
|
|
298
|
+
const newCache = {};
|
|
299
|
+
if (cache === undefined) {
|
|
300
|
+
cache = {};
|
|
265
301
|
}
|
|
266
302
|
// Save the pack
|
|
267
|
-
// Run the beforeSave script
|
|
268
|
-
await ((
|
|
269
|
-
|
|
270
|
-
destination: destinationPath,
|
|
271
|
-
}));
|
|
272
|
-
await savePack(dataPackName, {
|
|
273
|
-
// Save location
|
|
274
|
-
world: world,
|
|
275
|
-
asRootDatapack: root,
|
|
276
|
-
customPath: customPath,
|
|
277
|
-
minecraftPath: minecraftPath,
|
|
278
|
-
indentation: saveOptions.indentation,
|
|
279
|
-
// Data pack mcmeta
|
|
280
|
-
description: (_e = options.description) !== null && _e !== void 0 ? _e : sandstoneConfig.description,
|
|
281
|
-
formatVersion: (_f = options.formatVersion) !== null && _f !== void 0 ? _f : sandstoneConfig.formatVersion,
|
|
303
|
+
// Run the beforeSave script (TODO: This is where sandstone-server will remove restart env vars)
|
|
304
|
+
await ((_c = scripts === null || scripts === void 0 ? void 0 : scripts.beforeSave) === null || _c === void 0 ? void 0 : _c.call(scripts));
|
|
305
|
+
const packTypes = await sandstonePack.save({
|
|
282
306
|
// Additional parameters
|
|
283
|
-
dryRun:
|
|
284
|
-
verbose:
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
const
|
|
288
|
-
//
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
// Add to new cache. We use the relative path as key to make the cache lighter.
|
|
292
|
-
newCache.files[relativePath] = hashValue;
|
|
293
|
-
newCache.resultFolder = destinationPath;
|
|
294
|
-
if (((_a = cache[absProjectFolder].files) === null || _a === void 0 ? void 0 : _a[realPath]) === hashValue) {
|
|
307
|
+
dryRun: cliOptions.dry,
|
|
308
|
+
verbose: cliOptions.verbose,
|
|
309
|
+
fileHandler: (_d = saveOptions.customFileHandler) !== null && _d !== void 0 ? _d : (async ({ relativePath, content, contentSummary }) => {
|
|
310
|
+
// We hash the relative path alongside the content to ensure unique hash.
|
|
311
|
+
const hashValue = hash(contentSummary + relativePath);
|
|
312
|
+
// Add to new cache.
|
|
313
|
+
newCache[relativePath] = hashValue;
|
|
314
|
+
if (cache[relativePath] === hashValue) {
|
|
295
315
|
// Already in cache - skip
|
|
296
316
|
return;
|
|
297
317
|
}
|
|
298
318
|
// Not in cache: write to disk
|
|
319
|
+
const realPath = path_1.default.join(rootFolder, relativePath);
|
|
299
320
|
await mkDir(path_1.default.dirname(realPath));
|
|
300
321
|
return await fs_extra_1.default.writeFile(realPath, content);
|
|
301
322
|
})
|
|
302
323
|
});
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
//
|
|
309
|
-
if (
|
|
310
|
-
|
|
311
|
-
|
|
324
|
+
async function archiveOutput(packType, outputPath) {
|
|
325
|
+
const archive = new adm_zip_1.default();
|
|
326
|
+
await archive.addLocalFolderPromise(outputPath, {});
|
|
327
|
+
await archive.writeZipPromise(`${outputPath}.zip`, { overwrite: true });
|
|
328
|
+
}
|
|
329
|
+
// TODO: implement linking to make the cache more useful when not archiving.
|
|
330
|
+
if (!cliOptions.production) {
|
|
331
|
+
for (const packType of packTypes) {
|
|
332
|
+
const outputPath = path_1.default.join(rootFolder, '.sandstone/output/archives', `${packName}_${packType.type}`);
|
|
333
|
+
if (packType.handleOutput) {
|
|
334
|
+
await packType.handleOutput('output', async (relativePath, encoding = 'utf8') => await fs_extra_1.default.readFile(path_1.default.join(outputPath, relativePath), encoding), async (relativePath, contents) => {
|
|
335
|
+
if (contents === undefined) {
|
|
336
|
+
await fs_extra_1.default.unlink(path_1.default.join(outputPath, relativePath));
|
|
337
|
+
}
|
|
338
|
+
else {
|
|
339
|
+
await fs_extra_1.default.writeFile(path_1.default.join(outputPath, relativePath), contents);
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
if (packType.archiveOutput) {
|
|
344
|
+
archiveOutput(packType, outputPath);
|
|
345
|
+
}
|
|
346
|
+
// Handle client
|
|
347
|
+
if (!(server && packType.networkSides === 'server')) {
|
|
348
|
+
let fullClientPath;
|
|
349
|
+
if (worldName) {
|
|
350
|
+
fullClientPath = path_1.default.join(clientPath, packType.clientPath);
|
|
351
|
+
try {
|
|
352
|
+
fullClientPath = fullClientPath.replace('$packName$', packName);
|
|
353
|
+
}
|
|
354
|
+
catch { }
|
|
355
|
+
try {
|
|
356
|
+
fullClientPath = fullClientPath.replace('$worldName$', worldName);
|
|
357
|
+
}
|
|
358
|
+
catch { }
|
|
359
|
+
}
|
|
360
|
+
else {
|
|
361
|
+
fullClientPath = path_1.default.join(clientPath, packType.rootPath);
|
|
362
|
+
try {
|
|
363
|
+
fullClientPath = fullClientPath.replace('$packName$', packName);
|
|
364
|
+
}
|
|
365
|
+
catch { }
|
|
366
|
+
}
|
|
367
|
+
if (packType.archiveOutput) {
|
|
368
|
+
await fs_extra_1.default.copyFile(`${outputPath}.zip`, `${fullClientPath}.zip`);
|
|
369
|
+
}
|
|
370
|
+
else {
|
|
371
|
+
await fs_extra_1.default.remove(fullClientPath);
|
|
372
|
+
await fs_extra_1.default.copy(outputPath, fullClientPath);
|
|
373
|
+
}
|
|
374
|
+
if (packType.handleOutput) {
|
|
375
|
+
await packType.handleOutput('client', async (relativePath, encoding = 'utf8') => await fs_extra_1.default.readFile(path_1.default.join(clientPath, relativePath), encoding), async (relativePath, contents) => {
|
|
376
|
+
if (contents === undefined) {
|
|
377
|
+
fs_extra_1.default.unlink(path_1.default.join(clientPath, relativePath));
|
|
378
|
+
}
|
|
379
|
+
else {
|
|
380
|
+
await fs_extra_1.default.writeFile(path_1.default.join(clientPath, relativePath), contents);
|
|
381
|
+
}
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
// Handle server
|
|
386
|
+
if (server && (packType.networkSides === 'server' || packType.networkSides === 'both')) {
|
|
387
|
+
let serverPath = packType.serverPath;
|
|
388
|
+
try {
|
|
389
|
+
serverPath = serverPath.replace('$packName$', packName);
|
|
390
|
+
}
|
|
391
|
+
catch { }
|
|
392
|
+
if (packType.archiveOutput) {
|
|
393
|
+
await server.writeFile(await fs_extra_1.default.readFile(`${outputPath}.zip`, 'utf8'), `${serverPath}.zip`);
|
|
394
|
+
}
|
|
395
|
+
else {
|
|
396
|
+
server.remove(serverPath);
|
|
397
|
+
for await (const file of (0, klaw_1.default)(outputPath)) {
|
|
398
|
+
await server.writeFile(path_1.default.join(serverPath, file.path.split(outputPath)[1]), await fs_extra_1.default.readFile(file.path));
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
if (packType.handleOutput) {
|
|
402
|
+
await packType.handleOutput('server', server.readFile, server.writeFile);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
312
405
|
}
|
|
313
|
-
|
|
314
|
-
|
|
406
|
+
}
|
|
407
|
+
else {
|
|
408
|
+
for (const packType of packTypes) {
|
|
409
|
+
const outputPath = path_1.default.join(rootFolder, '.sandstone/output/archives', `${packName}_${packType.type}`);
|
|
410
|
+
if (packType.handleOutput) {
|
|
411
|
+
await packType.handleOutput('output', async (relativePath, encoding = 'utf8') => await fs_extra_1.default.readFile(path_1.default.join(outputPath, relativePath), encoding), async (relativePath, contents) => {
|
|
412
|
+
if (contents === undefined) {
|
|
413
|
+
await fs_extra_1.default.unlink(path_1.default.join(outputPath, relativePath));
|
|
414
|
+
}
|
|
415
|
+
else {
|
|
416
|
+
await fs_extra_1.default.writeFile(path_1.default.join(outputPath, relativePath), contents);
|
|
417
|
+
}
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
if (packType.archiveOutput) {
|
|
421
|
+
archiveOutput(packType, outputPath);
|
|
422
|
+
}
|
|
315
423
|
}
|
|
316
424
|
}
|
|
425
|
+
// Delete old files that aren't cached anymore
|
|
426
|
+
const oldFilesNames = new Set(Object.keys(cache));
|
|
427
|
+
Object.keys(newCache).forEach(name => oldFilesNames.delete(name));
|
|
428
|
+
await Promise.allSettled([...oldFilesNames.values()].map(name => (0, util_1.promisify)(fs_extra_1.default.rm)(path_1.default.join(outputFolder, name))));
|
|
317
429
|
// Override old cache
|
|
318
|
-
cache
|
|
430
|
+
cache = newCache;
|
|
319
431
|
// Run the afterAll script
|
|
320
|
-
await ((
|
|
321
|
-
dataPackName,
|
|
322
|
-
destination: destinationPath,
|
|
323
|
-
}));
|
|
432
|
+
await ((_e = scripts === null || scripts === void 0 ? void 0 : scripts.afterAll) === null || _e === void 0 ? void 0 : _e.call(scripts));
|
|
324
433
|
}
|
|
325
434
|
/**
|
|
326
435
|
* Build the project. Will log errors and never throw any.
|
|
@@ -331,9 +440,9 @@ async function _buildProject(options, { absProjectFolder, rootFolder, sandstoneC
|
|
|
331
440
|
*
|
|
332
441
|
* @param changedFiles The files that changed since the last build.
|
|
333
442
|
*/
|
|
334
|
-
async function buildProject(options, folders, changedFiles) {
|
|
443
|
+
async function buildProject(options, folders, resourceTypes, changedFiles) {
|
|
335
444
|
try {
|
|
336
|
-
await _buildProject(options, folders, changedFiles);
|
|
445
|
+
await _buildProject(options, folders, resourceTypes, changedFiles);
|
|
337
446
|
}
|
|
338
447
|
catch (err) {
|
|
339
448
|
logError(err);
|
package/lib/commands/build.d.ts
CHANGED
|
@@ -9,8 +9,8 @@ export default class Build extends Command {
|
|
|
9
9
|
namespace: import("@oclif/command/lib/flags").IOptionFlag<string | undefined>;
|
|
10
10
|
world: import("@oclif/command/lib/flags").IOptionFlag<string | undefined>;
|
|
11
11
|
root: import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
clientPath: import("@oclif/command/lib/flags").IOptionFlag<string | undefined>;
|
|
13
|
+
serverPath: import("@oclif/command/lib/flags").IOptionFlag<string | undefined>;
|
|
14
14
|
name: import("@oclif/command/lib/flags").IOptionFlag<string | undefined>;
|
|
15
15
|
description: import("@oclif/command/lib/flags").IOptionFlag<string | undefined>;
|
|
16
16
|
formatVersion: import("@oclif/parser/lib/flags").IOptionFlag<number | undefined>;
|
package/lib/commands/build.js
CHANGED
|
@@ -18,11 +18,11 @@ class Build extends command_1.Command {
|
|
|
18
18
|
transpileOnly: !flags.strictErrors,
|
|
19
19
|
project: tsConfigPath,
|
|
20
20
|
});
|
|
21
|
-
(0, buildProject_1.buildProject)(flags, folders);
|
|
21
|
+
(0, buildProject_1.buildProject)(flags, folders, utils_1.datapackResources);
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
exports.default = Build;
|
|
25
|
-
Build.description = 'Build the
|
|
25
|
+
Build.description = 'Build the packs. ⛏';
|
|
26
26
|
Build.examples = [
|
|
27
27
|
'$ sand build',
|
|
28
28
|
'$ sand build --verbose',
|
package/lib/commands/create.d.ts
CHANGED
|
@@ -6,11 +6,12 @@ export default class Create extends Command {
|
|
|
6
6
|
help: import("@oclif/parser/lib/flags").IBooleanFlag<void>;
|
|
7
7
|
yarn: import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
|
|
8
8
|
npm: import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
|
|
9
|
-
'
|
|
9
|
+
'pack-name': flags.IOptionFlag<string | undefined>;
|
|
10
10
|
namespace: flags.IOptionFlag<string | undefined>;
|
|
11
11
|
'save-root': import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
|
|
12
12
|
world: flags.IOptionFlag<string | undefined>;
|
|
13
|
-
'
|
|
13
|
+
'server-path': flags.IOptionFlag<string | undefined>;
|
|
14
|
+
'client-path': flags.IOptionFlag<string | undefined>;
|
|
14
15
|
};
|
|
15
16
|
static args: {
|
|
16
17
|
name: string;
|
package/lib/commands/create.js
CHANGED
|
@@ -28,7 +28,7 @@ class Create extends command_1.Command {
|
|
|
28
28
|
const { args, flags } = this.parse(Create);
|
|
29
29
|
const projectPath = path_1.default.resolve(args['project-name']);
|
|
30
30
|
const projectName = path_1.default.basename(projectPath);
|
|
31
|
-
const
|
|
31
|
+
const packName = await (0, utils_1.getFlagOrPrompt)(flags, 'pack-name', {
|
|
32
32
|
message: 'Name of your data pack (can be changed later) >',
|
|
33
33
|
type: 'input',
|
|
34
34
|
default: projectName,
|
|
@@ -41,27 +41,27 @@ class Create extends command_1.Command {
|
|
|
41
41
|
else if (flags.world) {
|
|
42
42
|
saveOptions.world = flags.world;
|
|
43
43
|
}
|
|
44
|
-
else if (flags['
|
|
45
|
-
saveOptions.
|
|
44
|
+
else if (flags['server-path']) {
|
|
45
|
+
saveOptions.serverPath = flags['server-path'];
|
|
46
46
|
}
|
|
47
|
-
else {
|
|
48
|
-
// User didn't specify a way to save the file. Ask
|
|
47
|
+
else { // TODO: Add support for ssh
|
|
48
|
+
// User didn't specify a way to save the file. Ask them.
|
|
49
49
|
const { saveChoice } = await inquirer_1.default.prompt({
|
|
50
50
|
name: 'saveChoice',
|
|
51
51
|
type: 'list',
|
|
52
|
-
message: 'Where do you want your
|
|
52
|
+
message: 'Where do you want your packs to be saved (can be changed later)?',
|
|
53
53
|
choices: [{
|
|
54
|
-
name: 'In the root .minecraft
|
|
54
|
+
name: 'In the root client (.minecraft) folder',
|
|
55
55
|
value: 'root',
|
|
56
|
-
short: '
|
|
56
|
+
short: 'Client folder',
|
|
57
57
|
}, {
|
|
58
|
-
name: 'In
|
|
58
|
+
name: 'In a world',
|
|
59
59
|
value: 'world',
|
|
60
|
-
short: 'World
|
|
60
|
+
short: 'World',
|
|
61
61
|
}, {
|
|
62
|
-
name: '
|
|
63
|
-
value: 'path',
|
|
64
|
-
short: '
|
|
62
|
+
name: 'In a server',
|
|
63
|
+
value: 'server-path',
|
|
64
|
+
short: 'Server path',
|
|
65
65
|
}],
|
|
66
66
|
});
|
|
67
67
|
if (saveChoice === 'root') {
|
|
@@ -69,22 +69,25 @@ class Create extends command_1.Command {
|
|
|
69
69
|
}
|
|
70
70
|
else if (saveChoice === 'world') {
|
|
71
71
|
const { world } = await inquirer_1.default.prompt({
|
|
72
|
-
name: '
|
|
73
|
-
message: 'What world do you want to save the
|
|
72
|
+
name: 'World',
|
|
73
|
+
message: 'What world do you want to save the packs in? >',
|
|
74
74
|
type: 'list',
|
|
75
75
|
choices: utils_1.getWorldsList,
|
|
76
76
|
});
|
|
77
77
|
saveOptions.world = world;
|
|
78
78
|
}
|
|
79
|
-
else {
|
|
80
|
-
const {
|
|
81
|
-
name: 'path',
|
|
82
|
-
message: 'Where
|
|
79
|
+
else { // TODO: Add native folder selector
|
|
80
|
+
const { serverPath } = await inquirer_1.default.prompt({
|
|
81
|
+
name: 'Server path',
|
|
82
|
+
message: 'Where is the server to save the packs in? Relative paths are accepted. >',
|
|
83
83
|
type: 'input',
|
|
84
84
|
});
|
|
85
|
-
saveOptions.
|
|
85
|
+
saveOptions.serverPath = serverPath;
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
|
+
if (flags['client-path']) {
|
|
89
|
+
saveOptions.clientPath = flags['client-path'];
|
|
90
|
+
}
|
|
88
91
|
const namespace = await (0, utils_1.getFlagOrPrompt)(flags, 'namespace', {
|
|
89
92
|
message: 'Default namespace (can be changed later) >',
|
|
90
93
|
default: 'default',
|
|
@@ -115,6 +118,7 @@ class Create extends command_1.Command {
|
|
|
115
118
|
(0, child_process_1.execSync)('npm install sandstone', { cwd: projectPath });
|
|
116
119
|
(0, child_process_1.execSync)('npm install --save-dev typescript @types/node sandstone-cli', { cwd: projectPath });
|
|
117
120
|
}
|
|
121
|
+
// TODO: Make profiles for either packs or libraries
|
|
118
122
|
// Merge with the package.json template
|
|
119
123
|
const generatedPackage = JSON.parse(fs_1.default.readFileSync(path_1.default.join(projectPath, 'package.json')).toString());
|
|
120
124
|
/** Remove the `main` property */
|
|
@@ -128,9 +132,13 @@ class Create extends command_1.Command {
|
|
|
128
132
|
fs_1.default.writeFileSync(path_1.default.join(projectPath, 'sandstone.config.ts'), `import type { SandstoneConfig } from 'sandstone'
|
|
129
133
|
|
|
130
134
|
export default {
|
|
131
|
-
name: ${toJson(
|
|
132
|
-
|
|
133
|
-
|
|
135
|
+
name: ${toJson(packName)},
|
|
136
|
+
packs: {
|
|
137
|
+
datapack: {
|
|
138
|
+
description: ${toJson(['A ', { text: 'Sandstone', color: 'gold' }, ' data pack.'])},
|
|
139
|
+
packFormat: ${11},
|
|
140
|
+
}
|
|
141
|
+
},
|
|
134
142
|
namespace: ${toJson(namespace)},
|
|
135
143
|
packUid: ${toJson((0, nanoid_1.nanoid)(8))},
|
|
136
144
|
saveOptions: ${toJson(Object.fromEntries(Object.entries(saveOptions).filter(([_, value]) => value !== undefined)))},
|
|
@@ -151,17 +159,18 @@ export default {
|
|
|
151
159
|
exports.default = Create;
|
|
152
160
|
Create.description = 'Create a new Sandstone project.';
|
|
153
161
|
Create.examples = [
|
|
154
|
-
'$ sand create my-
|
|
162
|
+
'$ sand create my-pack',
|
|
155
163
|
];
|
|
156
164
|
Create.flags = {
|
|
157
165
|
help: command_1.flags.help({ char: 'h' }),
|
|
158
166
|
yarn: command_1.flags.boolean({ description: 'Use yarn instead of npm.', env: 'USE_YARN', exclusive: ['npm'] }),
|
|
159
167
|
npm: command_1.flags.boolean({ description: 'Use npm.', env: 'USE_NPM', exclusive: ['yarn'] }),
|
|
160
|
-
'
|
|
168
|
+
'pack-name': command_1.flags.string({ char: 'd', env: 'PACK_NAME', description: 'The name of the data pack.' }),
|
|
161
169
|
namespace: command_1.flags.string({ char: 'n', env: 'NAMESPACE', description: 'The default namespace that will be used.' }),
|
|
162
|
-
'save-root': command_1.flags.boolean({ char: 'r', env: 'SAVE_ROOT', description: 'Save the data pack in the .minecraft/datapacks
|
|
163
|
-
world: command_1.flags.string({ char: 'w', env: 'WORLD', description: 'The world to save the
|
|
164
|
-
'
|
|
170
|
+
'save-root': command_1.flags.boolean({ char: 'r', env: 'SAVE_ROOT', description: 'Save the data pack & resource pack in the .minecraft/datapacks & .minecraft/resource_packs folders. Not compatible with --world.', exclusive: ['world'] }),
|
|
171
|
+
world: command_1.flags.string({ char: 'w', env: 'WORLD', description: 'The world to save the packs in. Not compatible with --save-root or --server', exclusive: ['save-root', 'server'] }),
|
|
172
|
+
'server-path': command_1.flags.string({ char: 's', env: 'SERVER_PATH', description: 'The server path to write the server-side packs at. Not compatible with --world.', exclusive: ['world'] }),
|
|
173
|
+
'client-path': command_1.flags.string({ char: 'c', env: 'CLIENT_PATH', description: 'The client path to write packs at.' }),
|
|
165
174
|
};
|
|
166
175
|
Create.args = [{
|
|
167
176
|
name: 'project-name',
|
package/lib/commands/watch.d.ts
CHANGED
|
@@ -9,8 +9,8 @@ export default class Watch extends Command {
|
|
|
9
9
|
namespace: flags.IOptionFlag<string | undefined>;
|
|
10
10
|
world: flags.IOptionFlag<string | undefined>;
|
|
11
11
|
root: import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
clientPath: flags.IOptionFlag<string | undefined>;
|
|
13
|
+
serverPath: flags.IOptionFlag<string | undefined>;
|
|
14
14
|
name: flags.IOptionFlag<string | undefined>;
|
|
15
15
|
description: flags.IOptionFlag<string | undefined>;
|
|
16
16
|
formatVersion: import("@oclif/parser/lib/flags").IOptionFlag<number | undefined>;
|
package/lib/commands/watch.js
CHANGED
|
@@ -15,6 +15,7 @@ class Watch extends command_1.Command {
|
|
|
15
15
|
let alreadyBuilding = false;
|
|
16
16
|
let needRebuild = false;
|
|
17
17
|
let client = null;
|
|
18
|
+
// TODO: add support for clients & resources that require restarts & world resets, sandstone-server should override the involved environment variables if mods are present that fix it
|
|
18
19
|
if (flags.autoReload !== undefined) {
|
|
19
20
|
try {
|
|
20
21
|
client = (await require('minecraft-protocol')).createClient({
|
|
@@ -36,7 +37,7 @@ class Watch extends command_1.Command {
|
|
|
36
37
|
return;
|
|
37
38
|
}
|
|
38
39
|
alreadyBuilding = true;
|
|
39
|
-
await (0, buildProject_1.buildProject)(flags, folders, paths);
|
|
40
|
+
await (0, buildProject_1.buildProject)(flags, folders, utils_1.datapackResources, paths);
|
|
40
41
|
client === null || client === void 0 ? void 0 : client.write('chat', { message: '/reload' });
|
|
41
42
|
alreadyBuilding = false;
|
|
42
43
|
if (needRebuild) {
|
|
@@ -72,7 +73,7 @@ class Watch extends command_1.Command {
|
|
|
72
73
|
}
|
|
73
74
|
}
|
|
74
75
|
exports.default = Watch;
|
|
75
|
-
Watch.description = 'Build the
|
|
76
|
+
Watch.description = 'Build the packs, and rebuild them on file change. ⛏';
|
|
76
77
|
Watch.examples = [
|
|
77
78
|
'$ sand watch',
|
|
78
79
|
'$ sand watch --verbose',
|
|
@@ -80,13 +81,14 @@ Watch.examples = [
|
|
|
80
81
|
];
|
|
81
82
|
Watch.flags = {
|
|
82
83
|
help: command_1.flags.help({ char: 'h' }),
|
|
83
|
-
dry: command_1.flags.boolean({ char: 'd', description: 'Do not save the
|
|
84
|
+
dry: command_1.flags.boolean({ char: 'd', description: 'Do not save the pack. Mostly useful with `verbose`.' }),
|
|
84
85
|
verbose: command_1.flags.boolean({ char: 'v', description: 'Log all resulting resources: functions, advancements...' }),
|
|
85
86
|
namespace: command_1.flags.string({ description: 'The default namespace. Override the value specified in the configuration file.' }),
|
|
86
87
|
world: command_1.flags.string({ description: 'The world to save the data pack in. Override the value specified in the configuration file.' }),
|
|
87
|
-
root: command_1.flags.boolean({ description: 'Save the data pack in the
|
|
88
|
-
|
|
89
|
-
|
|
88
|
+
root: command_1.flags.boolean({ description: 'Save the data pack & resource pack in the .minecraft/datapacks & .minecraft/resource_packs folders. Override the value specified in the configuration file.' }),
|
|
89
|
+
clientPath: command_1.flags.string({ name: 'client-path', description: 'Path of the client folder. Override the value specified in the configuration file.' }),
|
|
90
|
+
serverPath: command_1.flags.string({ name: 'server-path', description: 'Path of the server folder. Override the value specified in the configuration file.' }),
|
|
91
|
+
// TODO: ssh
|
|
90
92
|
name: command_1.flags.string({ description: 'Name of the data pack. Override the value specified in the configuration file.' }),
|
|
91
93
|
description: command_1.flags.string({ description: 'Description of the data pack. Override the value specified in the configuration file.' }),
|
|
92
94
|
formatVersion: command_1.flags.integer({ name: 'format', description: 'Pack format version. Override the value specified in the configuration file.' }),
|
package/lib/template/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Sandstone project
|
|
2
2
|
|
|
3
|
-
To build the
|
|
3
|
+
To build the packs, run:
|
|
4
4
|
```ts
|
|
5
5
|
npm run build
|
|
6
6
|
// or
|
|
@@ -9,7 +9,7 @@ yarn build
|
|
|
9
9
|
sand build
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
-
To automatically rebuild the
|
|
12
|
+
To automatically rebuild the packs on each change, run:
|
|
13
13
|
```ts
|
|
14
14
|
npm run watch
|
|
15
15
|
// or
|
package/lib/utils.d.ts
CHANGED
package/lib/utils.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.getProjectFolders = exports.getFileFolder = exports.getWorldPath = exports.getWorldsList = exports.getMinecraftPath = exports.hasYarn = exports.getFlagOrPrompt = void 0;
|
|
6
|
+
exports.datapackResources = exports.getProjectFolders = exports.getFileFolder = exports.getWorldPath = exports.getWorldsList = exports.getMinecraftPath = exports.hasYarn = exports.getFlagOrPrompt = void 0;
|
|
7
7
|
const inquirer_1 = __importDefault(require("inquirer"));
|
|
8
8
|
const fs_1 = __importDefault(require("fs"));
|
|
9
9
|
const os_1 = __importDefault(require("os"));
|
|
@@ -119,3 +119,4 @@ function getProjectFolders(projectFolder) {
|
|
|
119
119
|
};
|
|
120
120
|
}
|
|
121
121
|
exports.getProjectFolders = getProjectFolders;
|
|
122
|
+
exports.datapackResources = ['mcfunction', 'advancement', 'item_modifier', 'loot_table', 'predicate', 'recipe', 'tag', 'trim_material', 'trim_pattern'];
|
package/oclif.manifest.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"0.6.
|
|
1
|
+
{"version":"0.6.1","commands":{"build":{"id":"build","description":"Build the packs. ⛏","pluginName":"sandstone-cli","pluginType":"core","aliases":[],"examples":["$ sand build","$ sand build --verbose","$ sand build --verbose --dry"],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"dry":{"name":"dry","type":"boolean","char":"d","description":"Do not save the pack. Mostly useful with `verbose`.","allowNo":false},"verbose":{"name":"verbose","type":"boolean","char":"v","description":"Log all resulting resources: functions, advancements...","allowNo":false},"namespace":{"name":"namespace","type":"option","description":"The default namespace. Override the value specified in the configuration file."},"world":{"name":"world","type":"option","description":"The world to save the data pack in. Override the value specified in the configuration file."},"root":{"name":"root","type":"boolean","description":"Save the data pack & resource pack in the .minecraft/datapacks & .minecraft/resource_packs folders. Override the value specified in the configuration file.","allowNo":false},"clientPath":{"name":"clientPath","type":"option","description":"Path of the client folder. Override the value specified in the configuration file."},"serverPath":{"name":"serverPath","type":"option","description":"Path of the server folder. Override the value specified in the configuration file."},"name":{"name":"name","type":"option","description":"Name of the data pack. Override the value specified in the configuration file."},"description":{"name":"description","type":"option","description":"Description of the data pack. Override the value specified in the configuration file."},"formatVersion":{"name":"formatVersion","type":"option","description":"Pack format version. Override the value specified in the configuration file."},"fullTrace":{"name":"fullTrace","type":"boolean","description":"Show the full stack trace on errors.","allowNo":false},"strictErrors":{"name":"strictErrors","type":"boolean","description":"Stop data pack compilation on type errors.","allowNo":false},"production":{"name":"production","type":"boolean","char":"p","description":"Runs Sandstone in production mode. This sets process.env.SANDSTONE_ENV to \"production\".","allowNo":false},"autoReload":{"name":"autoReload","type":"option","description":"Automatically reload your data pack in-game. Requires to open the world to LAN with cheats enabled, and to specify the port.","helpValue":"port"}},"args":[{"name":"path","description":"Path of the folder containing source files.","required":true,"default":"./src"},{"name":"config-path","description":"Path of the sandstone.config.ts folder.","required":true,"default":"."}]},"create":{"id":"create","description":"Create a new Sandstone project.","pluginName":"sandstone-cli","pluginType":"core","aliases":[],"examples":["$ sand create my-pack"],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"yarn":{"name":"yarn","type":"boolean","description":"Use yarn instead of npm.","allowNo":false},"npm":{"name":"npm","type":"boolean","description":"Use npm.","allowNo":false},"pack-name":{"name":"pack-name","type":"option","char":"d","description":"The name of the data pack."},"namespace":{"name":"namespace","type":"option","char":"n","description":"The default namespace that will be used."},"save-root":{"name":"save-root","type":"boolean","char":"r","description":"Save the data pack & resource pack in the .minecraft/datapacks & .minecraft/resource_packs folders. Not compatible with --world.","allowNo":false},"world":{"name":"world","type":"option","char":"w","description":"The world to save the packs in. Not compatible with --save-root or --server"},"server-path":{"name":"server-path","type":"option","char":"s","description":"The server path to write the server-side packs at. Not compatible with --world."},"client-path":{"name":"client-path","type":"option","char":"c","description":"The client path to write packs at."}},"args":[{"name":"project-name","description":"Name of the project folder. This is not the name of the data pack.","required":true}]},"update":{"id":"update","description":"Update Sandstone & Sandstone-CLI.","pluginName":"sandstone-cli","pluginType":"core","aliases":[],"examples":["$ sand update","$ sand update --cli","$ sand update --sandstone","$ sand update --cli --sandstone --skip"],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"cli":{"name":"cli","type":"boolean","description":"Update the Sandstone CLI without asking.","allowNo":false},"sandstone":{"name":"sandstone","type":"boolean","description":"Update the current Sandstone version without asking.","allowNo":false},"skip":{"name":"skip","type":"boolean","description":"Skip all interactive prompts and refuse them.","allowNo":false},"yarn":{"name":"yarn","type":"boolean","description":"Use yarn to install the updates.","allowNo":false},"npm":{"name":"npm","type":"boolean","description":"Use npm to install the updates.","allowNo":false}},"args":[]},"watch":{"id":"watch","description":"Build the packs, and rebuild them on file change. ⛏","pluginName":"sandstone-cli","pluginType":"core","aliases":[],"examples":["$ sand watch","$ sand watch --verbose","$ sand watch --verbose --dry"],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"dry":{"name":"dry","type":"boolean","char":"d","description":"Do not save the pack. Mostly useful with `verbose`.","allowNo":false},"verbose":{"name":"verbose","type":"boolean","char":"v","description":"Log all resulting resources: functions, advancements...","allowNo":false},"namespace":{"name":"namespace","type":"option","description":"The default namespace. Override the value specified in the configuration file."},"world":{"name":"world","type":"option","description":"The world to save the data pack in. Override the value specified in the configuration file."},"root":{"name":"root","type":"boolean","description":"Save the data pack & resource pack in the .minecraft/datapacks & .minecraft/resource_packs folders. Override the value specified in the configuration file.","allowNo":false},"clientPath":{"name":"clientPath","type":"option","description":"Path of the client folder. Override the value specified in the configuration file."},"serverPath":{"name":"serverPath","type":"option","description":"Path of the server folder. Override the value specified in the configuration file."},"name":{"name":"name","type":"option","description":"Name of the data pack. Override the value specified in the configuration file."},"description":{"name":"description","type":"option","description":"Description of the data pack. Override the value specified in the configuration file."},"formatVersion":{"name":"formatVersion","type":"option","description":"Pack format version. Override the value specified in the configuration file."},"fullTrace":{"name":"fullTrace","type":"boolean","description":"Show the full stack trace on errors.","allowNo":false},"strictErrors":{"name":"strictErrors","type":"boolean","description":"Stop data pack compilation on type errors.","allowNo":false},"production":{"name":"production","type":"boolean","char":"p","description":"Runs Sandstone in production mode. This sets process.env.SANDSTONE_ENV to \"production\".","allowNo":false},"autoReload":{"name":"autoReload","type":"option","description":"Automatically reload your data pack in-game. Requires to open the world to LAN with cheats enabled, and to specify the port.","helpValue":"port"}},"args":[{"name":"path","description":"Path of the folder containing source files.","required":true,"default":"./src"},{"name":"config-path","description":"Path of the sandstone.config.ts folder.","required":true,"default":"."}]}}}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sandstone-cli",
|
|
3
3
|
"description": "The CLI for Sandstone - the data pack creation library.",
|
|
4
|
-
"version": "0.6.
|
|
4
|
+
"version": "0.6.1",
|
|
5
5
|
"contributors": [
|
|
6
6
|
{
|
|
7
7
|
"name": "TheMrZZ - Florian ERNST",
|
|
@@ -22,8 +22,10 @@
|
|
|
22
22
|
"@oclif/config": "^1",
|
|
23
23
|
"@oclif/plugin-help": "^3",
|
|
24
24
|
"@oclif/plugin-warn-if-update-available": "^1.7.0",
|
|
25
|
+
"@types/adm-zip": "^0.5.0",
|
|
25
26
|
"@types/node": "^18.11.18",
|
|
26
27
|
"@types/semver": "^7.3.4",
|
|
28
|
+
"adm-zip": "^0.5.10",
|
|
27
29
|
"chalk": "^4.1.0",
|
|
28
30
|
"chokidar": "^3.4.3",
|
|
29
31
|
"fs-extra": "^9.0.1",
|
|
@@ -42,7 +44,7 @@
|
|
|
42
44
|
"@oclif/dev-cli": "^1",
|
|
43
45
|
"@types/fs-extra": "^9.0.4",
|
|
44
46
|
"@types/inquirer": "^7.3.1",
|
|
45
|
-
"@types/klaw": "^3.0.
|
|
47
|
+
"@types/klaw": "^3.0.3",
|
|
46
48
|
"@types/lodash.debounce": "^4.0.6",
|
|
47
49
|
"@types/madge": "^5.0.0",
|
|
48
50
|
"@types/nodemon": "^1.19.0",
|