diff --git a/.gitignore b/.gitignore index b9b5ee10..f1fae0d4 100644 --- a/.gitignore +++ b/.gitignore @@ -9,12 +9,12 @@ cplefthook tmp/ dist/ -.rubygems/pkg/ -.rubygems/libexec/ -.npm/bin/ -!.npm/bin/*.js +packaging/rubygems/pkg/ +packaging/rubygems/libexec/ +packaging/npm-bundled/bin/ +packaging/npm-*/README.md package.json -!.npm/package.json +!packaging/npm-*/package.json node_modules/ yarn.lock package-lock.json diff --git a/.npm/README.md b/.npm/README.md deleted file mode 100644 index 08a64216..00000000 --- a/.npm/README.md +++ /dev/null @@ -1,203 +0,0 @@ -![Build Status](https://api.travis-ci.org/evilmartians/lefthook.svg?branch=master) - -# Lefthook - -> The fastest polyglot Git hooks manager out there - - - -Fast and powerful Git hooks manager for Node.js, Ruby or any other type of projects. - -* **Fast.** It is written in Go. Can run commands in parallel. -* **Powerful.** With a few lines in the config you can check only the changed files on `pre-push` hook. -* **Simple.** It is single dependency-free binary which can work in any environment. - -📖 [Read the introduction post](https://evilmartians.com/chronicles/lefthook-knock-your-teams-code-back-into-shape?utm_source=lefthook) - -```yml -# On `git push` lefthook will run spelling and links check for all of the changed files -pre-push: - parallel: true - commands: - spelling: - files: git diff --name-only HEAD @{push} - glob: "*.md" - run: npx yaspeller {files} - check-links: - files: git diff --name-only HEAD @{push} - glob: "*.md" - run: npx markdown-link-check {files} -``` - - -Sponsored by Evil Martians - -## Usage - -Choose your environment: - -* **[Node.js](./docs/node.md)** -* **[Ruby](./docs/ruby.md)** -* [Other environments](./docs/other.md) - -Then you can find all Lefthook features in [the full guide](./docs/full_guide.md) and explore [wiki](https://github.com/evilmartians/lefthook/wiki). - -*** - -## Why Lefthook - -* ### **Parallel execution** -If you want more speed. [Example](./docs/full_guide.md#parallel-execution) - -```yml -pre-push: - parallel: true -``` - -* ### **Flexible list of files** -If you want your own list. [Custom](./docs/full_guide.md#custom-file-list) and [prebuilt](./docs/full_guide.md#select-specific-file-groups) examples. - -```yml -pre-commit: - commands: - frontend-linter: - run: yarn eslint {staged_files} - backend-linter: - run: bundle exec rubocop --force-exclusion {all_files} - frontend-style: - files: git diff --name-only HEAD @{push} - run: yarn stylelint {files} -``` - -* ### **Glob and regexp filters** -If you want to filter list of files. - -```yml -pre-commit: - commands: - backend-linter: - glob: "*.rb" # glob filter - exclude: "application.rb|routes.rb" # regexp filter - run: bundle exec rubocop --force-exclusion {all_files} -``` - -* ### **Execute in sub-directory** -If you want to execute the commands in a relative path - -```yml -pre-commit: - commands: - backend-linter: - root: "api/" # Careful to have only trailing slash - glob: "*.rb" # glob filter - run: bundle exec rubocop {all_files} -``` - -* ### **Run scripts** - -If oneline commands are not enough, you can execute files. [Example](./docs/full_guide.md#bash-script-example). - -```yml -commit-msg: - scripts: - "template_checker": - runner: bash -``` - -* ### **Tags** -If you want to control a group of commands. [Example](./docs/full_guide.md#skipping-commands-by-tags). - -```yml -pre-push: - commands: - packages-audit: - tags: frontend security - run: yarn audit - gems-audit: - tags: backend security - run: bundle audit -``` - -* ### **Support Docker** - -If you are in the Docker environment. [Example](./docs/full_guide.md#referencing-commands-from-lefthookyml). - -```yml -pre-commit: - scripts: - "good_job.js": - runner: docker run -it --rm {cmd} -``` - -* ### **Local config** - -If you a frontend/backend developer and want to skip unnecessary commands or override something into Docker. [Description](./docs/full_guide.md#local-config). - -```yml -# lefthook-local.yml -pre-push: - exclude_tags: - - frontend - commands: - packages-audit: - skip: true -``` - -* ### **Direct control** - -If you want to run hooks group directly. - -```bash -$ lefthook run pre-commit -``` - -* ### **Your own tasks** - -If you want to run specific group of commands directly. - -```yml -fixer: - commands: - ruby-fixer: - run: bundle exec rubocop --force-exclusion --safe-auto-correct {staged_files} - js-fixer: - run: yarn eslint --fix {staged_files} -``` -```bash -$ lefthook run fixer -``` - - ---- - -## Table of contents: - -### Guides -* [Node.js](./docs/node.md) -* [Ruby](./docs/ruby.md) -* [Other environments](./docs/other.md) -* [Full features guide](./docs/full_guide.md) -* [Troubleshooting](https://github.com/evilmartians/lefthook/wiki/Troubleshooting) - -### Migrate from -* [Husky](https://github.com/evilmartians/lefthook/wiki/Migration-from-husky) -* [Husky and lint-staged](https://github.com/evilmartians/lefthook/wiki/Migration-from-husky-with-lint-staged) -* [Overcommit](https://github.com/evilmartians/lefthook/wiki/Migration-from-overcommit) - -### Examples -* [Simple script](https://github.com/evilmartians/lefthook/tree/master/examples/scripts) -* [Full features](https://github.com/evilmartians/lefthook/tree/master/examples/complete) - -### Benchmarks -* [vs Overcommit](https://github.com/evilmartians/lefthook/wiki/Benchmark-lefthook-vs-overcommit) -* [vs pre-commit](https://github.com/evilmartians/lefthook/wiki/Benchmark-lefthook-vs-pre-commit) - -### Comparison list -* [vs Overcommit, Husky, pre-commit](https://github.com/evilmartians/lefthook/wiki/Comparison-with-other-solutions) - -### Articles -* [Lefthook: Knock your team’s code back into shape](https://evilmartians.com/chronicles/lefthook-knock-your-teams-code-back-into-shape?utm_source=lefthook) -* [Lefthook + Crystalball](https://evilmartians.com/chronicles/lefthook-crystalball-and-git-magic?utm_source=lefthook) -* [Keeping OSS documentation in check with docsify, Lefthook, and friends](https://evilmartians.com/chronicles/keeping-oss-documentation-in-check-with-docsify-lefthook-and-friends?utm_source=lefthook) - diff --git a/cmd/templates/hook.tmpl b/cmd/templates/hook.tmpl index 45489592..cf8972a3 100644 --- a/cmd/templates/hook.tmpl +++ b/cmd/templates/hook.tmpl @@ -17,18 +17,21 @@ call_lefthook() if lefthook{{.Extension}} -h >/dev/null 2>&1 then eval lefthook{{.Extension}} $@ - elif test -f "$dir/node_modules/@arkweid/lefthook/bin/lefthook_${osArch}_${cpuArch}/lefthook{{.Extension}}" + elif test -f "$dir/node_modules/@evilmartians/lefthook/bin/lefthook_${osArch}_${cpuArch}/lefthook{{.Extension}}" then - eval "$dir/node_modules/@arkweid/lefthook/bin/lefthook_${osArch}_${cpuArch}/lefthook{{.Extension}} $@" + eval "$dir/node_modules/@evilmartians/lefthook/bin/lefthook_${osArch}_${cpuArch}/lefthook{{.Extension}} $@" + elif test -f "$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook_${osArch}_${cpuArch}/lefthook{{.Extension}}" + then + eval "$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook_${osArch}_${cpuArch}/lefthook{{.Extension}} $@" elif bundle exec lefthook -h >/dev/null 2>&1 then bundle exec lefthook $@ elif yarn lefthook -h >/dev/null 2>&1 then yarn lefthook $@ - elif npx @arkweid/lefthook -h >/dev/null 2>&1 + elif npx @evilmartians/lefthook -h >/dev/null 2>&1 then - npx @arkweid/lefthook $@ + npx @evilmartians/lefthook $@ else echo "Can't find lefthook in PATH" fi diff --git a/docs/full_guide.md b/docs/full_guide.md index b77d9005..18645384 100644 --- a/docs/full_guide.md +++ b/docs/full_guide.md @@ -10,18 +10,30 @@ go get github.com/evilmartians/lefthook ### npm or yarn -```bash -npm i @arkweid/lefthook --save-dev -# or yarn: -yarn add -D @arkweid/lefthook -``` +Lefthook is available on NPM in two flavors: + + 1. [@evilmartians/lefthook](https://www.npmjs.com/package/@evilmartians/lefthook) with pre-bundled binaries for all architectures: + + ```bash + npm install @evilmartians/lefthook --save-dev + # or yarn: + yarn add -D @evilmartians/lefthook + ``` + + 2. [@evilmartians/lefthook-installer](https://www.npmjs.com/package/@evilmartians/lefthook-installer) that wil fetch binary file on installation: + + ```bash + npm install @evilmartians/lefthook-installer --save-dev + # or yarn: + yarn add -D @evilmartians/lefthook-installer + ``` NOTE: if you install it this way you should call it with `npx` or `yarn` for all listed examples below. (for example: `lefthook install` -> `npx lefthook install`) You can also install lefthook as a global dependency ```bash -npm install -g @arkweid/lefthook +npm install -g @evilmartians/lefthook ``` diff --git a/docs/node.md b/docs/node.md index 23730e1b..8e152353 100644 --- a/docs/node.md +++ b/docs/node.md @@ -4,14 +4,23 @@ This is guide of using Lefthook git hook manager in Node.js projects. You can fi ## Install -Lefthook is [available on npm](https://www.npmjs.com/package/@arkweid/lefthook): +Lefthook is available on NPM in two flavors: -```bash -npm install @arkweid/lefthook --save-dev -# or yarn: -yarn add -D @arkweid/lefthook -``` + 1. [@evilmartians/lefthook](https://www.npmjs.com/package/@evilmartians/lefthook) with pre-bundled binaries for all architectures: + + ```bash + npm install @evilmartians/lefthook --save-dev + # or yarn: + yarn add -D @evilmartians/lefthook + ``` + + 2. [@evilmartians/lefthook-installer](https://www.npmjs.com/package/@evilmartians/lefthook) that wil fetch binary file on installation: + ```bash + npm install @evilmartians/lefthook-installer --save-dev + # or yarn: + yarn add -D @evilmartians/lefthook-installer + ``` ## Edit @@ -33,7 +42,7 @@ pre-commit: ## Test it ```bash -npx @arkweid/lefthook install && npx @arkweid/lefthook run pre-commit +npx @evilmartians/lefthook install && npx @evilmartians/lefthook run pre-commit ``` ### More info diff --git a/packaging/npm-bundled/bin/index.js b/packaging/npm-bundled/bin/index.js new file mode 100644 index 00000000..2e64e83e --- /dev/null +++ b/packaging/npm-bundled/bin/index.js @@ -0,0 +1,17 @@ +#!/usr/bin/env node + +var spawn = require('child_process').spawn; +const { getExePath } = require('../get-exe'); + +var command_args = process.argv.slice(2); + +var child = spawn( + getExePath(), + command_args, + { stdio: "inherit" }); + +child.on('close', function (code) { + if (code !== 0) { + process.exit(1); + } +}); diff --git a/packaging/npm-bundled/get-exe.js b/packaging/npm-bundled/get-exe.js new file mode 100644 index 00000000..217578ba --- /dev/null +++ b/packaging/npm-bundled/get-exe.js @@ -0,0 +1,36 @@ +const path = require("path") + +function getExePath() { + // Detect OS + // https://nodejs.org/api/process.html#process_process_platform + let goOS = process.platform; + let extension = ''; + if (['win32', 'cygwin'].includes(process.platform)) { + goOS = 'windows'; + extension = '.exe'; + } + + // Detect architecture + // https://nodejs.org/api/process.html#process_process_arch + let goArch = process.arch; + switch (process.arch) { + case 'x64': { + goArch = 'amd64'; + break; + } + case 'x32': + case 'ia32': { + goArch = '386'; + break; + } + } + + const dir = path.join(__dirname, 'bin'); + const executable = path.join( + dir, + `lefthook_${goOS}_${goArch}`, + `lefthook${extension}` + ); + return executable; +} +exports.getExePath = getExePath; diff --git a/packaging/npm-bundled/package.json b/packaging/npm-bundled/package.json new file mode 100644 index 00000000..6a396539 --- /dev/null +++ b/packaging/npm-bundled/package.json @@ -0,0 +1,35 @@ +{ + "name": "@evilmartians/lefthook", + "version": "0.7.7", + "description": "Simple git hooks manager", + "main": "index.js", + "bin": { + "lefthook": "./bin/index.js" + }, + "repository": "https://github.com/evilmartians/lefthook", + "keywords": [ + "git", + "hook", + "manager" + ], + "author": "Arkweid", + "license": "MIT", + "bugs": { + "url": "https://github.com/evilmartians/lefthook/issues" + }, + "homepage": "https://github.com/evilmartians/lefthook#readme", + "os": [ + "darwin", + "linux", + "win32" + ], + "cpu": [ + "x64", + "arm64", + "ia32" + ], + "scripts": { + "version": "git clean -fd bin/ && (cd ../../dist/ && find . -executable -type f -exec cp --parents \\{\\} ../packaging/npm-bundled/bin/ \\;) && cp -f ../../README.md ./", + "postinstall": "node postinstall.js" + } +} diff --git a/packaging/npm-bundled/postinstall.js b/packaging/npm-bundled/postinstall.js new file mode 100644 index 00000000..2300daea --- /dev/null +++ b/packaging/npm-bundled/postinstall.js @@ -0,0 +1,10 @@ +if (!process.env.CI) { + const { spawnSync } = require('child_process'); + const { getExePath } = require('./get-exe'); + + // run install + spawnSync(getExePath(), ['install', '-f'], { + cwd: process.env.INIT_CWD || process.cwd(), + stdio: 'inherit', + }); +} diff --git a/.npm/bin/index.js b/packaging/npm-installer/bin/index.js similarity index 100% rename from .npm/bin/index.js rename to packaging/npm-installer/bin/index.js diff --git a/.npm/install.js b/packaging/npm-installer/install.js similarity index 100% rename from .npm/install.js rename to packaging/npm-installer/install.js diff --git a/.npm/package.json b/packaging/npm-installer/package.json similarity index 88% rename from .npm/package.json rename to packaging/npm-installer/package.json index 0329b0c7..2aa0b192 100644 --- a/.npm/package.json +++ b/packaging/npm-installer/package.json @@ -1,5 +1,5 @@ { - "name": "@arkweid/lefthook", + "name": "@evilmartians/lefthook-installer", "version": "0.7.7", "description": "Simple git hooks manager", "main": "index.js", @@ -28,6 +28,7 @@ "arm64" ], "scripts": { + "version": "cp -f ../../README.md ./", "install": "node install.js" }, "dependencies": { diff --git a/.rubygems/Gemfile b/packaging/rubygems/Gemfile similarity index 100% rename from .rubygems/Gemfile rename to packaging/rubygems/Gemfile diff --git a/.rubygems/README.md b/packaging/rubygems/README.md similarity index 100% rename from .rubygems/README.md rename to packaging/rubygems/README.md diff --git a/.rubygems/Rakefile b/packaging/rubygems/Rakefile similarity index 100% rename from .rubygems/Rakefile rename to packaging/rubygems/Rakefile diff --git a/.rubygems/bin/lefthook b/packaging/rubygems/bin/lefthook similarity index 100% rename from .rubygems/bin/lefthook rename to packaging/rubygems/bin/lefthook diff --git a/.rubygems/lefthook.gemspec b/packaging/rubygems/lefthook.gemspec similarity index 100% rename from .rubygems/lefthook.gemspec rename to packaging/rubygems/lefthook.gemspec diff --git a/.rubygems/lib/lefthook.rb b/packaging/rubygems/lib/lefthook.rb similarity index 100% rename from .rubygems/lib/lefthook.rb rename to packaging/rubygems/lib/lefthook.rb diff --git a/.rubygems/libexec/.keep b/packaging/rubygems/libexec/.keep similarity index 100% rename from .rubygems/libexec/.keep rename to packaging/rubygems/libexec/.keep diff --git a/spec/fixtures/pre-commit b/spec/fixtures/pre-commit index fe9702ca..93d32392 100644 --- a/spec/fixtures/pre-commit +++ b/spec/fixtures/pre-commit @@ -15,9 +15,9 @@ call_lefthook() if lefthook -h >/dev/null 2>&1 then eval lefthook $@ - elif test -f "$dir/node_modules/@arkweid/lefthook/bin/lefthook" + elif test -f "$dir/node_modules/@evilmartians/lefthook/bin/lefthook" then - eval "$dir/node_modules/@arkweid/lefthook/bin/lefthook $@" + eval "$dir/node_modules/@evilmartians/lefthook/bin/lefthook $@" elif bundle exec lefthook -h >/dev/null 2>&1 then bundle exec lefthook $@ diff --git a/spec/fixtures/pre-push b/spec/fixtures/pre-push index e855c935..9459d6bf 100644 --- a/spec/fixtures/pre-push +++ b/spec/fixtures/pre-push @@ -15,9 +15,9 @@ call_lefthook() if lefthook -h >/dev/null 2>&1 then eval lefthook $@ - elif test -f "$dir/node_modules/@arkweid/lefthook/bin/lefthook" + elif test -f "$dir/node_modules/@evilmartians/lefthook/bin/lefthook" then - eval "$dir/node_modules/@arkweid/lefthook/bin/lefthook $@" + eval "$dir/node_modules/@evilmartians/lefthook/bin/lefthook $@" elif bundle exec lefthook -h >/dev/null 2>&1 then bundle exec lefthook $@