Skip to content

Commit

Permalink
require user to specify the Neon project type:
Browse files Browse the repository at this point in the history
- either by passing --app or --lib
- or by interactive dialog via stdin
  • Loading branch information
dherman committed May 12, 2024
1 parent c4a8e9b commit 7661e45
Show file tree
Hide file tree
Showing 9 changed files with 394 additions and 116 deletions.
17 changes: 2 additions & 15 deletions pkgs/create-neon/dev/expect.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,7 @@
import { ChildProcess } from "child_process";
import { PassThrough, Readable, Writable } from "stream";
import { StringDecoder } from "string_decoder";
import { Readable, Writable } from "stream";
import readStream from "stream-to-string";

function readChunks(input: Readable): Readable {
let output = new PassThrough({ objectMode: true });
let decoder = new StringDecoder("utf8");
input.on("data", (data) => {
output.write(decoder.write(data));
});
input.on("close", () => {
output.write(decoder.end());
output.end();
});
return output;
}
import { readChunks } from "../src/shell.js";

function splitLines(s: string): string[] {
return s.split(/([^\n]*\r?\n)/).filter((x) => x);
Expand Down
1 change: 1 addition & 0 deletions pkgs/create-neon/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"prepublishOnly": "npm run build",
"pretest": "npm run build",
"test": "mocha",
"manual-interactive-test": "npm run build && rm -rf create-neon-manual-test-project && node ./dist/src/bin/create-neon.js create-neon-manual-test-project",
"manual-test": "npm run build && rm -rf create-neon-manual-test-project && node ./dist/src/bin/create-neon.js --lib --yes create-neon-manual-test-project"
},
"repository": {
Expand Down
40 changes: 26 additions & 14 deletions pkgs/create-neon/src/bin/create-neon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ import { CI } from "../ci.js";
import { GitHub } from "../ci/github.js";
import { Lang, ModuleType } from "../package.js";
import {
NodePlatform,
PlatformPreset,
assertIsPlatformPreset,
isNodePlatform,
isPlatformPreset,
} from "@neon-rs/manifest/platform";

Expand All @@ -33,6 +35,7 @@ function tsTemplates(pkg: string): Record<string, string> {
}

const OPTIONS = [
{ name: "app", type: Boolean, defaultValue: false },
{ name: "lib", type: Boolean, defaultValue: false },
{ name: "bins", type: String, defaultValue: "none" },
{ name: "platform", type: String, multiple: true, defaultValue: ["common"] },
Expand All @@ -43,6 +46,10 @@ const OPTIONS = [
try {
const opts = commandLineArgs(OPTIONS, { stopAtFirstUnknown: true });

if (opts.app && opts.lib) {
throw new Error("Cannot choose both --app and --lib");
}

if (!opts._unknown || opts._unknown.length === 0) {
throw new Error("No package name given");
}
Expand All @@ -55,7 +62,10 @@ try {
const platforms = parsePlatforms(opts.platform);
const cache = parseCache(opts.lib, opts.bins, pkg);
const ci = parseCI(opts.ci);
const yes = !!opts.yes;

if (opts.yes) {
process.env['npm_configure_yes'] = 'true';
}

createNeon(pkg, {
templates: opts.lib ? tsTemplates(pkg) : JS_TEMPLATES,
Expand All @@ -68,7 +78,7 @@ try {
platforms,
}
: null,
yes,
app: opts.app ? true : null
});
} catch (e) {
printErrorWithUsage(e);
Expand All @@ -77,17 +87,21 @@ try {

function parsePlatforms(
platforms: string[]
): PlatformPreset | PlatformPreset[] | undefined {
): NodePlatform | PlatformPreset | (NodePlatform | PlatformPreset)[] | undefined {
if (platforms.length === 0) {
return undefined;
} else if (platforms.length === 1) {
const preset = platforms[0];
assertIsPlatformPreset(preset);
return preset;
const platform = platforms[0];
if (isNodePlatform(platform) || isPlatformPreset(platform)) {
return platform;
}
throw new TypeError(`expected platform or preset, got ${platform}`);
} else {
return platforms.map((preset) => {
assertIsPlatformPreset(preset);
return preset;
return platforms.map((platform) => {
if (isNodePlatform(platform) || isPlatformPreset(platform)) {
return platform;
}
throw new TypeError(`expected platform or preset, got ${platform}`);
});
}
}
Expand All @@ -110,18 +124,16 @@ function parseCache(
bins: string,
pkg: string
): Cache | undefined {
const defaultOrg = "@" + pkg;

if (bins === "none") {
return lib ? new NPM(defaultOrg) : undefined;
return lib ? new NPM(pkg) : undefined;
}

if (bins === "npm") {
return new NPM(defaultOrg);
return new NPM(pkg);
}

if (bins.startsWith("npm:")) {
return new NPM(bins.substring(4));
return new NPM(pkg, bins.substring(4));
}

throw new Error(
Expand Down
11 changes: 8 additions & 3 deletions pkgs/create-neon/src/cache/npm.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import { Cache } from "../cache.js";

export class NPM implements Cache {
readonly org: string | null;
readonly org: string;

readonly type: string = "npm";

constructor(org: string | null) {
this.org = org;
constructor(pkg: string, org?: string) {
this.org = org || NPM.inferOrg(pkg);
}

static inferOrg(pkg: string): string {
const m = pkg.match(/^@([^/]+)\/([^/]+)/);
return "@" + (m ? m[1] : pkg);
}
}
28 changes: 28 additions & 0 deletions pkgs/create-neon/src/fs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import * as fs from 'node:fs/promises';
import * as path from 'node:path';
import { existsSync, rmSync } from 'node:fs';

export async function assertCanMkdir(dir: string) {
// pretty lightweight way to check both that folder doesn't exist and
// that the user has write permissions.
await fs.mkdir(dir);
await fs.rmdir(dir);
}

export async function mktemp(): Promise<string> {
const tmpFolderName = await fs.mkdtemp("neon-");
const tmpFolderAbsPath = path.join(process.cwd(), tmpFolderName);
function cleanupTmp() {
try {
if (existsSync(tmpFolderAbsPath)) {
rmSync(tmpFolderAbsPath, { recursive: true });
}
} catch (e) {
console.error(`warning: could not delete ${tmpFolderName}: ${e}`);
}
}
process.on('exit', cleanupTmp);
process.on('SIGINT', cleanupTmp);
process.on('uncaughtException', cleanupTmp);
return tmpFolderName;
}
Loading

0 comments on commit 7661e45

Please sign in to comment.