0.1.7 • Published 3 years ago

@adlib/cli v0.1.7

Weekly downloads
-
License
ISC
Repository
github
Last release
3 years ago

@adlib/cli

Simple, flexible, and sharable project configuration.

  • Reduce configuration clutter.
    • Tool configuration files (eg. Babel, Webpack) can be copied into your project "just-in-time", and then removed after use.
  • Isolate development dependencies.
    • Configuration package dependencies are kept outside of your project's resolve paths.
  • Simplify configuration creation and sharing.
    • Define project initialization and tasks in a simple and friendly YAML file.
    • Use configuration packages published to NPM or Git, or just use a local directory to get going fast.
  • Meet the needs of any project.
    • No preference for any specific tools or build strategies.
    • Anyone can create and publish a configuration.

Getting Started

Install Adlib globally. This makes it simple to run Adlib tasks in any project with an adlib configuration.

$ npm add -g @adlib/cli

Add the Adlib configuration to your package.json file. The config value can be an NPM package (with optional version range), Git repo URL, .tgz file (local or remote), or a local directory. The optional pm value can be set to npm, yarn, or omitted for auto-detection.

{
  "adlib": {
    "config": "@adlib/config-typescript",
    "pm": "npm"
  }
}

Run the init task in your project directory to install your chosen configuration and to perform any project "bootstrapping" the configuration may include. This is technically optional because it is done "on-demand" when running all Adlib tasks.

$ adlib init

Run tasks defined by the configuration.

$ adlib <task>

If you don't know the tasks defined by the configuration, you can run the ls task to list them.

$ adlib ls

Built-in Tasks

Adlib has the following built-in tasks.

  • adlib help - Print the Adlib help text.
  • adlib version - Print the Adlib version in use.
  • adlib init - Restore the configuration.
  • adlib ls - List the tasks defined by the configuration.
  • adlib eject <task> - Permanently copy a task's "just-in-time" configuration files into your project for customization.
  • adlib exec <...args> - Execute an arbitrary command within the configuration context. The process will be able to resolve configuration dependencies and invoke executables locally installed to the configuration.

Optional Setup

Install Adlib as a dev dependency of your project. The globally installed Adlib will always delegate to a locally installed version if it exists. This can be used to "pin" the Adlib version that your project uses.

$ npm add -D @adlib/cli

Adlib itself has no dependencies, and exports nothing, so it won't pollute your project scope.

Create A Configuration

A configuration must have at least two files: package.json and adlib.yaml.

The package.json file is required because Adlib uses npm internally to get configuration packages. So, Adlib configurations must actually be valid NPM packages. Everything in this file is up to you.

The adlib.yaml file has the following structure:

# Optional Bootstrap configuration. Things that will be done when the
# "init" task is invoked.
init:

  # Optional files to copy from the configuration to the target
  # project.
  #
  # Only individual files are supported. Directories and globs are
  # not supported. Only files that do not exist will be created.
  # Files are never overwritten.
  copy:

    # Simple filename path strings copy a source file from the
    # configuration, to the ROOT of the target project (regardless of
    # the source file's directory structure). The filename will not
    # be changed.
    - filename # from <config>/filename, to <target>/filename

    # Objects with "from" and "to" path properties allow a source
    # file to be renamed and/or placed in a subdirectory of the
    # target project.
    - from: filename # <config>/filename
      to: subdirectory/renamed # <target>/subdirectory/renamed

  # Optional key/value pairs to be added to the target project's
  # package.json file.
  #
  # Only new keys will be added. Keys are never overwritten or
  # removed. Deep merging is not supported.
  config:

    # Key and value pair.
    key: value
  
  # Optional DEV dependencies to be installed in the target project.
  # Only new dependencies will be added.
  #
  # Dependencies are never overwritten or removed. Dependency
  # strings are the same arguments that could be passed to "npm add".
  install:

    # Without version the version range from the configuration's
    # package.json file will be used. If the package is not a
    # configuration dependency, then it will be installed at the
    # "latest" tag.
    - package
    
    # Version ranges and tags override any version in the
    # configuration package.json file.
    - package@^1.2.3
    - package@prerelease

# Optional map of tasks which can be run using "adlib <task>".
tasks:

  # Task names can be any string except the built-in Adlib
  # tasks (help, version, init, ls, exec, eject).
  myTask:

    # A description which will be printed when the "adlib ls" command
    # is invoked.
    describe: My Task

    # Optional files to copy before running the task (ie.
    # just-in-time).
    #
    # Copied files will be deleted after the task completes (even if
    # it fails). The structure and behavior of this option is the
    # same as "init.copy" option described above.
    copy:
      - myFile
      - from: myFile
        to: subdirectory/renamedFile
    
    # Required array of commands.
    run:

      # Command string.
      #
      # For portability, these strings are parsed using a "Bash-like"
      # syntax. However, Bash operators (eg. && || >) are NOT
      # supported and will cause an error.
      #
      # If a command fails, the task fails immediately without
      # running any of the following commands.
      - echo "quoted argument"

Managing Dependencies

Whenever possible, avoid adding dependencies to the init.install array in your adlib.yaml file. Reducing the number of dependencies in target projects should be a top priority.

The unfortunate current exception is usually ESLint (or other linter dependencies), because your IDE will probably need to know about those dependencies in order to provide inline linting hints.

Managing Tool Configuration Files

Use the "just-in-time" feature (tasks.<task>.copy) whenever possible. It allows target projects to eject configuration files for customization. Many tools will allow you to give an explicit configuration path, which would let you simply target the configuration in the .adlib/config/... directory. But, this will make it hard for consumers to customize.

If you do need to add permanent configuration to target projects, consider adding it to the target's package.json using the init.config map in your adlib.yaml file. This will keep the file structure of the target project cleaner than copying in configuration files.

Sharing Configurations

Add the adlib-config keyword to your package and publish it to NPM. Adding this keyword will allow others to find your configuration using the keywords:adlib-config query.

As a best practice, describe the intended use, target environments, and tool-chain in the configuration's README.md file.