diff --git a/.lintstagedrc.js b/.lintstagedrc.js index 21badc964..3bc13d48a 100644 --- a/.lintstagedrc.js +++ b/.lintstagedrc.js @@ -1,67 +1,69 @@ const { CLIEngine } = require('eslint'); const { getClangPaths } = require('./scripts/get_clang_paths'); +const { findRustProjectPath } = require('./scripts/get_cargo_path'); const cli = new CLIEngine({}); module.exports = { '*.{js,mjs,cjs}': function eslint(files) { // This logic is likely broken and needs to be updated. see ENG-1011 return ( 'eslint --cache --fix --max-warnings=0 ' + files.filter(file => !cli.isPathIgnored(file)).join(' ') ); }, '*.{css,html,md,json}': function prettier(files) { return 'prettier --write ' + files.join(' '); }, '*.sh': function shellCheck(files) { return 'shellcheck -x -P SCRIPTDIR ' + files.join(' '); }, 'lib/**/*.js': function libFlow(files) { return 'yarn workspace lib flow --quiet'; }, 'lib/**/*.js': function libTest(files) { return 'yarn workspace lib test'; }, '{web,lib}/**/*.js': function webFlow(files) { return 'yarn workspace web flow --quiet'; }, '{native,lib}/**/*.js': function nativeFlow(files) { return 'yarn workspace native flow --quiet'; }, '{keyserver,web,lib}/**/*.js': function keyserverFlow(files) { return 'yarn workspace keyserver flow --quiet'; }, '{keyserver,web,lib}/**/*.js': function keyserverTest(files) { return 'yarn workspace keyserver test'; }, '{landing,lib}/**/*.js': function landingFlow(files) { return 'yarn workspace landing flow --quiet'; }, '{desktop,lib}/**/*.js': function desktopFlow(files) { return 'yarn workspace desktop flow --quiet'; }, 'services/identity/**/*.rs': function testIdentity(files) { return 'bash -c "cd services/identity && cargo test"'; }, '{native,services}/**/*.{h,cpp,java,mm}': function clangFormat(files) { files = files.filter(path => { if (path.indexOf('generated') !== -1) { return false; } for (const allowedPath of getClangPaths()) { if (path.indexOf(allowedPath) !== -1) { return true; } } return false; }); return 'clang-format -i ' + files.join(' '); }, - 'services/commtest/**/*.rs': function rustFormat(files) { - return 'yarn rust-pre-commit'; + '*.rs': function rustFormat(files) { + const paths = new Set(files.map(findRustProjectPath).filter(Boolean)); + return `yarn rust-pre-commit ${Array.from(paths).join(' ')}`; }, 'services/terraform/*.tf': function checkTerraform(files) { return 'yarn terraform-pre-commit'; }, }; diff --git a/scripts/get_cargo_path.js b/scripts/get_cargo_path.js new file mode 100644 index 000000000..11f6e694d --- /dev/null +++ b/scripts/get_cargo_path.js @@ -0,0 +1,12 @@ +// @flow + +const findUp = require('find-up'); + +// finds the path to the parent directory containing a Cargo.toml file for the +// given path. Returns null if no Cargo.toml file is found. +function findRustProjectPath(path) { + const cargoTomlPath = findUp.sync('Cargo.toml', { cwd: path }); + return cargoTomlPath ? cargoTomlPath.replace('/Cargo.toml', '') : null; +} + +module.exports = { findRustProjectPath }; diff --git a/scripts/rust_pre_commit.sh b/scripts/rust_pre_commit.sh index 537bfdc9e..f3157ff3f 100755 --- a/scripts/rust_pre_commit.sh +++ b/scripts/rust_pre_commit.sh @@ -1,21 +1,25 @@ #!/usr/bin/env bash set -e # shellcheck source=/dev/null [[ -r "$HOME"/.cargo/env ]] && source "$HOME"/.cargo/env -PATHS="services/commtest" +if [[ "$#" -eq 0 ]]; then + echo "no Cargo project paths provided" + exit 1 +fi command -v cargo > /dev/null -for directory in $PATHS; do - pushd "$directory" +# iterate over all provided Cargo project paths +for directory in "$@"; do + pushd "$directory" > /dev/null echo "formatting ${directory}..." cargo fmt --all -- --check echo "checking ${directory}..." cargo check - popd # $directory + popd > /dev/null # $directory done echo "done formatting"