Skip to content

Commit

Permalink
feat: detect options automagically (#509)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: Configuration options are now detected automatically. Any manual configuration in tooling config files should be removed.
  • Loading branch information
connor-baer authored May 6, 2022
1 parent eb0105f commit c347790
Show file tree
Hide file tree
Showing 32 changed files with 639 additions and 448 deletions.
30 changes: 11 additions & 19 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,16 @@
*/

// eslint-disable-next-line node/no-unpublished-require
module.exports = require('./dist/eslint')(
{
language: 'TypeScript',
environments: ['Node'],
frameworks: ['Jest'],
openSource: true,
module.exports = require('./dist/eslint')({
rules: {
'no-process-exit': 'off',
},
{
rules: {
'no-process-exit': 'off',
},
overrides: [
{
files: ['src/cli/index.ts'],
rules: {
'node/shebang': 'off',
},
overrides: [
{
files: ['src/cli/index.ts'],
rules: {
'node/shebang': 'off',
},
],
},
);
},
],
});
2 changes: 1 addition & 1 deletion .releaserc.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@
* limitations under the License.
*/

module.exports = require('./dist/semantic-release')({ publish: true });
module.exports = require('./dist/semantic-release')();
121 changes: 46 additions & 75 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ A toolkit that makes it a breeze to set up and maintain JavaScript + TypeScript

### Installation

Foundry needs to be installed as a dev-dependency via the [Yarn](https://yarnpkg.com) or [npm](https://www.npmjs.com) package managers. The npm CLI ships with [Node](https://nodejs.org/en/). You can read how to install the Yarn CLI in [their documentation](https://yarnpkg.com/en/docs/install). Foundry requires Node v12+.
Foundry needs to be installed as a dev-dependency via the [Yarn](https://yarnpkg.com) or [npm](https://www.npmjs.com) package managers. The npm CLI ships with [Node](https://nodejs.org/en/). You can read how to install the Yarn CLI in [their documentation](https://yarnpkg.com/en/docs/install). Foundry requires Node `^14.17 || >=16`.

Depending on your preference, run one of the following.

Expand All @@ -51,50 +51,59 @@ $ yarn run foundry init
$ npx foundry init
```

Foundry will launch an interactive prompt to ask you questions about your project, such as in which language it is written, which frameworks it uses, or whether you are planning to open source it. Once you have answered all questions, Foundry will write the config files (don't worry, it asks before overwriting existing files) and will add scripts to your `package.json` file to conveniently run the tools.
Foundry will launch an interactive prompt to ask you questions about your project, such as whether you are planning to open source it. Once you have answered all questions, Foundry will write the config files (don't worry, it asks before overwriting existing files) and will add scripts to your `package.json` file to conveniently run the tools.

Alternatively, you can pass your answers to the `init` command directly as flags. This is useful for environments such as CI where interactive prompts cannot be used. Here is an overview of all available options (you can view this help menu by running `npx foundry init --help`):

```sh
--presets, -p A preset configures a group of tools that solve a common
problem [array] [options: "lint", "release", "ci"]
--language, -l The programming language in which the project is written
[options: "TypeScript", "JavaScript"]
--environments, -e The environment(s) in which the code runs
[array] [options: "Node", "Browser"]
--frameworks, -f The framework(s) that the project uses
[array] [options: "React", "Emotion", "Jest"]
--ci The CI platform the project uses [options: "github-actions"]
--openSource, -o Whether the project is open-source [boolean]
--publish Whether to publish to NPM [boolean]
--configDir, -c The directory to write the configs to [string] [default: "."]
--help Show this help menu [boolean]
-p, --presets A preset configures a group of tools that solve a common
problem [array] [choices: "lint", "release", "ci"]
-o, --openSource Whether the project is open-source [boolean]
--publish Whether to publish to NPM [boolean]
-c, --configDir The directory to write configs to [string] [default: "."]
--overwrite Whether to overwrite existing config files
[boolean] [default: false]
--version Show version number [boolean]
--help Show this help menu [boolean]
```

## Configuration

All config files that are generated by Foundry follow the same format. They import a configuration function, optionally call it with an options object and/or overrides, and export the result. Here's an example:
All config files that are generated by Foundry follow the same format. They import a configuration function, optionally call it with overrides, and export the result. Here's an example:

```js
module.exports = require('@sumup/foundry/<tool>')(options, overrides);
module.exports = require('@sumup/foundry/<tool>')(overrides);

// Example for .eslintrc.js:
module.exports = require('@sumup/foundry/eslint')(
{
language: 'TypeScript',
environments: ['Browser'],
module.exports = require('@sumup/foundry/eslint')({
rules: {
'@emotion/jsx-import': 'error',
},
{
rules: {
'@emotion/jsx-import': 'error',
},
},
);
});
```

The options for each tool are documented below.
The overrides are merged with Foundry's default configuration. The overrides follow each tool's configuration schema, please refer to their official documentation.

Foundry analyzes your project's `package.json` file to tailor the configurations to your project. If the automatic detection is inaccurate, [please open an issue](https://github.com/sumup-oss/foundry/issues/new/choose) so we can improve it for everyone. Alternatively, you can explicitly set the options under the `foundry` property in your `package.json` file:

```json
// package.json
{
"foundry": {
"publish": true
}
}
```

The overrides are merged with Foundry's default configuration after the options have been applied. The overrides follow each tool's configuration schema, please refer to their official documentation.
The supported options are:

| Name | Type | Options | Default |
| ------------ | ------- | --------------------------------------------------------------------------------- | -------------- |
| language | string | 'TypeScript', 'JavaScript' | _autodetected_ |
| environments | array | 'Browser', 'Node' | _autodetected_ |
| frameworks | array | 'React', 'Next.js', 'Emotion', 'Jest', 'Testing Library', 'Cypress', 'Playwright' | _autodetected_ |
| openSource | boolean | true, false | _autodetected_ |
| publish | boolean | true, false | false |

## Presets

Expand All @@ -110,40 +119,10 @@ Check code for syntax errors and format it automatically. The preset adds the fo

The preset includes the following tools:

#### ESLint

[ESLint](https://www.npmjs.com/package/eslint) identifies and fixes problematic patterns in your code so you can spot mistakes early.

ESLint's configuration options:

| Name | Type | Options | Default |
| ------------ | ------- | --------------------------------------------------------------------------------- | -------------- |
| language | string | 'TypeScript', 'JavaScript' | 'TypeScript' |
| environments | array | 'Browser', 'Node' | [] |
| frameworks | array | 'React', 'Next.js', 'Emotion', 'Jest', 'Testing Library', 'Cypress', 'Playwright' | _autodetected_ |
| openSource | boolean | true, false | false |

#### Prettier

[Prettier](https://prettier.io) is our code formatter of choice. It makes all our code look the same after every save.

Prettier currently has no configuration options.

#### lint-staged

[lint-staged](https://www.npmjs.com/package/lint-staged) is a tool for running linters on files staged for your next commit in git. Together with Husky (see below) it prevents bad code from being committed.

lint-staged's configuration options:

| Name | Type | Options | Default |
| -------- | ------ | -------------------------- | ------------ |
| language | string | 'TypeScript', 'JavaScript' | 'TypeScript' |

#### Husky

[Husky](https://github.com/typicode/husky) makes setting up git hooks very easy. Whenever someone installs your project, Husky will automatically set up git hooks as part of its `postinstall` script.

Husky currently has no configuration options.
- **[ESLint](https://www.npmjs.com/package/eslint)** identifies and fixes problematic patterns in your code so you can spot mistakes early.
- **[Prettier](https://prettier.io)** is our code formatter of choice. It makes all our code look the same after every save.
- **[lint-staged](https://www.npmjs.com/package/lint-staged)** is a tool for running linters on files staged for your next commit in git. Together with Husky (see below) it prevents problematic code from being committed.
- **[Husky](https://github.com/typicode/husky)** makes setting up git hooks very easy. Whenever someone installs your project, Husky will automatically set up git hooks as part of its `postinstall` script.

### 🚀 Release

Expand All @@ -153,25 +132,17 @@ Automatically generate release notes and (optionally) publish to NPM. The preset

The preset includes the following tools:

#### semantic-release

[semantic-release](https://www.npmjs.com/package/semantic-release) automates the whole package release workflow including determining the next version number, generating the release notes, and publishing the package.

semantic-releases's configuration options:

| Name | Type | Options | Default |
| ------- | ------- | ----------- | ------- |
| publish | boolean | true, false | false |
- **[semantic-release](https://www.npmjs.com/package/semantic-release)** automates the whole package release workflow including determining the next version number, generating the release notes, and publishing the package.

### 🤖 Continuous Integration (CI)

Validate the code on every push using the [🔍 linting](#-lint) preset (if configured). The supported CI providers are:

- [**GitHub Actions**](https://github.com/features/actions) builds, tests, and publishes your code right from GitHub.
- **[GitHub Actions](https://github.com/features/actions)** builds, tests, and publishes your code right from GitHub.

## Running a tool

Foundry manages all supported tools for you and exposes them via the `run` command. As an example: to run ESLint through Foundry, execute:
Foundry manages all supported tools for you and exposes them via the `run` command. As an example, to run ESLint through Foundry, execute:

```sh
# With Yarn
Expand All @@ -185,7 +156,7 @@ Here, `src` is the folder you want ESLint to check. Note that you can use any of

## Why?

> ##### TLDR
> ##### TL;DR
>
> Creating and maintaining a JavaScript project can be very tedious. There are tools, configurations, dependency management, and boilerplate. With Foundry, you can fix all of that with a single dependency. It lints, creates files, and keeps the tools up to date. And the best part? You can still get down and dirty with your configurations. But only if you want.
Expand Down
14 changes: 6 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,15 @@
"release": "cd ./dist && semantic-release"
},
"engines": {
"node": ">=16 || ^14.17"
"node": "^14.17 || >=16"
},
"browserslist": [
"chrome >= 57",
"firefox >= 54",
"safari >= 10.3",
"edge >= 16",
"opera >= 44",
"samsung >= 6.2",
"supports css-grid and supports object-entries"
"node 14.17",
"node 16"
],
"foundry": {
"publish": true
},
"dependencies": {
"@babel/core": "^7.17.10",
"@babel/eslint-parser": "^7.14.3",
Expand Down
20 changes: 2 additions & 18 deletions src/cli/defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,11 @@
* limitations under the License.
*/

import {
Options,
Preset,
Language,
Environment,
Framework,
CI,
} from '../types/shared';
import { InitOptions, Preset } from '../types/shared';

export const DEFAULT_OPTIONS: Options = {
export const DEFAULT_OPTIONS: InitOptions = {
presets: [Preset.LINT],
configDir: '.',
language: Language.TYPESCRIPT,
environments: [Environment.BROWSER],
frameworks: [
Framework.REACT,
Framework.EMOTION,
Framework.JEST,
Framework.TESTING_LIBRARY,
],
ci: CI.GITHUB_ACTIONS,
openSource: false,
publish: false,
overwrite: false,
Expand Down
25 changes: 2 additions & 23 deletions src/cli/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

import yargs from 'yargs';

import { Preset, Language, Environment, Framework, CI } from '../types/shared';
import { Preset } from '../types/shared';
import { enumToChoices } from '../lib/choices';

import { run, RunParams } from './run';
Expand All @@ -33,30 +33,9 @@ void yargs
presets: {
alias: 'p',
desc: 'A preset configures a group of tools that solve a common problem',
choices: enumToChoices(Preset) as Preset[],
choices: enumToChoices(Preset),
type: 'array',
},
language: {
alias: 'l',
desc: 'The programming language the project uses',
choices: enumToChoices(Language),
},
environments: {
alias: 'e',
desc: 'The environment(s) that the code runs in',
choices: enumToChoices(Environment),
type: 'array',
},
frameworks: {
alias: 'f',
desc: 'The frameworks the project uses',
choices: enumToChoices(Framework),
type: 'array',
},
ci: {
desc: 'The CI platform the project uses',
choices: enumToChoices(CI),
},
openSource: {
alias: 'o',
desc: 'Whether the project is open-source',
Expand Down
Loading

0 comments on commit c347790

Please sign in to comment.