diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..3c4e9f0 --- /dev/null +++ b/.clang-format @@ -0,0 +1,89 @@ +# From https://github.com/man-group/sparrow with sparrow-specific regexes removed. + +BasedOnStyle: Mozilla + +AccessModifierOffset: '-4' +AlignAfterOpenBracket: BlockIndent +AlignEscapedNewlines: Left +AllowAllArgumentsOnNextLine: false +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: false +AllowShortIfStatementsOnASingleLine: false +# Forbid one line lambdas because clang-format makes a weird split when +# single instructions lambdas are too long. +AllowShortLambdasOnASingleLine: Empty +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakTemplateDeclarations: Yes +BinPackArguments: false +BinPackParameters: false +BreakBeforeBinaryOperators: NonAssignment +BreakBeforeBraces: Allman +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: BeforeComma +BreakInheritanceList: AfterComma +BreakStringLiterals: false +ColumnLimit: '110' +ConstructorInitializerIndentWidth: '4' +ContinuationIndentWidth: '4' +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +EmptyLineAfterAccessModifier: Always +EmptyLineBeforeAccessModifier: Always +ExperimentalAutoDetectBinPacking: true +IncludeBlocks: Regroup +IncludeCategories: +- Regex: <[^.]+> + Priority: 1 +- Regex: <.+> + Priority: 2 +- Regex: '".+"' + Priority: 5 +IndentCaseLabels: true +IndentPPDirectives: AfterHash +IndentWidth: '4' +IndentWrappedFunctionNames: false +InsertBraces: true +InsertTrailingCommas: Wrapped +KeepEmptyLinesAtTheStartOfBlocks: false +LambdaBodyIndentation: Signature +Language: Cpp +MaxEmptyLinesToKeep: '2' +NamespaceIndentation: All +ObjCBlockIndentWidth: '4' +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: false +PackConstructorInitializers: Never +PenaltyBreakAssignment: 100000 +PenaltyBreakBeforeFirstCallParameter: 0 +PenaltyBreakComment: 10 +PenaltyBreakOpenParenthesis: 0 +PenaltyBreakTemplateDeclaration: 0 +PenaltyExcessCharacter: 10 +PenaltyIndentedWhitespace: 0 +PenaltyReturnTypeOnItsOwnLine: 10 +PointerAlignment: Left +QualifierAlignment: Custom # Experimental +QualifierOrder: [inline, static, constexpr, const, volatile, type] +ReflowComments: true +SeparateDefinitionBlocks: Always +SortIncludes: CaseInsensitive +SortUsingDeclarations: true +SpaceAfterCStyleCast: true +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: '2' +SpacesInAngles: false +SpacesInCStyleCastParentheses: false +SpacesInContainerLiterals: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: c++20 +TabWidth: '4' +UseTab: Never diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..cc84447 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,31 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v6.0.0 + hooks: + - id: check-merge-conflict + - id: check-toml + - id: check-yaml + - id: debug-statements + - id: end-of-file-fixer + - id: mixed-line-ending + - id: trailing-whitespace + + - repo: https://github.com/asottile/pyupgrade + rev: v3.21.2 + hooks: + - id: pyupgrade + args: ['--py312-plus'] + + - repo: https://github.com/pre-commit/mirrors-clang-format + rev: v21.1.2 + hooks: + - id: clang-format + args: [--style=file] + exclude_types: [javascript,json] + + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.14.0 + hooks: + - id: ruff-check + args: [--fix] + - id: ruff-format diff --git a/README.md b/README.md index 9eff6b3..4ac0793 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,12 @@ The CLI is tested using `python`. From the top-level directory: pytest -v ``` +`pre-commit` runs automatically on `git commit`. To run it manually use: + +```bash +pre-commit run --all-files +``` + # WebAssembly build and deployment The `wasm` directory contains everything needed to build the local `git2cpp` source code as an diff --git a/dev-environment.yml b/dev-environment.yml index c578ec0..288a620 100644 --- a/dev-environment.yml +++ b/dev-environment.yml @@ -6,6 +6,7 @@ dependencies: - libgit2 - cmake - pkg-config + - pre-commit - python - pytest - termcolor-cpp diff --git a/docs/create_markdown.py b/docs/create_markdown.py index 7cb59fe..0c7bec2 100644 --- a/docs/create_markdown.py +++ b/docs/create_markdown.py @@ -26,7 +26,7 @@ def sanitise_line(line): return line -# Process a single subcommand, adding new subcommands found to to_process. +# Process a single subcommand, adding new subcommands found to to_process. def process(args, to_process): cmd = args + ["--help"] cmd_string = " ".join(cmd) @@ -37,7 +37,7 @@ def process(args, to_process): p = subprocess.run(cmd, capture_output=True, text=True, check=True) # Write output markdown file, identifying subcommands at the same time to provide - # links to the subcommand markdown files. + # links to the subcommand markdown files. subcommands = [] with open(filename, "w") as f: f.write(f"({filename})=\n") # Target for links. @@ -52,7 +52,9 @@ def process(args, to_process): if match: subcommand = match.group(2) subcommand_filename = get_filename(args + [subcommand]) - line = match.group(1) + f"[{subcommand}]({subcommand_filename})" + match.group(3) + line = ( + match.group(1) + f"[{subcommand}]({subcommand_filename})" + match.group(3) + ) subcommands.append(subcommand) elif line.startswith("SUBCOMMANDS:"): in_subcommand_section = True @@ -74,10 +76,10 @@ def process(args, to_process): if __name__ == "__main__": - # Modify the PATH so that git2cpp is found by name, as using a full path will cause the help + # Modify the PATH so that git2cpp is found by name, as using a full path will cause the help # pages to write that full path. - git2cpp_dir = Path(__file__).parent.parent / 'build' - os.environ["PATH"] = f'{git2cpp_dir}{os.pathsep}{os.environ["PATH"]}' + git2cpp_dir = Path(__file__).parent.parent / "build" + os.environ["PATH"] = f"{git2cpp_dir}{os.pathsep}{os.environ['PATH']}" to_process = [["git2cpp"]] while len(to_process) > 0: diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..90d4005 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,6 @@ +# This is not a python project but it contains python tests so here are settings for python linting. +[tool.ruff] +line-length = 100 +target-version = "py312" +[tool.ruff.format] +line-ending = "lf" diff --git a/src/main.cpp b/src/main.cpp index 5d0223a..712885e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,10 +1,9 @@ -#include #include -#include // For version number only #include -#include "utils/git_exception.hpp" -#include "version.hpp" +#include +#include // For version number only + #include "subcommand/add_subcommand.hpp" #include "subcommand/branch_subcommand.hpp" #include "subcommand/checkout_subcommand.hpp" @@ -21,12 +20,14 @@ #include "subcommand/rebase_subcommand.hpp" #include "subcommand/remote_subcommand.hpp" #include "subcommand/reset_subcommand.hpp" +#include "subcommand/revlist_subcommand.hpp" +#include "subcommand/revparse_subcommand.hpp" +#include "subcommand/rm_subcommand.hpp" #include "subcommand/stash_subcommand.hpp" #include "subcommand/status_subcommand.hpp" #include "subcommand/tag_subcommand.hpp" -#include "subcommand/revparse_subcommand.hpp" -#include "subcommand/revlist_subcommand.hpp" -#include "subcommand/rm_subcommand.hpp" +#include "utils/git_exception.hpp" +#include "version.hpp" int main(int argc, char** argv) { @@ -69,7 +70,8 @@ int main(int argc, char** argv) if (version->count()) { - std::cout << "git2cpp version " << GIT2CPP_VERSION_STRING << " (libgit2 " << LIBGIT2_VERSION << ")" << std::endl; + std::cout << "git2cpp version " << GIT2CPP_VERSION_STRING << " (libgit2 " << LIBGIT2_VERSION + << ")" << std::endl; } else if (app.get_subcommands().size() == 0) { @@ -86,7 +88,8 @@ int main(int argc, char** argv) std::cerr << e.what() << std::endl; exit_code = e.error_code(); } - catch (std::exception& e) { + catch (std::exception& e) + { std::cerr << e.what() << std::endl; exit_code = 1; } diff --git a/src/subcommand/add_subcommand.cpp b/src/subcommand/add_subcommand.cpp index e1aa4f4..ca52940 100644 --- a/src/subcommand/add_subcommand.cpp +++ b/src/subcommand/add_subcommand.cpp @@ -1,13 +1,13 @@ +#include "add_subcommand.hpp" + #include -#include "add_subcommand.hpp" #include "../wrapper/index_wrapper.hpp" #include "../wrapper/repository_wrapper.hpp" - add_subcommand::add_subcommand(const libgit2_object&, CLI::App& app) { - auto *sub = app.add_subcommand("add", "Add file contents to the index"); + auto* sub = app.add_subcommand("add", "Add file contents to the index"); sub->add_option("", m_add_files, "Files to add"); @@ -16,10 +16,14 @@ add_subcommand::add_subcommand(const libgit2_object&, CLI::App& app) // sub->add_flag("-u,--update", update_flag, ""); // sub->add_flag("-v,--verbose", verbose_flag, ""); - sub->callback([this]() { this->run(); }); + sub->callback( + [this]() + { + this->run(); + } + ); }; - void add_subcommand::run() { auto directory = get_current_git_path(); diff --git a/src/subcommand/add_subcommand.hpp b/src/subcommand/add_subcommand.hpp index 6f31dff..0504799 100644 --- a/src/subcommand/add_subcommand.hpp +++ b/src/subcommand/add_subcommand.hpp @@ -12,6 +12,7 @@ class add_subcommand void run(); private: + bool m_all_flag = false; std::vector m_add_files; }; diff --git a/src/subcommand/branch_subcommand.cpp b/src/subcommand/branch_subcommand.cpp index f0ea9fa..3d233c4 100644 --- a/src/subcommand/branch_subcommand.cpp +++ b/src/subcommand/branch_subcommand.cpp @@ -1,6 +1,7 @@ +#include "../subcommand/branch_subcommand.hpp" + #include -#include "../subcommand/branch_subcommand.hpp" #include "../wrapper/repository_wrapper.hpp" branch_subcommand::branch_subcommand(const libgit2_object&, CLI::App& app) @@ -14,9 +15,18 @@ branch_subcommand::branch_subcommand(const libgit2_object&, CLI::App& app) sub->add_flag("-r,--remotes", m_remote_flag, "List or delete (if used with -d) the remote-tracking branches"); sub->add_flag("-l,--list", m_list_flag, "List branches"); sub->add_flag("-f,--force", m_force_flag, "Skips confirmation"); - sub->add_flag("--show-current", m_show_current_flag, "Print the name of the current branch. In detached HEAD state, nothing is printed."); + sub->add_flag( + "--show-current", + m_show_current_flag, + "Print the name of the current branch. In detached HEAD state, nothing is printed." + ); - sub->callback([this]() { this->run(); }); + sub->callback( + [this]() + { + this->run(); + } + ); } void branch_subcommand::run() diff --git a/src/subcommand/checkout_subcommand.cpp b/src/subcommand/checkout_subcommand.cpp index d3477a3..1c3dfdb 100644 --- a/src/subcommand/checkout_subcommand.cpp +++ b/src/subcommand/checkout_subcommand.cpp @@ -1,8 +1,9 @@ +#include "../subcommand/checkout_subcommand.hpp" + #include -#include #include +#include -#include "../subcommand/checkout_subcommand.hpp" #include "../subcommand/status_subcommand.hpp" #include "../utils/git_exception.hpp" #include "../wrapper/repository_wrapper.hpp" @@ -15,9 +16,18 @@ checkout_subcommand::checkout_subcommand(const libgit2_object&, CLI::App& app) sub->add_option("", m_branch_name, "Branch to checkout"); sub->add_flag("-b", m_create_flag, "Create a new branch before checking it out"); sub->add_flag("-B", m_force_create_flag, "Create a new branch or reset it if it exists before checking it out"); - sub->add_flag("-f, --force", m_force_checkout_flag, "When switching branches, proceed even if the index or the working tree differs from HEAD, and even if there are untracked files in the way"); - - sub->callback([this]() { this->run(); }); + sub->add_flag( + "-f, --force", + m_force_checkout_flag, + "When switching branches, proceed even if the index or the working tree differs from HEAD, and even if there are untracked files in the way" + ); + + sub->callback( + [this]() + { + this->run(); + } + ); } void print_no_switch(status_list_wrapper& sl) @@ -44,7 +54,7 @@ void checkout_subcommand::run() if (repo.state() != GIT_REPOSITORY_STATE_NONE) { - throw std::runtime_error("Cannot checkout, repository is in unexpected state"); + throw std::runtime_error("Cannot checkout, repository is in unexpected state"); } git_checkout_options options; @@ -112,19 +122,14 @@ void checkout_subcommand::run() } } -annotated_commit_wrapper checkout_subcommand::create_local_branch -( - repository_wrapper& repo, - const std::string_view target_name, - bool force -) +annotated_commit_wrapper +checkout_subcommand::create_local_branch(repository_wrapper& repo, const std::string_view target_name, bool force) { auto branch = repo.create_branch(target_name, force); return repo.find_annotated_commit(branch); } -void checkout_subcommand::checkout_tree -( +void checkout_subcommand::checkout_tree( const repository_wrapper& repo, const annotated_commit_wrapper& target_annotated_commit, const std::string_view target_name, @@ -135,8 +140,7 @@ void checkout_subcommand::checkout_tree throw_if_error(git_checkout_tree(repo, target_commit, &options)); } -void checkout_subcommand::update_head -( +void checkout_subcommand::update_head( repository_wrapper& repo, const annotated_commit_wrapper& target_annotated_commit, const std::string_view target_name diff --git a/src/subcommand/checkout_subcommand.hpp b/src/subcommand/checkout_subcommand.hpp index e041174..99661d4 100644 --- a/src/subcommand/checkout_subcommand.hpp +++ b/src/subcommand/checkout_subcommand.hpp @@ -17,23 +17,17 @@ class checkout_subcommand private: - annotated_commit_wrapper create_local_branch - ( - repository_wrapper& repo, - const std::string_view target_name, - bool force - ); + annotated_commit_wrapper + create_local_branch(repository_wrapper& repo, const std::string_view target_name, bool force); - void checkout_tree - ( + void checkout_tree( const repository_wrapper& repo, const annotated_commit_wrapper& target_annotated_commit, const std::string_view target_name, const git_checkout_options& options ); - void update_head - ( + void update_head( repository_wrapper& repo, const annotated_commit_wrapper& target_annotated_commit, const std::string_view target_name diff --git a/src/subcommand/clone_subcommand.cpp b/src/subcommand/clone_subcommand.cpp index 926628e..4d8ad08 100644 --- a/src/subcommand/clone_subcommand.cpp +++ b/src/subcommand/clone_subcommand.cpp @@ -1,6 +1,7 @@ +#include "../subcommand/clone_subcommand.hpp" + #include -#include "../subcommand/clone_subcommand.hpp" #include "../utils/credentials.hpp" #include "../utils/input_output.hpp" #include "../utils/progress.hpp" @@ -13,11 +14,17 @@ clone_subcommand::clone_subcommand(const libgit2_object&, CLI::App& app) sub->add_option("", m_repository, "The (possibly remote) repository to clone from.")->required(); sub->add_option("", m_directory, "The name of a new directory to clone into."); sub->add_option("--depth", m_depth, "Create a shallow clone of that depth."); - // sub->add_option("--shallow-since", m_shallow_since, "