Skip to content

Architecture for setup wizard #1240

@matejchalk

Description

@matejchalk

Developer story

To build a feature-rich setup wizard described in #1239 and its sub-issues, we need to pick the right tools and architecture. The goal of this task is to research and design how we'll build this tool.

Technical design

Our create-cli and nx-plugin packages

Technically, we do already have a config generator in @code-pushup/create-cli and @code-pushup/nx-plugin. However, all it does is generate an empty (and therefore invalid) config file, and it's not actually used anywhere. Furthermore, we can't even build on top of it, as it's tightly coupled to Nx - in fact, @code-pushup/create-cli executes the @code-pushup/nx-plugin:configuration generator. Basing our setup wizard on an Nx generator would severely limit its capabilities. For example, Nx generators only support static prompts, whereas we'll need dynamic prompts that depend on previous prompt answers or information from the user's file system.

We'll need to break create-cli's dependency on nx-plugin. Instead of create-cli being a thin wrapper around a generator in nx-plugin, our core implementation should be entirely Nx-agnostic, and the Nx generator should be a thin wrapper on top of it.

User input

To make the setup wizard user-friendly, the primary mode of accepting user input should be via interactive terminal prompts. We can use @inquirer/prompts to integrate a rich set of prompts - input, select, checkbox, etc.

In some circumstances, it may be beneficial to set the prompt answers with CLI arguments. For example, adding --mode=monorepo would skip a Do you want to use standalone or monorepo mode? prompt. As there will be a large number of prompts, we should organize them using namespaces - e.g., --plugins.options.eslint.patterns='src/**/*.ts'. We'll also need to parse array (--plugins.enabled=eslint,coverage ➡️ { plugins: { enabled: ['eslint', 'coverage'] } }) and boolean (--no-upload ➡️ { upload: false }) values according to common conventions. We can use yargs to parse command-line arguments, since we already use it in @code-pushup/cli.

Plugin bindings

Our generated config won't be useful unless it sets up plugins with a working configuration. Obviously, we can't set up custom plugins with a few terminal prompts. But every one of our official plugins should be fully supported. This means each plugin will have its own dedicated prompts, as well as suggested categories.

To provide some separation between the core layer and plugin layer in our codebase, we should extend the PluginConfig interface with additional bindings. These will be optional in general, so that custom plugins don't have to implement them, but every official plugin should implement these bindings eventually. These "codegen" bindings will consist of callback functions that will be called by the core layer for each selected plugin.

File system

TODO

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions