Skip to content

Commit

Permalink
feat: make how
Browse files Browse the repository at this point in the history
  • Loading branch information
jonahsnider committed Jan 5, 2021
1 parent c0a14b5 commit a32255f
Show file tree
Hide file tree
Showing 10 changed files with 3,109 additions and 4,816 deletions.
41 changes: 11 additions & 30 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,28 +30,6 @@ jobs:
with:
name: tsc_output
path: tsc_output
lint:
name: Lint

runs-on: ubuntu-latest

steps:
- name: Checkout git repository
uses: actions/checkout@v2
- name: Get Yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn config get cacheFolder)"
- name: Cache dependencies
uses: actions/cache@v2
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Install dependencies with Yarn
run: yarn install --immutable
- name: Lint
run: yarn run lint
style:
name: Check style

Expand All @@ -74,11 +52,13 @@ jobs:
run: yarn install --immutable
- name: Check style
run: yarn run style
test:
name: Run unit tests
publish:
name: Publish

runs-on: ubuntu-latest

if: ${{ github.ref == 'refs/heads/main' }}

steps:
- name: Checkout git repository
uses: actions/checkout@v2
Expand All @@ -94,9 +74,10 @@ jobs:
${{ runner.os }}-yarn-
- name: Install dependencies with Yarn
run: yarn install --immutable
- name: Run tests
run: yarn run test
- name: Submit test coverage
uses: codecov/codecov-action@v1
with:
token: ${{ secrets.CODECOV_TOKEN }}
- name: Compile TypeScript for publishing
run: yarn run build
- name: Run semantic release
run: yarn run semantic-release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
Binary file added lib/glow-1.3.0
Binary file not shown.
68 changes: 25 additions & 43 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,65 +4,47 @@
"name": "Jonah Snider",
"url": "https://jonah.pw"
},
"ava": {
"extensions": [
"ts"
],
"files": [
"!tsc_output"
],
"require": [
"ts-node/register",
"source-map-support/register"
]
},
"description": "Learn how to use CLI apps.",
"bugs": {
"url": "https://github.com/pizzafox/typescript-starter/issues"
"url": "https://github.com/pizzafox/how/issues"
},
"devDependencies": {
"@istanbuljs/nyc-config-typescript": "1.0.1",
"ava": "3.15.0",
"eslint-plugin-prettier": "3.3.1",
"nyc": "15.1.0",
"@types/node": "14.14.20",
"prettier": "2.2.1",
"prettier-config-xo": "1.0.3",
"source-map-support": "0.5.19",
"semantic-release": "17.3.1",
"ts-node": "9.1.1",
"typescript": "4.1.3",
"xo": "0.37.1"
"typescript": "4.1.3"
},
"files": [
"tsc_output",
"lib"
],
"bin": "./tsc_output/index.js",
"license": "Apache-2.0",
"main": "./tsc_output/index.js",
"name": "typescript-starter",
"nyc": {
"all": true,
"extends": "@istanbuljs/nyc-config-typescript",
"include": [
"src/**/*.ts"
],
"reporter": [
"lcov",
"cobertura"
]
"name": "@pizzafox/how",
"publishConfig": {
"access": "public"
},
"private": true,
"repository": {
"type": "git",
"url": "git+https://github.com/pizzafox/typescript-starter.git"
"url": "git+https://github.com/pizzafox/how.git"
},
"type": "module",
"scripts": {
"build": "tsc",
"lint": "xo",
"prebuild": "rm -rf tsc_output",
"pretest": "rm -rf coverage .nyc_output",
"style": "prettier --check .",
"test": "nyc ava"
"style": "prettier --check ."
},
"os": [
"linux"
],
"engines": {
"node": ">=14.0.0"
},
"version": "1.0.0",
"xo": {
"prettier": true,
"rules": {
"prettier/prettier": "off"
}
"version": "0.0.0-development",
"dependencies": {
"execa": "5.0.0"
}
}
File renamed without changes.
51 changes: 30 additions & 21 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,33 @@
# [TypeScript](https://www.typescriptlang.org) Starter
# How

[![Build Status](https://github.com/pizzafox/typescript-starter/workflows/CI/badge.svg)](https://github.com/pizzafox/typescript-starter/actions)
[![Build Status](https://github.com/pizzafox/how/workflows/CI/badge.svg)](https://github.com/pizzafox/how/actions)
[![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/xojs/xo)
[![codecov](https://codecov.io/gh/pizzafox/typescript-starter/branch/master/graph/badge.svg)](https://codecov.io/gh/pizzafox/typescript-starter)

My personal TypeScript starter template.
Learn how to use CLI apps.

## Usage

Install using your favorite Node.js package manager:

```sh
npm i -g @pizzafox/how
yarn global add @pizzafox/how
pnpm i -g add @pizzafox/how
```

Make sure you're using Linux with an AMD64 CPU and also a recent version of Node.js (something that can run modules natively).

```sh
how <app>
```

### Example

Learn how to use `tar`:

```sh
how tar
```

## Contributing

Expand Down Expand Up @@ -35,23 +58,9 @@ yarn run style

### Linting

This project uses [XO](https://github.com/xojs/xo) (which uses [ESLint](https://eslint.org) and some plugins internally) to perform static analysis of the source code.
It reports issues like unused variables or not following best practices to ensure the project is well-written.

```sh
yarn run lint
```
There is intentionally no lint script.
Contributors are expected to write flawless code.

### Testing

Unit tests are stored alongside source files (ex. `config.ts` would have `config.test.ts`).
You can run the tests with the `test` script:

```sh
yarn run test
```

#### Coverage

This will generate a `coverage` folder which has a breakdown of coverage of the project.
The CI will upload the coverage information to [CodeCov](https://codecov.io) which can be [viewed here](https://codecov.io/gh/pizzafox/typescript-starter).
There are no unit tests for the same reason there is no lint script.
15 changes: 15 additions & 0 deletions src/format.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const examples = /`(.*)`/gm;
const exampleHeadings = /^- (.*)/gm;
const doubleBrackets = /{{|}}/g;

export function format(tldr: string): string {
return tldr
.replaceAll(
examples,
`\`\`\`sh
$1
\`\`\``
)
.replaceAll(exampleHeadings, '## $1')
.replaceAll(doubleBrackets, '');
}
7 changes: 0 additions & 7 deletions src/index.test.ts

This file was deleted.

61 changes: 54 additions & 7 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,55 @@
/**
* Says hello world.
* @param subject What the subject of the message is.
* @returns Hello world message
*/
export function helloWorld(subject?: string): string {
return `Hello, ${subject ?? 'world'}.`;
import execa from 'execa';
import fs from 'fs/promises';
import {homedir} from 'os';
import path from 'path';
import {stdout} from 'process';
import {format} from './format.js';

const tldrPath = path.join(homedir(), '.cache', 'how', 'tldr');

try {
await fs.access(tldrPath);
} catch (error) {
await fs.mkdir(tldrPath, {recursive: true});
await execa(`git`, ['clone', 'https://github.com/tldr-pages/tldr.git', tldrPath]);
}

if (Math.random() > 0.95) {
try {
await execa(`git`, ['pull'], {cwd: tldrPath});
console.error('you got unlucky and the cache was refreshed');
} catch (error) {
console.error('failed to refresh cache');
}
}

const command = process.argv[process.argv.length - 1];

// Command was probably a path (ex. '/home/jonah/programming/how/tsc_output')
if (command.includes(path.sep)) {
console.error('no program');
process.exit(1);
}

const potentialPaths = ['common', 'linux'].map(dir => path.join(tldrPath, 'pages', dir, `${command}.md`));

for (const potentialPath of potentialPaths) {
try {
await fs.access(potentialPath);
} catch {
continue;
}

const contents = await fs.readFile(potentialPath, 'utf-8');
const formatted = format(contents);

const tldr = await execa('./lib/glow-1.3.0', ['-s', 'dark', '-'], {
input: formatted
});

stdout.write(format(tldr.stdout));
process.exit(0);
}

console.error('no');
process.exit(1);
11 changes: 7 additions & 4 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
{
"compilerOptions": {
"module": "commonjs",
"moduleResolution": "node",
"module": "ESNext",
"target": "ESNext",
"lib": ["ESNext"],
"forceConsistentCasingInFileNames": true,
"moduleResolution": "Node",
"outDir": "tsc_output",
"allowSyntheticDefaultImports": true,
"resolveJsonModule": true,
"sourceMap": true,
"strict": true,
"target": "es2018"
"strict": true
},
"exclude": ["node_modules", "nyc_output", "coverage"],
"include": ["src"]
Expand Down
Loading

0 comments on commit a32255f

Please sign in to comment.