Skip to content

Commit

Permalink
Merge branch 'release/1.3.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
gaui committed Jul 15, 2019
2 parents 39c2cca + b5e7539 commit 9675ace
Show file tree
Hide file tree
Showing 43 changed files with 1,706 additions and 3,102 deletions.
17 changes: 0 additions & 17 deletions .babelrc

This file was deleted.

28 changes: 28 additions & 0 deletions .babelrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
const babelDefaultEnvOpts = {
corejs: 2,
useBuiltIns: 'entry'
};

const presets = [['@babel/env', babelDefaultEnvOpts], '@babel/typescript'];

const plugins = [['@babel/proposal-class-properties']];

const config = {
env: {
test: {
presets: [
['@babel/env', { ...babelDefaultEnvOpts, modules: 'commonjs' }],
'@babel/typescript'
],
plugins: [...plugins]
},
development: {
presets: [['@babel/env', { targets: 'last 1 Chrome version' }]],
plugins: []
}
},
presets,
plugins
};

module.exports = config;
3 changes: 2 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ module.exports = {
plugins: ['@typescript-eslint'],
rules: {
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/no-use-before-define': ['error', 'nofunc']
'@typescript-eslint/no-use-before-define': ['error', 'nofunc'],
'@typescript-eslint/explicit-function-return-type': 'off'
}
};
1 change: 0 additions & 1 deletion .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ logs
*.log
npm*
yarn*
tslint.json
tsconfig.json
examples/
src/
Expand Down
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
12.4.0
63 changes: 63 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Changelog

## 1.3.0

- **refactor:** Use `.d.ts` files instead of exporting/importing types/interfaces.
- **fix:** Fixed `toArray()` for commands with arguments and added tests.
- **docs:** Moved changelog from `README.md` to `CHANGELOG.md`.
- **chore:** Added Renovate to manage dependencies.
- **chore:** Pin all dependencies to fixed SemVer.
- **chore:** Node v8 support bumped to v10 (LTS).
- **chore:** Pin Node development to `12.4.0` (`engines:node` restriction + `.nvmrc` file).
- **chore:** Upgrade various dependencies to latest version, e.g. Babel, TypeScript + Jest.
- **chore:** Added `yarn audit` npm script to manage vulnerabilities in package dependencies.
- **chore:** Utilise Jest test coverage feature, to use in CI.
- **chore:** Use [@pika/pack](https://github.com/pikapkg/pack) for bundling and distributing the library.

## 1.2.2

- **fix:** Wrong import for `glob` module.

## 1.2.1

- **feat:** Added the option to convert platform specific variables with the [`convertVariables` option](#convertVariables).
- **feat:** Added the option to ignore lines based on a RegExp pattern with the [`lineIgnorePattern` option](#lineIgnorePattern), e.g. comment lines starting with `#` or `//`
- **feat:** Dynamic Variables can now be [primitive values instead of only functions](#dynamicVariables).
- **feat:** Now possible to chain `prependArgument()` and `appendArgument()` functions on `ICommand`.
- **feat:** New option `throwUnresolvedVariables` that throws an exception and stops the process when handling variables that cannot be resolved.
- **fix:** Empty arguments resulted in the string `undefined`.
- **chore:** Unit tests for all core functionality.
- **chore:** Moved examples to CodeSandbox.
- **chore:** Use Ramda.
- **chore:** Use microbundle for bundling and distribution.
- **chore:** Migrate from TSLint to ESLint

## 1.1.4

- Added possibility to specify stdout/stderr callbacks when executing a command (in `exec()` function).
- Added stdout/stderr output when promise for process is resolved.
- Only use `close` event (instead of both `close` and `exit`) in ChildProcess to determine status of process.

## 1.1.3

- Upgraded to Babel 7 stable release.
- Updated dependencies.
- Added reference to git repo in package.json.

## 1.1.2

- Added option for specifying which shell to use for executing commands. Default is `/bin/bash`

## 1.1.1

- Added support for class properties (Babel plugin).

## 1.1.0

- Babel 7.
- Possibility to specify root dir for glob search patterns.
- Bunch of refactoring.

## 1.0.0

First release.
201 changes: 89 additions & 112 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,94 @@
# argster

A simple command/argument manager with a simple API that makes it easy to build commands and arguments.
A simple command/argument manager with a simple API that makes it easy to build dynamic commands and dynamic arguments with computed values.

## Examples
## What

Check out this [CodeSandbox](https://codesandbox.io/s/lyjjqzv38q).
The [Builder's](#builder) builds and manages commands. When a new `Builder` instance is created, it provides an simple API to create and execute commands, append and prepend dynamic arguments.

When creating [commands](#command) through the builder, it goes through the list of file patterns recursively, reads each file, parses each line in the file, resolves dynamic variables to their values, and generates an executable command string. When a command is executed, it returns an object which contains both a _promise_ which is resolved or rejected based on how the process exits (0 / 1), along with a [Readable](https://nodejs.org/api/stream.html#stream_readable_streams) streams object for listening to stdout and stderr streams.

So instead of manually creating the following command in our CI pipeline, with dynamic arguments and dynamic values that need to be computed at runtime:

```bash
docker build . -t myimage:1.0.0 --label org.label-schema.build-date=2019-07-14 --label org.label-schema.name=argster-120-example --label org.label-schema.vendor=Vendor --label org.label-schema.version=1.0.0 --label org.label-schema.schema-version=1.0.0-rc.1
```

You could create a simple JavaScript script and create complex commands with dynamic arguments (evaluated JavaScript functions) and version control it all with Git.

### Example (docker build)

Pay special attention to the `org.label-schema.build-date` label with the dynamic date.

**1. If we created the following builder and command**

```typescript
const options = {
dynamicVariables: {
BUILD_DATE: () => new Date().toISOString().slice(0, 10),
NAME: () => pkg.name,
VERSION: () => pkg.version,
DESCRIPTION: () => pkg.description,
VENDOR: () => "Vendor",
SCHEMA_VERSION: () => "1.0.0-rc.1"
},
skipUnresolvedVariables: true
};

const builder = new Builder(options);

const cmd = builder.createCommand('docker build .', [
{
patterns: ['**/*.lbl'],
prefix: '--label'
}
]);

cmd.prependArgument({
argument: `myimage:${pkg.version}`,
prefix: '-t'
});

command.exec();
```

**2. And had this pattern file**

**`./some/deep/path/file.lbl`**

```ini
org.label-schema.build-date=${BUILD_DATE}
org.label-schema.name=${NAME}
org.label-schema.description=${DESCRIPTION}
org.label-schema.vendor=${VENDOR}
org.label-schema.version=${VERSION}
org.label-schema.schema-version=${SCHEMA_VERSION}
```

**3. This will be the executed command:**

```bash
docker build . -t myimage:1.0.0 --label org.label-schema.build-date=2019-07-14 --label org.label-schema.name=argster-120-example --label org.label-schema.vendor=Vendor --label org.label-schema.version=1.0.0 --label org.label-schema.schema-version=1.0.0-rc.1
```

## Why

I always felt the lack of a tool/library to easily create dynamic commands with dynamic arguments that were derived by functions but had the possibility to version control, without creating complex shell scripts. It first started when I was experimenting with DevOps and started to work with Docker trying to create sane images. I started reading about best practices around labeling and tagging Docker images and stumbled up on [Label Schema](http://label-schema.org/rc1/#label-semantics).

I sat down and thought about the following technologies:

- Label Schema and label semantics for e.g. Docker images
- Dockerfile and `ENV` / `ARG`
- Dockerfile and `.env` file
- Power of JavaScript
- Power of variables
- Power of Git

With the great tech above I wanted to utilise it all and create a Node library that was able to build up complex dynamic command-line commands and arguments. Then the idea of **argster** was born.

Check out this [CodeSandbox](https://codesandbox.io/s/lyjjqzv38q) for examples.

Checkout the [roadmap](#roadmap) for what to come.

## Setup

Expand Down Expand Up @@ -57,59 +141,6 @@ All files matching the glob pattern `**/*.arg` and `**/*.lbl` would be read and

When the command arguments are evaluated, a finalized command string is generated from those file contents.

To explain...

#### 1. If we created the following builder/command

```typescript
const extensions = [
{
prefix: '--build-arg',
patterns: ['**/*.arg']
},
{
prefix: '--label',
patterns: ['**/*.lbl']
}
];

const options = {
dynamicVariables: {
BUILD_DATE: () => new Date().toISOString().slice(0, 10)
}
};

const builder = new Builder(options);
const command = builder.createCommand('docker build .', extensions);
command.exec();
```

#### 2. And had these pattern files

**`./foo/file.arg`**

```ini
VAR1=VAL1
VAR2=VAL2
VAR3=VAL3
```

**`./foo/bar/file.lbl`**

```ini
org.label-schema.build-date=${BUILD_DATE}
org.label-schema.name=MyProject
```

#### 3. This would be the generated command that would be executed


```bash
docker build . --build-arg VAR1=VAL1 --build-arg VAR2=VAL2 --build-arg VAR3=VAL3 --label org.label-schema.build-date=2018-08-03 --label org.label-schema.name=MyProject
```

Take a look at how the `${BUILD_DATE}` argument now has the actual date. This is based on the dynamic variable we specified in the builder options above.

### Builder Options

#### rootDir
Expand Down Expand Up @@ -287,14 +318,10 @@ toString(): string;
toArray(): ReadonlyArray<string>;
```

## How it works

The [Builder's](#builder) responsibility is to build and manage commands. When a new `Builder` instance is created, it provides a API to create commands.

When creating [commands](#command) through the builder, it goes through the list of file patterns recursively, reads each file, parses each line in the file, resolves dynamic variables to their values, and generates a executable command string. When a command is executed, it returns an object which contains both a _promise_ which is resolved or rejected based on how the process exits, along with a [Readable](https://nodejs.org/api/stream.html#stream_readable_streams) streams object for listening to stdout and stderr streams.

## Roadmap

- Set up automated TypeScript documentation for APIs
- Follow [Conventional Commits](https://www.conventionalcommits.org)
- Set up CI to run automated tests
- Plugin / Middleware architecture
- Ability to hook into events
Expand All @@ -315,53 +342,3 @@ Just remember to run the following beforehand:
- `yarn typecheck`
- `yarn format`
- `yarn lint`

## Changelog

### 1.2.2

- **fix:** Wrong import for `glob` module.

### 1.2.1

- **feat:** Added the option to convert platform specific variables with the [`convertVariables` option](#convertVariables).
- **feat:** Added the option to ignore lines based on a RegExp pattern with the [`lineIgnorePattern` option](#lineIgnorePattern), e.g. comment lines starting with `#` or `//`
- **feat:** Dynamic Variables can now be [primitive values instead of only functions](#dynamicVariables).
- **feat:** Now possible to chain `prependArgument()` and `appendArgument()` functions on `ICommand`.
- **feat:** New option `throwUnresolvedVariables` that throws an exception and stops the process when handling variables that cannot be resolved.
- **fix:** Empty arguments resulted in the string `undefined`.
- **chore:** Unit tests for all core functionality.
- **chore:** Moved examples to CodeSandbox.
- **chore:** Use Ramda.
- **chore:** Use microbundle for bundling and distribution.
- **chore:** Migrate from TSLint to ESLint

### 1.1.4

- Added possibility to specify stdout/stderr callbacks when executing a command (in `exec()` function).
- Added stdout/stderr output when promise for process is resolved.
- Only use `close` event (instead of both `close` and `exit`) in ChildProcess to determine status of process.

### 1.1.3

- Upgraded to Babel 7 stable release.
- Updated dependencies.
- Added reference to git repo in package.json.

### 1.1.2

- Added option for specifying which shell to use for executing commands. Default is `/bin/bash`

### 1.1.1

- Added support for class properties (Babel plugin).

### 1.1.0

- Babel 7.
- Possibility to specify root dir for glob search patterns.
- Bunch of refactoring.

### 1.0.0

First release.
4 changes: 1 addition & 3 deletions __tests__/__mocks__/basic.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { Builder, IBuilderOptions } from '../../src';
import { IUtilsParam } from '../../src/api/utils';
import { ILogUtils } from '../../src/api/utils/log';
import { Builder } from '../../src';
import utilFactory from '../../src/utils/factory';

export const fs = (str: string): typeof import('fs') => {
Expand Down
7 changes: 1 addition & 6 deletions __tests__/e2e/e2e.spec.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
import * as path from 'path';
import {
Builder,
IArgumentFilePatterns,
IBuilder,
IBuilderOptions
} from '../../src';
import { Builder } from '../../src';
import Command from '../../src/command';

const rootDir = path.join(__dirname, 'data');
Expand Down
Loading

0 comments on commit 9675ace

Please sign in to comment.