Skip to content

Commit

Permalink
Merge pull request #322 from mitmedialab/issue_321_yargs
Browse files Browse the repository at this point in the history
Introduced yargs
  • Loading branch information
pmalacho-mit authored Dec 22, 2023
2 parents 1f27b09 + a96663f commit b01a58e
Show file tree
Hide file tree
Showing 42 changed files with 99,326 additions and 97,334 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,18 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## 2023-12-22

### Changed
- Using `yargs` npm package to parse command-line options instead of homegrown functionality (no more ugly `only=`)
- Extensions are now bundled / served explicilty (based on the `--include` / `-i` flag) instead of all being included by default
- I.e. `npm run dev` now **REQUIRES** the `--include` / `-i` flag to be provided to indicate which extension(s) to bundle & serve
- e.g. `npm run dev -- --include myAwesomeExtension` or `npm run dev -- -i myAwesomeExtension`
- Based on input / work from @sanjaiyan-dev, now bundle all extensions concurrently
- This was previously avoided, since it could lead to out of memory issues (since `npm run dev` was bundling all extensions by default). Now that extension bundling is more explicit, this is is less of a concern, and extensions are bundled concurrently by default
- Concurrent bundling can be opted-out-of (as is the case for the github action the bundles all extensions) by setting the `--parrallel` / `-p` flag to `false`
- e.g. `npm run dev -- --include all -p false`

## 2023-07-14

### Changed
Expand Down
17 changes: 11 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ npm run init
# This should only need to be ran once (unless you checkout a branch that adds new package dependencies).
# Takes ~1.5 minutes

npm run dev
# This starts up a development server, serving all the currently implemented extensions.
npm run dev -- --include examples
# This starts up a development server, serving the two "example" extensions.
# It takes about ~20s to initially startup and serve everything.
# Open http://localhost:8601/ in your browser (keep refreshing if nothing's coming up)
```
Expand Down Expand Up @@ -84,16 +84,21 @@ After you've [made your extension](#-making-an-extension), run the following com
cd prg-extension-boilerplate/ # If not already there
# Change directory (cd) to prg-extension-boilerplate/

npm run dev only=<folder name of extension>
# For example: npm run dev only=my_awesome_extension
npm run dev -- --include <folder name of extension(s)>
# For example: npm run dev -- --include my_awesome_extension
# Start a development server to view your extension and reload it as you make changes
# This command will take ~20s to startup and serve everything to http://localhost:8601/

# Note: you can use the '-i' shorthand instead of writing out '--include'
npm run dev -- -i <folder name of extension(s)>

# Alternatively, serve all the currently implemented extensions
npm run dev
# NOTE: This will be more intensive on your computer
npm run dev -- --include all
# NOTE: This will be much more intensive on your computer
```

> **_FYI:_** If you're wondering why the extra `--` are necessary in the above commands, it's to ensure that node does not parse the `--include` flag (or any other options following the standalone `--`) as node options, and instead passes those arguments to the appropriate script. [See more.](https://nodejs.org/docs/latest-v8.x/api/cli.html#cli_1)
Then, after navigating to http://localhost:8601/, follow the 'Adding Extensions' guidance in the [official extension documentation](https://en.scratch-wiki.info/wiki/Extension) to add your extension to the workspace.

As long as the development server is running (meaning the `npm run dev` command is still executing), every change you make to the extension file(s) will trigger the page to refresh and your changes will be reflected automagically 🪄.
Expand Down
2 changes: 1 addition & 1 deletion extensions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export default class ExampleExtension extends extension({ name: "Example" }) {
```
- Instead of running the following from the root of the project every time:
```
npm run dev only=myExtension
npm run dev -- --include myExtension
```
- Inspect the `package.json` file to see all augmented scripts.

Expand Down
2 changes: 1 addition & 1 deletion extensions/documentation/src/anatomy/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Below are the files you should always find within an extension's directory:
```
- Instead of running the following from the root of the project every time:
```
npm run dev only=myExtension
npm run dev -- --include myExtension
```
- Inspect the `package.json` file to see all augmented scripts.

Expand Down
34 changes: 15 additions & 19 deletions extensions/scripts/bundle.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,33 @@
import chalk from 'chalk';
import { getAllExtensionDirectories, getExtensionDirectory, watchForExtensionDirectoryAdded } from './utils/fileSystem';
import { extensionGlob, extensionPathIsValid, } from './utils/fileSystem';
import { sendToParent } from '$root/scripts/comms';
import { processOptions } from "$root/scripts/buildOptions";
import options from "$root/scripts/options";
import bundleFramework from "./bundles/framework";
import { bundleExtension } from "./bundles";
import { hackToFilterOutUnhelpfulRollupLogs } from './utils/rollupHelper';

const { watch, specifiedDir, individually } = processOptions({ watch: false });
const specialGlobs = new Map([
["all", "!([.]|commo*)*/"], // all folders EXCEPT ".templates" & "common"
["examples", "*_example/"], // all folders ending with "_example"
]);

const { watch, include, parrallel } = options(process.argv);
const globs = (Array.isArray(include) ? include : [include])
.map(pattern => specialGlobs.has(pattern) ? specialGlobs.get(pattern) : pattern);

hackToFilterOutUnhelpfulRollupLogs();

(async () => {
await bundleFramework(watch);

const soloDirectory = specifiedDir ? getExtensionDirectory(specifiedDir) : undefined;
const extensionDirectories = soloDirectory ? [soloDirectory] : getAllExtensionDirectories();

const { length } = extensionDirectories;
const extensionDirectories = Array.from(new Set((await Promise.all(globs.map(extensionGlob))).flat()));

if (individually) {
for (const dir of extensionDirectories) {
await bundleExtension(dir, length, watch);
}
} else {
extensionDirectories.forEach(dir => bundleExtension(dir, length, watch));
}
for (const dir of extensionDirectories) if (!extensionPathIsValid(dir)) throw new Error(`Invalid extension path: ${dir}`);

if (soloDirectory || !watch) return;
const { length } = extensionDirectories;

watchForExtensionDirectoryAdded(
extensionDirectories,
(path, stats) => bundleExtension(path, extensionDirectories.length + 1, true)
);
if (parrallel) await Promise.all(extensionDirectories.map(dir => bundleExtension(dir, length, watch)));
else for (const dir of extensionDirectories) await bundleExtension(dir, length, watch)
})()
.catch((e: any) => {
console.error(chalk.red(e));
Expand Down
2 changes: 1 addition & 1 deletion extensions/scripts/bundles/plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { FrameworkID, untilCondition, extensionBundleEvent, blockBundleEvent } f
import { type Plugin } from "rollup";
import { appendToRootDetailsFile, populateMenuFileForExtension } from "../extensionsMenu";
import { exportAllFromModule, toNamedDefaultExport } from "../utils/importExport";
import { default as glob } from 'glob';
import { glob } from 'glob';
import { commonDirectory, deleteAllFilesInDir, extensionBundlesDirectory, fileName, generatedMenuDetailsDirectory, getBundleFile, getDirectoryAndFileName, tsToJs } from "../utils/fileSystem";
import { BundleInfo } from ".";
import ts from "typescript";
Expand Down
4 changes: 2 additions & 2 deletions extensions/scripts/factories/customArgument.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import chalk from "chalk";
import path from "path";
import { copyTemplateToDestinationAndIncrementIfExists, processDirectoryArg } from ".";
import { copyTemplateToDestinationAndIncrementIfExists, getDirectoryArg } from ".";

const directory = processDirectoryArg();
const directory = getDirectoryArg();
const destination = copyTemplateToDestinationAndIncrementIfExists(directory, "CustomArgument.svelte");

const name = path.basename(destination).replace(path.extname(destination), "");
Expand Down
15 changes: 7 additions & 8 deletions extensions/scripts/factories/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@ import path from "path";
import assert from "assert";
import fs from "fs";
import chalk from "chalk";
import { processArgs } from "$root/scripts/processArgs";
import { UnionToTuple, ValueOf } from "$common";
import { DirectoryArg, directoryDefault, directoryFlag, getPathToExtension, getPathToTemplate } from ".";

const alreadyExists = (directory: string) => fs.existsSync(getPathToExtension(directory, false));
import { ValueOf } from "$common";
import { getPathToExtension, getPathToTemplate, directoryArg } from ".";
import { parsePositionalArgs } from "$root/scripts/options";

const OperationMap = {
Default: "default",
Expand All @@ -28,11 +26,12 @@ Object.values(templateByOperation)
.map(template => getPathToTemplate(template))
.forEach(filepath => assert(fs.existsSync(filepath)));

const { directory, operation } = processArgs<DirectoryArg & { operation: Operation }>(
{ ...directoryFlag, operation: "op" },
{ ...directoryDefault, operation: OperationMap.Default }
const { directory, operation } = parsePositionalArgs(directoryArg,
["operation", { type: "string", default: OperationMap.Default, choices: operations }]
);

const alreadyExists = (directory: string) => fs.existsSync(getPathToExtension(directory, false));

const error = (msg: string) => { throw new Error(chalk.redBright(msg)) };

if (!directory) error("A directory must be provided in order to create an extension.");
Expand Down
23 changes: 11 additions & 12 deletions extensions/scripts/factories/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import path from "path";
import fs from "fs";
import yargs, { type PositionalOptions, type InferredOptionType, choices } from 'yargs';
import { hideBin } from 'yargs/helpers'
import { extensionsSrc, templatesDirectory } from "scripts/utils/fileSystem";
import chalk from "chalk";
import { processArgs } from "$root/scripts/processArgs";
import { PositionalArg, parsePositionalArgs } from "$root/scripts/options";

export const getPathToTemplate = (name: string) => {
const location = path.join(templatesDirectory, name);
Expand Down Expand Up @@ -50,17 +52,14 @@ export const copyTemplateToDestinationAndIncrementIfExists = (extensionDirectory
return destination;
}

export type DirectoryArg = {
directory: string;
}
export const error = (msg: string) => { throw new Error(chalk.redBright(msg)) };

export const directoryFlag: DirectoryArg = { directory: "dir" };
export const directoryDefault: DirectoryArg = { directory: null };
export const checkPositionalArgs = <T>(argv: T) => { };

export const error = (msg: string) => { throw new Error(chalk.redBright(msg)) };
export const directoryArg = ["directory", {
type: "string",
demandOption: true,
description: "The name of the extension directory"
}] as const satisfies PositionalArg;

export const processDirectoryArg = () => {
const { directory } = processArgs<DirectoryArg>(directoryFlag, directoryDefault);
if (!directory) error("An extension directory must be provided in order to add a ui to an extension.");
return directory;
}
export const getDirectoryArg = () => parsePositionalArgs(directoryArg).directory;
4 changes: 2 additions & 2 deletions extensions/scripts/factories/package.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import fs from "fs";
import chalk from "chalk";
import { processDirectoryArg, copyTemplateToDestination } from ".";
import { copyTemplateToDestination, getDirectoryArg, } from ".";
import { splitOnCapitals } from "$common";

const convertToPackageName = (name: string) =>
Expand All @@ -18,7 +18,7 @@ const fillInPackageDetails = (location: string, name: string) => {
fs.writeFileSync(location, text, { encoding });
}

const directory = processDirectoryArg();
const directory = getDirectoryArg();
const file = copyTemplateToDestination(directory, "package.json");
fillInPackageDetails(file, directory);

Expand Down
4 changes: 2 additions & 2 deletions extensions/scripts/factories/test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import chalk from "chalk";
import { processDirectoryArg, copyTemplateToDestination } from ".";
import { copyTemplateToDestination, getDirectoryArg } from ".";

const directory = processDirectoryArg();
const directory = getDirectoryArg();
const destination = copyTemplateToDestination(directory, "index.test.ts");

const msg = [
Expand Down
4 changes: 2 additions & 2 deletions extensions/scripts/factories/translations.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import chalk from "chalk";
import { processDirectoryArg, copyTemplateToDestination } from ".";
import { copyTemplateToDestination, getDirectoryArg } from ".";

const directory = processDirectoryArg();
const directory = getDirectoryArg();
const destination = copyTemplateToDestination(directory, "translations.ts");

const msg = [
Expand Down
4 changes: 2 additions & 2 deletions extensions/scripts/factories/ui.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import chalk from "chalk";
import path from "path";
import { copyTemplateToDestinationAndIncrementIfExists, processDirectoryArg } from ".";
import { copyTemplateToDestinationAndIncrementIfExists, getDirectoryArg } from ".";

const directory = processDirectoryArg();
const directory = getDirectoryArg();
const destination = copyTemplateToDestinationAndIncrementIfExists(directory, "UI.svelte");

const name = path.basename(destination).replace(path.extname(destination), "");
Expand Down
Loading

0 comments on commit b01a58e

Please sign in to comment.