Skip to content

Commit

Permalink
feat: --branch --preset and --lucky options (#309)
Browse files Browse the repository at this point in the history
* feat: add branch option to git clone

* feat: pass branch to git cloner

* feat: add `-b` or `--branch` option for custom branches

* chore: update version

* test: ignore `/lib`

* test: fix tests for `git` module

* refactor: move type check to functions

* feat: `canUseDirAsName` binary helper

* feat: add `getPresets` helper

* chore: export new helpers

* add preset options

* feat: add lucky helpers

* feat: add `lucky` option for random answers

* docs: add new options to `--help`

* docs: add new options to `readme.md`

* docs: add `presets` to docs/references

* fix: auto accept telemetry on presets

* fix: handle `value` with `name` property

* feat: add preset answers to extras

* refactor: use `for`

* refactor(1/2): supply only `yes` instead of answers for lucky

* refactor(2/2): map prompts and change default for presets

* chore: fix failing action
  • Loading branch information
aliemir authored Jun 24, 2022
1 parent a7af4b3 commit 2ef4345
Show file tree
Hide file tree
Showing 15 changed files with 300 additions and 81 deletions.
1 change: 1 addition & 0 deletions @types/sao.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ interface IExtras {
debug: boolean;
paths: IPaths;
projectType: string;
presetAnswers?: Record<string, string | undefined>;
}
interface Options$1 {
appName?: string;
Expand Down
13 changes: 9 additions & 4 deletions README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,12 @@

## About

Superplate lets you start rock-solid, production-ready *React* and *Next.JS* projects just in seconds. The command-line interface guides the user through setup and no additional build configurations are required.
Superplate lets you start rock-solid, production-ready _React_ and _Next.JS_ projects just in seconds. The command-line interface guides the user through setup and no additional build configurations are required.

Superplate ships with more than 30 plugins including popular UIKits, testing frameworks and many useful developer tools.

## Available Integrations

<a href="https://pankod.github.io/superplate/docs/">
<img src="images/available.png" align="center" />
</a>
Expand All @@ -56,9 +57,9 @@ For more detailed information and usage, you may refer to our [documentation pag

## Quick Start

To use superplate, make sure you have *npx* is installed on your system (npx is shipped by default since npm 5.2.0).
To use superplate, make sure you have _npx_ is installed on your system (npx is shipped by default since npm 5.2.0).

To create a new app, run the following command:
To create a new app, run the following command:

```bash
npx superplate-cli <my-project>
Expand Down Expand Up @@ -134,11 +135,15 @@ Options:
-d, --debug prints additional logs
-s, --source <path-to-source> Use this option to target a custom source of plugins
Source path can be a remote git repository or a local path.
-p, --project <project-type> In sources with multiple types, you can use this option to preset the type.
-b, --branch <branch-name> If your source is a git repository, you can define a custom branch for `superplate` to use.
-o, --preset <preset-name> If your source includes presets, you can select one of them to prefill the answers.
-l, --lucky You can select random choices with this option, if you are feeling lucky.
```

## Development mode commands

Watches for changes in the code; builds the project and then globally installs superplate for testing.
Watches for changes in the code; builds the project and then globally installs superplate for testing.

```
npm run dev:global
Expand Down
15 changes: 15 additions & 0 deletions documentation/docs/development/references.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ CLI has two built-in prompts; app name and the package manager questions are pro

You can also apply ignore patterns for your plugins, those ignore glob patterns can be applied project-wide or only for specified plugins. Provide a function with prompt answers to whether the ignore patterns will apply or not.

Also you can define presets, those will be available to use with `--preset` option. Presets can include all or part of the choices.

```ts
prompts: {
type: string;
Expand All @@ -27,6 +29,11 @@ ignores: {
pattern: string[]
}[];
```
```ts
presets: Array<{
name: string;
answers: Record<string,string>;
}>;

**Example**

Expand Down Expand Up @@ -63,6 +70,14 @@ module.exports = {
},
pattern: ["src/components/**", "pages/index.tsx"],
},
],
presets: [
{
name: "with-antd",
answers: {
ui: "antd"
}
}
]
};
Expand Down
4 changes: 1 addition & 3 deletions jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,7 @@ export default {
// ],

// An array of regexp pattern strings that are matched against all test paths, matched tests are skipped
// testPathIgnorePatterns: [
// "/node_modules/"
// ],
testPathIgnorePatterns: ["/node_modules/", "/lib"],

// The regexp pattern or array of patterns that Jest uses to detect test files
// testRegex: [],
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "superplate-cli",
"version": "1.5.1",
"version": "1.6.1",
"description": "The frontend boilerplate with superpowers",
"license": "MIT",
"repository": {
Expand Down
5 changes: 5 additions & 0 deletions src/Helper/binary/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,9 @@ export const BinaryHelper = {
return false;
}
},
CanUseDirAsName: (projectDir: string): boolean => {
// eslint-disable-next-line no-useless-escape
const invalidChars = /[\\\/,.]/;
return !invalidChars.test(projectDir);
},
};
23 changes: 5 additions & 18 deletions src/Helper/git/index.spec.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
import { GitHelper } from "./";
import { promisify } from "util";

jest.mock("util", () => ({
promisify: jest.fn(() => {
throw new Error();
}),
}));
describe("Git Helper", () => {
it("not found git url IsRepoExist", async () => {
const isRepoExist = await GitHelper.IsRepoExist(
Expand All @@ -22,23 +16,16 @@ describe("Git Helper", () => {
});

it("valid git url CloneAndGetPath", async () => {
(promisify as any).mockImplementation(() =>
jest
.fn()
.mockResolvedValue({ stdout: "git@github.com:mock/url.git" }),
);

const cloneAndPath = await GitHelper.CloneAndGetPath(
const cloneAndPath = GitHelper.CloneAndGetPath(
"https://github.com/pankod/action-test",
);

expect(cloneAndPath).not.toBeFalsy();
await expect(cloneAndPath).resolves.not.toBeUndefined();
});

it("invalid git url CloneAndGetPath", async () => {
(promisify as any).mockImplementation(() => new Error());
await expect(
GitHelper.CloneAndGetPath("https://pankod.com"),
).rejects.toThrowError();
const cloneAndPath = GitHelper.CloneAndGetPath("https://pankod.com");

await expect(cloneAndPath).rejects.toThrowError();
});
});
10 changes: 5 additions & 5 deletions src/Helper/git/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,17 @@ export const GitHelper = {
}
return { exists: false, error: "Source path not valid" };
},
CloneAndGetPath: async (path: string): Promise<string> => {
CloneAndGetPath: async (path: string, branch?: string): Promise<string> => {
try {
const tempInfo = await promisify(mkdir)("");
await promisify(exec)(
`git clone --depth 1 ${UrlHelper.GetGitUrl(
path,
)} "${tempInfo}"`,
`git clone --depth 1 ${
branch ? `--branch ${branch}` : ""
} ${UrlHelper.GetGitUrl(path)} "${tempInfo}"`,
);
return tempInfo;
} catch (e) {
throw Error(e);
throw new Error(e instanceof Error ? e.message : (e as string));
}
},
};
13 changes: 12 additions & 1 deletion src/Helper/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,20 @@ export {
concatExtend,
handleIgnore,
} from "./plugin";
export { get_source } from "./source";
export {
get_source,
get_project_types,
is_multi_type,
prompt_project_types,
} from "./source";
export { UrlHelper } from "./url";
export { GitHelper } from "./git";
export { FSHelper } from "./fs";
export { tips } from "./tips";
export { BinaryHelper } from "./binary";
export { get_presets } from "./preset";
export {
get_prompts_and_choices,
get_random_answer,
get_random_answers,
} from "./lucky";
54 changes: 54 additions & 0 deletions src/Helper/lucky/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import path from "path";

export type ProjectPrompt = {
name: string;
type: "select";
choices: { name?: string; message: string; value?: string }[];
default?: string;
skip?: ({ answers }: { answers: Record<string, string> }) => boolean;
};

export const get_prompts_and_choices = async (
source: string,
): Promise<ProjectPrompt[]> => {
try {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const sourcePrompts = require(path.resolve(source, "prompt.js"));

return (sourcePrompts.prompts ?? []) as ProjectPrompt[];
} catch (e) {
return [];
}
};

export const get_random_answer = (
projectPrompt: ProjectPrompt,
currentAnswers: Record<string, string>,
): [key: string, value: string | undefined] | undefined => {
if (projectPrompt.skip && projectPrompt.skip({ answers: currentAnswers })) {
return undefined;
}

const randomIndex = Math.floor(
Math.random() * projectPrompt.choices.length,
);

const { name, value } = projectPrompt.choices[randomIndex];

return [projectPrompt.name, name ?? value ?? undefined];
};

export const get_random_answers = (
projectPrompts: ProjectPrompt[],
): Record<string, string> => {
const answers: Record<string, string> = {};

for (const prompt of projectPrompts) {
const [key, value] = get_random_answer(prompt, answers) ?? [];
if (key && value) {
answers[key] = value;
}
}

return { ...answers };
};
17 changes: 17 additions & 0 deletions src/Helper/preset/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import path from "path";

export type Preset = {
name: string;
answers: Record<string, string>;
};

export const get_presets = async (source: string): Promise<Preset[]> => {
try {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const sourcePrompts = require(path.resolve(source, "prompt.js"));

return (sourcePrompts.presets ?? []) as Preset[];
} catch (e) {
return [];
}
};
Loading

0 comments on commit 2ef4345

Please sign in to comment.