@flare-desktop/cli 0.1.2 → 0.1.3
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/package.json +1 -1
- package/src/assets/flare-mark.png +0 -0
- package/src/commands/dev.js +9 -3
- package/src/commands/init.js +16 -1
- package/src/lib/build.js +24 -1
- package/src/lib/cmake.js +17 -4
- package/src/lib/icons.js +7 -17
- package/src/templates/project.js +3 -0
package/package.json
CHANGED
|
Binary file
|
package/src/commands/dev.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { setTimeout as delay } from "node:timers/promises";
|
|
2
2
|
|
|
3
|
-
import { compileApplication, runHook } from "../lib/build.js";
|
|
3
|
+
import { compileApplication, ensureFrontendDirectory, runHook } from "../lib/build.js";
|
|
4
4
|
import { FlareError } from "../lib/errors.js";
|
|
5
5
|
import { loadProject, productName } from "../lib/project.js";
|
|
6
6
|
import { run, startShell, terminate } from "../lib/process.js";
|
|
@@ -48,6 +48,12 @@ export async function devCommand(context) {
|
|
|
48
48
|
process.once("SIGTERM", sigtermHandler);
|
|
49
49
|
|
|
50
50
|
try {
|
|
51
|
+
await ensureFrontendDirectory({
|
|
52
|
+
projectDirectory: context.projectDirectory,
|
|
53
|
+
config,
|
|
54
|
+
logger: context.logger
|
|
55
|
+
});
|
|
56
|
+
|
|
51
57
|
if (config.build.beforeDevCommand) {
|
|
52
58
|
context.logger.info(`before dev command: ${config.build.beforeDevCommand}`);
|
|
53
59
|
server = startShell(config.build.beforeDevCommand, { cwd: context.projectDirectory });
|
|
@@ -61,8 +67,8 @@ export async function devCommand(context) {
|
|
|
61
67
|
const { binary } = await compileApplication({
|
|
62
68
|
projectDirectory: context.projectDirectory,
|
|
63
69
|
config,
|
|
64
|
-
|
|
65
|
-
|
|
70
|
+
configFile: context.flags.config || "flare.config.json",
|
|
71
|
+
environment: context.flags.environment,
|
|
66
72
|
mode: "Debug",
|
|
67
73
|
logger: context.logger
|
|
68
74
|
});
|
package/src/commands/init.js
CHANGED
|
@@ -6,6 +6,7 @@ import { placeholderIcon } from "../lib/icons.js";
|
|
|
6
6
|
import { isValidAppName, toKebabCase } from "../lib/project.js";
|
|
7
7
|
import { installSdk } from "../lib/sdk.js";
|
|
8
8
|
import { writePng } from "../lib/png.js";
|
|
9
|
+
import { runShell } from "../lib/process.js";
|
|
9
10
|
import { CORE_VERSION, MIN_CLI_VERSION } from "../release-versions.js";
|
|
10
11
|
import {
|
|
11
12
|
cmakeTemplate,
|
|
@@ -36,6 +37,7 @@ export async function initProject({
|
|
|
36
37
|
template = "javascript",
|
|
37
38
|
sdkMode = "source",
|
|
38
39
|
sdkFetch,
|
|
40
|
+
installDependencies = false,
|
|
39
41
|
force = false,
|
|
40
42
|
logger
|
|
41
43
|
}) {
|
|
@@ -121,12 +123,25 @@ export async function initProject({
|
|
|
121
123
|
|
|
122
124
|
const written = [...files.map((entry) => entry.file), "icons/icon.png", "icons/32x32.png"];
|
|
123
125
|
|
|
126
|
+
if (installDependencies) {
|
|
127
|
+
if (logger) logger.info("installing project dependencies with npm");
|
|
128
|
+
let result;
|
|
129
|
+
try {
|
|
130
|
+
result = await runShell("npm install --no-audit --no-fund", { cwd: targetDirectory });
|
|
131
|
+
} catch (error) {
|
|
132
|
+
throw new FlareError(`npm install could not start in '${targetDirectory}': ${error.message}; run npm install manually`);
|
|
133
|
+
}
|
|
134
|
+
if (result.code !== 0) {
|
|
135
|
+
throw new FlareError(`npm install failed in '${targetDirectory}' (code ${result.code}); the project was kept, run npm install manually`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
124
139
|
if (logger) {
|
|
125
140
|
logger.info(`created project '${projectName}' in '${targetDirectory}'`);
|
|
126
141
|
logger.info("");
|
|
127
142
|
logger.info("next steps:");
|
|
128
143
|
logger.step(`cd ${path.relative(process.cwd(), targetDirectory) || "."}`);
|
|
129
|
-
logger.step("npm install");
|
|
144
|
+
if (!installDependencies) logger.step("npm install");
|
|
130
145
|
logger.step("npm run dev");
|
|
131
146
|
}
|
|
132
147
|
|
package/src/lib/build.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
|
|
1
3
|
import { buildDirectory, buildProject, configureProject, findExecutable } from "./cmake.js";
|
|
2
4
|
import { FlareError } from "./errors.js";
|
|
3
5
|
import { binaryName, frontendDirectory } from "./project.js";
|
|
@@ -10,14 +12,35 @@ export async function runHook(command, { cwd, env, logger, label }) {
|
|
|
10
12
|
if (result.code !== 0) throw new FlareError(`${label} failed with code ${result.code}`);
|
|
11
13
|
}
|
|
12
14
|
|
|
15
|
+
export async function ensureFrontendDirectory({ projectDirectory, config, logger }) {
|
|
16
|
+
const frontend = frontendDirectory(projectDirectory, config);
|
|
17
|
+
if (existsSync(frontend)) return;
|
|
18
|
+
if (!config.build.beforeBuildCommand) {
|
|
19
|
+
throw new FlareError(`frontend directory '${frontend}' is missing and no beforeBuildCommand is configured`);
|
|
20
|
+
}
|
|
21
|
+
logger.info("preparing frontend assets for CMake embedding");
|
|
22
|
+
await runHook(config.build.beforeBuildCommand, {
|
|
23
|
+
cwd: projectDirectory,
|
|
24
|
+
logger,
|
|
25
|
+
label: "frontend build command"
|
|
26
|
+
});
|
|
27
|
+
if (!existsSync(frontend)) {
|
|
28
|
+
throw new FlareError(`frontend build command did not create '${frontend}'`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
13
32
|
export async function compileApplication({ projectDirectory, config, mode, env, logger, configFile, environment }) {
|
|
33
|
+
const frontend = frontendDirectory(projectDirectory, config);
|
|
34
|
+
if (!existsSync(frontend)) {
|
|
35
|
+
throw new FlareError(`frontend directory '${frontend}' is missing; run the frontend build command before compiling`);
|
|
36
|
+
}
|
|
14
37
|
const directory = buildDirectory(projectDirectory, mode);
|
|
15
38
|
await configureProject(projectDirectory, {
|
|
16
39
|
directory,
|
|
17
40
|
mode,
|
|
18
41
|
env,
|
|
19
42
|
logger,
|
|
20
|
-
frontendDirectory:
|
|
43
|
+
frontendDirectory: frontend,
|
|
21
44
|
configFile,
|
|
22
45
|
environment
|
|
23
46
|
});
|
package/src/lib/cmake.js
CHANGED
|
@@ -35,24 +35,37 @@ export function buildDirectory(projectDirectory, mode) {
|
|
|
35
35
|
return path.join(projectDirectory, "build", mode === "Debug" ? "debug" : "release");
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
export function msvcUtf8Arguments(directory, { platform = process.platform, cxxFlags = process.env.CXXFLAGS ?? "" } = {}) {
|
|
39
|
+
if (platform !== "win32") return [];
|
|
40
|
+
const cacheFile = path.join(directory, "CMakeCache.txt");
|
|
41
|
+
const cache = existsSync(cacheFile) ? readFileSync(cacheFile, "utf8") : "";
|
|
42
|
+
const existing = cache.match(/^CMAKE_CXX_FLAGS:STRING=(.*)$/m)?.[1] ?? cxxFlags;
|
|
43
|
+
if (/(?:^|\s)\/utf-8(?:\s|$)/i.test(existing)) return [];
|
|
44
|
+
return [`-DCMAKE_CXX_FLAGS:STRING=${[existing.trim(), "/utf-8"].filter(Boolean).join(" ")}`];
|
|
45
|
+
}
|
|
46
|
+
|
|
38
47
|
export async function configureProject(projectDirectory, { directory, mode, env, logger, frontendDirectory, configFile = "flare.config.json", environment = "production" }) {
|
|
39
48
|
if (!cmakeVersion()) throw new FlareError("cmake was not found in PATH");
|
|
40
49
|
const outputDirectory = path.join(directory, "bin");
|
|
41
50
|
const configuration = mode.toUpperCase();
|
|
51
|
+
const generator = process.env.CMAKE_GENERATOR ?? "";
|
|
52
|
+
const multiConfiguration = generator
|
|
53
|
+
? /^(Visual Studio|Xcode|Ninja Multi-Config)/.test(generator)
|
|
54
|
+
: process.platform === "win32";
|
|
55
|
+
const prebuiltSdk = existsSync(path.join(projectDirectory, "vendor", "flare", "sdk-manifest.json"));
|
|
42
56
|
const args = [
|
|
43
57
|
"-S",
|
|
44
58
|
projectDirectory,
|
|
45
59
|
"-B",
|
|
46
60
|
directory,
|
|
47
61
|
...generatorArguments(),
|
|
48
|
-
`-DCMAKE_BUILD_TYPE=${mode}
|
|
62
|
+
...(!multiConfiguration ? [`-DCMAKE_BUILD_TYPE=${mode}`] : []),
|
|
49
63
|
`-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=${outputDirectory}`,
|
|
50
64
|
`-DCMAKE_RUNTIME_OUTPUT_DIRECTORY_${configuration}=${outputDirectory}`,
|
|
51
65
|
"-DCMAKE_EXPORT_COMPILE_COMMANDS=ON",
|
|
52
66
|
`-DFLARE_FRONTEND_DIR=${frontendDirectory ?? path.join(projectDirectory, "frontend")}`,
|
|
53
|
-
"-DFLARE_BUILD_EXAMPLES=OFF",
|
|
54
|
-
"
|
|
55
|
-
"-DFLARE_INSTALL=OFF"
|
|
67
|
+
...(!prebuiltSdk ? ["-DFLARE_BUILD_EXAMPLES=OFF", "-DFLARE_BUILD_TESTS=OFF", "-DFLARE_INSTALL=OFF"] : []),
|
|
68
|
+
...msvcUtf8Arguments(directory, { cxxFlags: env?.CXXFLAGS ?? process.env.CXXFLAGS ?? "" })
|
|
56
69
|
];
|
|
57
70
|
logger.debug(`cmake ${args.join(" ")}`);
|
|
58
71
|
const result = await run("cmake", args, { cwd: projectDirectory, env });
|
package/src/lib/icons.js
CHANGED
|
@@ -1,23 +1,13 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
|
|
1
3
|
import { FlareError } from "./errors.js";
|
|
2
|
-
import { resizePng, writePng } from "./png.js";
|
|
4
|
+
import { readPng, resizePng, writePng } from "./png.js";
|
|
5
|
+
|
|
6
|
+
let defaultMark;
|
|
3
7
|
|
|
4
8
|
export function placeholderIcon(size = 512) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const radius = size * 0.46;
|
|
8
|
-
for (let y = 0; y < size; y += 1) {
|
|
9
|
-
for (let x = 0; x < size; x += 1) {
|
|
10
|
-
const target = (y * size + x) * 4;
|
|
11
|
-
const distance = Math.hypot(x - center, y - center) / radius;
|
|
12
|
-
const glow = Math.max(0, Math.min(1, 1 - Math.abs(distance - 0.55) * 1.6));
|
|
13
|
-
const edge = distance <= 1 ? 1 : 0;
|
|
14
|
-
data[target] = edge ? Math.round(44 + 172 * glow) : 0;
|
|
15
|
-
data[target + 1] = edge ? Math.round(35 + 132 * glow) : 0;
|
|
16
|
-
data[target + 2] = edge ? Math.round(40 + 137 * glow) : 0;
|
|
17
|
-
data[target + 3] = edge ? 255 : 0;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
return { width: size, height: size, data };
|
|
9
|
+
defaultMark ??= readPng(readFileSync(new URL("../assets/flare-mark.png", import.meta.url)));
|
|
10
|
+
return resizePng(defaultMark, size, size);
|
|
21
11
|
}
|
|
22
12
|
|
|
23
13
|
const ICO_SIZES = [16, 24, 32, 48, 64, 128, 256];
|
package/src/templates/project.js
CHANGED
|
@@ -94,6 +94,9 @@ FetchContent_MakeAvailable(flare)`}
|
|
|
94
94
|
|
|
95
95
|
add_executable(${name} source/main.cpp)
|
|
96
96
|
target_link_libraries(${name} PRIVATE flare::core flare::assets)
|
|
97
|
+
if(MSVC)
|
|
98
|
+
target_compile_options(${name} PRIVATE /utf-8)
|
|
99
|
+
endif()
|
|
97
100
|
|
|
98
101
|
find_program(FLARE_NODE_EXECUTABLE node REQUIRED)
|
|
99
102
|
set(FLARE_CONFIG_FILE "flare.config.json" CACHE STRING "Source application configuration")
|