diff --git a/LICENSE b/LICENSE index 7fdeb68..581b690 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021 pepperkit +Copyright (c) 2023 pepperkit Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 6024b20..01f1ac6 100644 --- a/README.md +++ b/README.md @@ -5,15 +5,13 @@ [![Reliability Rating](https://sonarcloud.io/api/project_badges/measure?project=pepperkit_git-hooks-maven-plugin&metric=reliability_rating)](https://sonarcloud.io/dashboard?id=pepperkit_git-hooks-maven-plugin) [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=pepperkit_git-hooks-maven-plugin&metric=security_rating)](https://sonarcloud.io/dashboard?id=pepperkit_git-hooks-maven-plugin) -Maven plugin for easy git hooks configuration. Provides three goals to work with git hooks: -1. `initHooks` - installs configured git hooks; -2. `printHooks` - prints all or specific hooks installed at the moment, to make sure that the plugin was configured correctly; -3. `executeHooks` - executes all or specific hooks installed at the moment, to make sure that the hooks work as expected, - without the need to actually trigger the hook with git action. +Maven plugin for easy git hooks configuration. ## Usage -Add the plugin into your `pom.xml`, configure the hooks, and optionally set the execution to install the hooks each time -the project is rebuild. +Add the plugin into your `pom.xml`, configure the hooks, and set the execution to install the hooks each time +the project is rebuild. Be aware that for hooks to be installed to git, any `mvn` goal should be first executed, +like `compile` or `test`. It means that after editing git-hooks-maven-plugin configuration in `pom.xml`, +it's necessary to manually run `mvn compile` or any other maven goal, on the initializing step of which git hooks will be installed. The example with *pre-commit* and *pre-push* hooks configured, will look like it: ```xml @@ -43,13 +41,6 @@ The example with *pre-commit* and *pre-push* hooks configured, will look like it Hook's content is any command line script, which is considered successful if exit code is equal to `0`, and not otherwise. If execution of the script is successful, git action will be proceeded, if not - it will be cancelled. -Then you can execute one of the following goals manually: -1. `mvn io.github.pepperkit:git-hooks-maven-plugin:initHooks` - to manually install configured git hooks; -2. `mvn io.github.pepperkit:git-hooks-maven-plugin:printHooks` - print all the installed hooks to the console; -3. `mvn -DhookName= io.github.pepperkit:git-hooks-maven-plugin:printHooks` - print only the specified hook; -4. `mvn io.github.pepperkit:git-hooks-maven-plugin:executeHooks` - execute all the installed hooks; -5. `mvn -DhookName= io.github.pepperkit:git-hooks-maven-plugin:executeHooks` - execute only the specified hook. - ## Project's structure ``` └── src @@ -58,3 +49,5 @@ Then you can execute one of the following goals manually: └── system-test # system tests └── resources # system tests scenarios and pre-configured pom files needed for the tests ``` + +More about pepperkit projects could be found on its website: https://pepperkit.github.io/ \ No newline at end of file diff --git a/pom.xml b/pom.xml index bf6bdd7..1a83f6f 100644 --- a/pom.xml +++ b/pom.xml @@ -111,7 +111,7 @@ org.mockito mockito-core - 5.3.0 + 5.4.0 test @@ -210,7 +210,6 @@ ${checkstyle.url} - UTF-8 true true false diff --git a/src/main/java/io/github/pepperkit/githooks/GitHooksManager.java b/src/main/java/io/github/pepperkit/githooks/GitHooksManager.java index e750d97..1becf58 100644 --- a/src/main/java/io/github/pepperkit/githooks/GitHooksManager.java +++ b/src/main/java/io/github/pepperkit/githooks/GitHooksManager.java @@ -16,14 +16,18 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.attribute.PosixFilePermission; -import java.time.Instant; import java.time.ZoneId; import java.time.format.DateTimeFormatter; -import java.util.*; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; import java.util.concurrent.Executors; import java.util.stream.Collectors; -import net.lingala.zip4j.ZipFile; import org.apache.maven.plugin.logging.Log; import org.apache.maven.plugin.logging.SystemStreamLog; @@ -131,41 +135,6 @@ List getExistingHookFiles() { .collect(Collectors.toList()); } - /** - * Checks if the plugin is launched the first time (`archived` directory is already created). - * @return true if it's launched first time, false - otherwise - */ - boolean isFirstLaunchOfPlugin() { - return !Files.exists(ARCHIVES_PATH); - } - - /** - * Backups existing hook files into a zip file. - * @param hookFiles hook files to back up - * @throws IllegalStateException if an error occurs on writing the backup file - */ - void backupExistingHooks(List hookFiles) { - try { - Files.createDirectories(ARCHIVES_PATH); - zipFiles(hookFiles, ARCHIVES_PATH.resolve("hooks_" + formatter.format(Instant.now()) + ".zip").toString()); - } catch (IOException e) { - throw new IllegalStateException("Cannot create backup for existing hooks", e); - } - } - - private void zipFiles(List srcFiles, String outputFileName) throws IOException { - if (srcFiles.isEmpty()) { - logger.debug("No hooks existed, nothing to backup"); - return; - } - - logger.info("Making backup of the existing hooks. " - + "They will be available in directory: " + ARCHIVES_PATH); - try (ZipFile backup = new ZipFile(outputFileName)) { - backup.addFiles(srcFiles); - } - } - /** * Writes hook file with the specified name and value. * @param hookName hook's name diff --git a/src/main/java/io/github/pepperkit/githooks/InitHooksMojo.java b/src/main/java/io/github/pepperkit/githooks/InitHooksMojo.java index 5f1ab4e..7d74a62 100644 --- a/src/main/java/io/github/pepperkit/githooks/InitHooksMojo.java +++ b/src/main/java/io/github/pepperkit/githooks/InitHooksMojo.java @@ -45,23 +45,13 @@ public void setHooks(String hooks) { public void execute() throws MojoExecutionException { List existingHookFiles = gitHooksManager.getExistingHookFiles(); if (hooks == null) { - gitHooksManager.backupExistingHooks(existingHookFiles); existingHookFiles.forEach(File::delete); return; } - if (gitHooksManager.isFirstLaunchOfPlugin() && !existingHookFiles.isEmpty()) { - throw new MojoExecutionException("There are existing hooks detected, which were not created using this" - + " plugin. Please, make sure that you transferred them to plugin's configuration " - + "and delete them manually."); - } - gitHooksManager.checkProvidedHookNamesCorrectness(hooks); gitHooksManager.checkGitHooksDirAndCreateIfMissing(); - List hookFiles = gitHooksManager.getExistingHookFiles(); - gitHooksManager.backupExistingHooks(hookFiles); - String hookToBeCreated = null; try { for (Map.Entry hook : hooks.entrySet()) { diff --git a/src/system-test/java/io/github/pepperkit/githooks/steps/GivenStepDefinitions.java b/src/system-test/java/io/github/pepperkit/githooks/steps/GivenStepDefinitions.java index c6aa9ac..f854e58 100644 --- a/src/system-test/java/io/github/pepperkit/githooks/steps/GivenStepDefinitions.java +++ b/src/system-test/java/io/github/pepperkit/githooks/steps/GivenStepDefinitions.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 PepperKit + * Copyright (C) 2023 PepperKit * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. diff --git a/src/system-test/java/io/github/pepperkit/githooks/steps/ThenStepDefinitions.java b/src/system-test/java/io/github/pepperkit/githooks/steps/ThenStepDefinitions.java index 6469eb3..0655215 100644 --- a/src/system-test/java/io/github/pepperkit/githooks/steps/ThenStepDefinitions.java +++ b/src/system-test/java/io/github/pepperkit/githooks/steps/ThenStepDefinitions.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 PepperKit + * Copyright (C) 2023 PepperKit * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. @@ -57,6 +57,13 @@ public void previouslyAddedHooksAreArchived() throws IOException, InterruptedExc .hasSize(1); } + @Then("previously added hooks are not archived") + public void previouslyAddedHooksAreNotArchived() throws IOException, InterruptedException { + cmdResult = container.execInContainer("ls", ".git/hooks/archived"); + assertThat(cmdResult.getStdout().split(" ")) + .hasSize(0); + } + @Then("it prints all the hooks installed at the moment") public void printsAllHooksInstalled() { assertThat(cmdResult.getStdout()) diff --git a/src/system-test/java/io/github/pepperkit/githooks/steps/WhenStepDefinitions.java b/src/system-test/java/io/github/pepperkit/githooks/steps/WhenStepDefinitions.java index 818fc0d..f76f88d 100644 --- a/src/system-test/java/io/github/pepperkit/githooks/steps/WhenStepDefinitions.java +++ b/src/system-test/java/io/github/pepperkit/githooks/steps/WhenStepDefinitions.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 PepperKit + * Copyright (C) 2023 PepperKit * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. @@ -52,4 +52,16 @@ public void testGoalLaunchedWithPrePushHookSpecified() throws IOException, Inter cmdResult = container.execInContainer("mvn", "-f", "pre_commit_push_hooks-pom.xml", "-DhookName=pre-push", "io.github.pepperkit:git-hooks-maven-plugin:executeHooks"); } + + @When("initHooks goal of the plugin is launched with the same plugin's configuration") + public void initWithHooksConfigured() throws IOException, InterruptedException { + cmdResult = container.execInContainer("mvn", "-f", "pre_commit_push_hooks-pom.xml", + "io.github.pepperkit:git-hooks-maven-plugin:initHooks"); + assertThat(cmdResult.getStdout()) + .contains("BUILD SUCCESS"); + + cmdResult = container.execInContainer("cat", ".git/hooks/pre-commit"); + assertThat(cmdResult.getStdout()) + .contains("pre-commit hook is invoked"); + } } diff --git a/src/system-test/resources/io/github/pepperkit/githooks/init.feature b/src/system-test/resources/io/github/pepperkit/githooks/init.feature index 1c80c7b..33c6866 100644 --- a/src/system-test/resources/io/github/pepperkit/githooks/init.feature +++ b/src/system-test/resources/io/github/pepperkit/githooks/init.feature @@ -19,10 +19,3 @@ Feature: Initialize git hooks via initHooks goal And initHooks goal was launched before with hooks presented in configuration When initHooks goal of the plugin is launched with hooks deleted from plugin's configuration Then previously added hooks are deleted - - Scenario: Archives previously installed hooks - Given there's a maven project with git-hooks plugin configured - And git repository is set up for the project - And initHooks goal was launched before with hooks presented in configuration - When initHooks goal of the plugin is launched with another plugin's configuration - Then previously added hooks are archived diff --git a/src/test/java/io/github/pepperkit/githooks/InitHooksMojoTest.java b/src/test/java/io/github/pepperkit/githooks/InitHooksMojoTest.java index 8d32d08..fab79a0 100644 --- a/src/test/java/io/github/pepperkit/githooks/InitHooksMojoTest.java +++ b/src/test/java/io/github/pepperkit/githooks/InitHooksMojoTest.java @@ -73,20 +73,6 @@ void initThrowsMojoExecutionExceptionIfCreatingOfHookFails() throws MojoExecutio assertThat(excThrown.getMessage()).contains("pre-push"); } - @Test - void initThrowsExceptionIfItIsFirstLaunchAndThereAreExistingHooks() throws MojoExecutionException { - Map hooks = new HashMap<>(); - hooks.put("pre-commit", "mvn -B checkstyle:checkstyle"); - initHooksMojo.hooks = hooks; - - when(gitHooksManagerMock.getExistingHookFiles()) - .thenReturn(Collections.singletonList(new File("pre-commit"))); - when(gitHooksManagerMock.isFirstLaunchOfPlugin()).thenReturn(true); - - MojoExecutionException excThrown = assertThrows(MojoExecutionException.class, initHooksMojo::execute); - assertThat(excThrown.getMessage()).containsIgnoringCase("there are existing hooks detected"); - } - @Test void setHooksToNullIfNullStringProvidedInConfiguration() { initHooksMojo.setHooks("null");