diff --git a/.githooks/pre-commit b/.githooks/pre-commit new file mode 100755 index 0000000..143618d --- /dev/null +++ b/.githooks/pre-commit @@ -0,0 +1,17 @@ +#!/bin/bash + +set -e + +echo 'Run clippy ...' +# Make cargo clippy fail on warnings by setting `-D warnings` +cargo clippy -- -D warnings + +echo 'Run rustfmt ...' + +RUSTFMT_CONFIG="group_imports=StdExternalCrate,imports_granularity=Crate" + +# Apply formatting to modified Rust files and stage them +for rust_file in $(git diff --name-only --staged | grep ".*\.rs$"); do + rustfmt +nightly --config $RUSTFMT_CONFIG $rust_file + git add $rust_file +done diff --git a/.gitignore b/.gitignore index d9c690a..1c757c8 100644 --- a/.gitignore +++ b/.gitignore @@ -17,5 +17,6 @@ # End of https://www.gitignore.io/api/rust *.sublime-workspace +.vscode notes.md .DS_Store diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml deleted file mode 100644 index 7a2ce11..0000000 --- a/.pre-commit-config.yaml +++ /dev/null @@ -1,6 +0,0 @@ -repos: -- repo: https://github.com/doublify/pre-commit-rust - rev: master - hooks: - - id: clippy - - id: fmt diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 19e89b1..0000000 --- a/.travis.yml +++ /dev/null @@ -1,10 +0,0 @@ -language: rust -rust: - - stable - - beta - - nightly - - 1.48.0 -jobs: - allow_failures: - - rust: nightly - fast_finish: true diff --git a/Cargo.lock b/Cargo.lock index c3697c9..dfb0e6d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -68,7 +68,7 @@ checksum = "93ae1ddd39efd67689deb1979d80bad3bf7f2b09c6e6117c8d1f2443b5e2f83e" dependencies = [ "bstr", "doc-comment", - "predicates", + "predicates 2.1.1", "predicates-core", "predicates-tree", "wait-timeout", @@ -128,7 +128,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.61", + "syn", ] [[package]] @@ -176,6 +176,107 @@ dependencies = [ "num-traits", ] +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + [[package]] name = "hashbrown" version = "0.11.2" @@ -200,9 +301,9 @@ dependencies = [ [[package]] name = "indoc" -version = "1.0.7" +version = "2.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adab1eaa3408fb7f0c777a73e7465fd5656136fc93b670eb6df3c88c2c1344e3" +checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5" [[package]] name = "is_terminal_polyfill" @@ -219,6 +320,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -262,15 +372,38 @@ dependencies = [ "indexmap", ] +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "predicates" version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a5aab5be6e4732b473071984b3164dbbfb7a3674d30ea5ff44410b6bcd960c3c" dependencies = [ + "difflib", + "itertools 0.10.5", + "predicates-core", +] + +[[package]] +name = "predicates" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b87bfd4605926cdfefc1c3b5f8fe560e3feca9d5552cf68c466d3d8236c7e8" +dependencies = [ + "anstyle", "difflib", "float-cmp", - "itertools", "normalize-line-endings", "predicates-core", "regex", @@ -312,9 +445,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.5.6" +version = "1.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1" +checksum = "8b1f693b24f6ac912f4893ef08244d70b6067480d2f1a46e950c9691e6749d1d" dependencies = [ "aho-corasick", "memchr", @@ -329,21 +462,43 @@ checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" [[package]] name = "regex-syntax" -version = "0.6.26" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "relative-path" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" +checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" [[package]] name = "rstest" -version = "0.12.0" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5316d2a1479eeef1ea21e7f9ddc67c191d497abc8fc3ba2467857abbb68330" +dependencies = [ + "futures", + "futures-timer", + "rstest_macros", + "rustc_version", +] + +[[package]] +name = "rstest_macros" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d912f35156a3f99a66ee3e11ac2e0b3f34ac85a07e05263d05a7e2c8810d616f" +checksum = "04a9df72cc1f67020b0d63ad9bfe4a323e459ea7eb68e03bd9824db49f9a4c25" dependencies = [ "cfg-if", + "glob", "proc-macro2", "quote", + "regex", + "relative-path", "rustc_version", - "syn 1.0.82", + "syn", + "unicode-ident", ] [[package]] @@ -362,21 +517,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012" [[package]] -name = "strsim" -version = "0.11.1" +name = "slab" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] [[package]] -name = "syn" -version = "1.0.82" +name = "strsim" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" @@ -412,7 +565,7 @@ checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524" dependencies = [ "proc-macro2", "quote", - "syn 2.0.61", + "syn", ] [[package]] @@ -422,10 +575,10 @@ dependencies = [ "assert_cmd", "clap", "indoc", - "itertools", + "itertools 0.13.0", "lazy_static", "petgraph", - "predicates", + "predicates 3.1.0", "rstest", "thiserror", ] @@ -436,12 +589,6 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" -[[package]] -name = "unicode-xid" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" - [[package]] name = "utf8parse" version = "0.2.1" diff --git a/Cargo.toml b/Cargo.toml index 6ba7ad4..c5b28ab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,13 +16,13 @@ rust-version = "1.74" [dependencies] clap = {version = "4.3", features = ["derive"] } -itertools = "0.10" +itertools = "0.13" lazy_static = "1.4" petgraph = "0.6" thiserror = "1.0.58" [dev-dependencies] assert_cmd = "2.0" -indoc = "1.0" -predicates = "2" -rstest = "0.12" +indoc = "2.0" +predicates = "3.1" +rstest = "0.19" diff --git a/README.md b/README.md index 7526ebe..32f2296 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,20 @@ `ukebox` is a ukulele chord toolbox for the command line written in Rust. +## Table of contents + +- [Features](#features) +- [Installation](#installation) +- [Usage](#usage) + - [Chord chart lookup](#chord-chart-lookup) + - [Chord name lookup](#chord-name-lookup) + - [Voice leading](#voice-leading) +- [Supported chord types](#supported-chord-types) +- [Development](#development) + - [Pre-commit hooks](#pre-commit-hooks) +- [License](#license) +- [Contribution](#contribution) + ## Features * shows you how to play a given chord on a ukulele by printing a **chord chart** in ASCII art @@ -329,6 +343,24 @@ C added 9th - Cadd9, Cadd2 C added 4th - Cadd4 ``` +## Development + +### Pre-commit hooks + +To automatically enforce coding conventions, Git hooks can simplify the process. Pre-commit hooks run before each commit, checking conditions or modifying files (e.g., using rustfmt to format code). The .githooks folder contains a pre-commit script that runs the Rust linter clippy and formats the code with rustfmt. You need to install these tools and configure Git to use the hooks in .githooks. + +``` +$ rustup component add clippy +$ rustup component add rustfmt +$ git config core.hooksPath .githooks +``` + +Now, the hooks will run every time you commit. If a problem is found, the commit process is aborted with a message. Resolve clippy warnings manually, add changed files with git add, and rerun git commit until no errors remain. + +To ignore clippy lints for specific blocks, use #[allow(LINT_NAME)], or globally with #![allow(LINT_NAME)] at the top of lib.rs. Prevent rustfmt from formatting a block by adding #[rustfmt::skip]. + +To bypass pre-commit hooks for a commit, add the -n option to git commit. + ## License Licensed under either of diff --git a/src/chord.rs b/src/chord.rs index 8036dc6..1ff374d 100644 --- a/src/chord.rs +++ b/src/chord.rs @@ -1,7 +1,9 @@ -use std::convert::TryFrom; -use std::fmt; -use std::ops::{Add, Sub}; -use std::str::FromStr; +use std::{ + convert::TryFrom, + fmt, + ops::{Add, Sub}, + str::FromStr, +}; use itertools::Itertools; diff --git a/src/chord_chart.rs b/src/chord_chart.rs index 428b51e..88bd90b 100644 --- a/src/chord_chart.rs +++ b/src/chord_chart.rs @@ -1,6 +1,4 @@ -use std::cmp::max; -use std::fmt; -use std::fmt::Write; +use std::{cmp::max, fmt, fmt::Write}; use crate::{FretID, Semitones, UkeString, Voicing, MIN_CHART_WIDTH}; diff --git a/src/chord_sequence.rs b/src/chord_sequence.rs index f49d254..059fc7b 100644 --- a/src/chord_sequence.rs +++ b/src/chord_sequence.rs @@ -1,5 +1,4 @@ -use std::slice::Iter; -use std::str::FromStr; +use std::{slice::Iter, str::FromStr}; use crate::Chord; diff --git a/src/chord_type.rs b/src/chord_type.rs index 0911848..e05ca47 100644 --- a/src/chord_type.rs +++ b/src/chord_type.rs @@ -1,7 +1,4 @@ -use std::cmp::min; -use std::convert::TryFrom; -use std::fmt; -use std::str::FromStr; +use std::{cmp::min, convert::TryFrom, fmt, str::FromStr}; use crate::{Interval, PitchClass, PITCH_CLASS_COUNT, STRING_COUNT}; diff --git a/src/distance.rs b/src/distance.rs index 258906a..090b0a6 100644 --- a/src/distance.rs +++ b/src/distance.rs @@ -1,5 +1,4 @@ -use std::iter::Sum; -use std::ops::Add; +use std::{iter::Sum, ops::Add}; #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] /// The distance between two voicings combining semitone distance diff --git a/src/fingering.rs b/src/fingering.rs index ae28200..a6b39ad 100644 --- a/src/fingering.rs +++ b/src/fingering.rs @@ -66,9 +66,8 @@ impl From for Fingering { mod tests { use rstest::rstest; - use crate::{FretID, Tuning, STRING_COUNT}; - use super::*; + use crate::{FretID, Tuning, STRING_COUNT}; #[rstest( frets, finger_positions, diff --git a/src/fret_pattern.rs b/src/fret_pattern.rs index c70aada..3d44f51 100644 --- a/src/fret_pattern.rs +++ b/src/fret_pattern.rs @@ -1,6 +1,4 @@ -use std::convert::TryInto; -use std::slice::Iter; -use std::str::FromStr; +use std::{convert::TryInto, slice::Iter, str::FromStr}; use crate::{FretID, STRING_COUNT}; diff --git a/src/lib.rs b/src/lib.rs index 5ffe751..47b0ec0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,8 +18,7 @@ pub mod voicing_graph; pub use chord::Chord; pub use chord_chart::ChordChart; pub use chord_sequence::ChordSequence; -pub use chord_type::ChordType; -pub use chord_type::NoMatchingChordTypeFoundError; +pub use chord_type::{ChordType, NoMatchingChordTypeFoundError}; pub use distance::Distance; pub use fingering::Fingering; pub use fret_pattern::FretPattern; diff --git a/src/note.rs b/src/note.rs index a4762ff..62df237 100644 --- a/src/note.rs +++ b/src/note.rs @@ -1,6 +1,8 @@ -use std::fmt; -use std::ops::{Add, Sub}; -use std::str::FromStr; +use std::{ + fmt, + ops::{Add, Sub}, + str::FromStr, +}; use crate::{Interval, PitchClass, Semitones, StaffPosition}; diff --git a/src/tuning.rs b/src/tuning.rs index c2086d6..80155c8 100644 --- a/src/tuning.rs +++ b/src/tuning.rs @@ -1,5 +1,4 @@ -use std::fmt; -use std::str::FromStr; +use std::{fmt, str::FromStr}; use clap::ValueEnum; diff --git a/src/voicing.rs b/src/voicing.rs index 370b80d..1fba44b 100644 --- a/src/voicing.rs +++ b/src/voicing.rs @@ -1,7 +1,9 @@ -use std::cmp::{max, min, Ordering}; -use std::convert::{TryFrom, TryInto}; -use std::fmt; -use std::slice::Iter; +use std::{ + cmp::{max, min, Ordering}, + convert::{TryFrom, TryInto}, + fmt, + slice::Iter, +}; use itertools::Itertools; diff --git a/src/voicing_graph.rs b/src/voicing_graph.rs index 4150e18..9adae72 100644 --- a/src/voicing_graph.rs +++ b/src/voicing_graph.rs @@ -1,9 +1,7 @@ use std::iter::Iterator; use itertools::Itertools; -use petgraph::algo::all_simple_paths; -use petgraph::prelude::NodeIndex; -use petgraph::Graph; +use petgraph::{algo::all_simple_paths, prelude::NodeIndex, Graph}; use crate::{Chord, ChordSequence, Distance, Semitones, Voicing, VoicingConfig}; diff --git a/ukebox.sublime-project b/ukebox.sublime-project deleted file mode 100644 index 24db303..0000000 --- a/ukebox.sublime-project +++ /dev/null @@ -1,8 +0,0 @@ -{ - "folders": - [ - { - "path": "." - } - ] -}