Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Validate Git branch naming convention #328 #329

Merged
merged 11 commits into from
Mar 16, 2017

Conversation

ademarco
Copy link
Contributor

@ademarco ademarco commented Mar 9, 2017

Q A
Branch master
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? no
Documented? yes
Fixed tickets #328

This PR adds branch name checking allowing to define branch names as follows:

parameters:
  tasks:
      git_branch_name:
        matchers:
          - '/^issue-\d+-[a-z-]+/'
        case_insensitive: false

New Task Checklist:

  • Is the README.md file updated?
  • Are the dependencies added to the composer.json suggestions?
  • Is the doc/tasks.md file updated?
  • Are the task parameters documented?
  • Is the task registered in the tasks.yml file?
  • Does the task contains phpspec tests?
  • Is the configuration having logical allowed types?
  • Does the task run in the correct context?
  • Is the run() method readable?
  • Is the run() method using the configuration correctly?
  • Are all CI services returning green?

@ademarco
Copy link
Contributor Author

ademarco commented Mar 9, 2017

Here a first draft, still need to provide tests.

I'm not sure how to answer to these:

 Is the run() method readable?
 Is the run() method using the configuration correctly?

@ademarco
Copy link
Contributor Author

@veewee does the PR look OK or should I polish it a little more?

Copy link
Contributor

@veewee veewee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @ademarco,

Thanks for the PR! It took me some time to get to the reviewing part. I've added some remarks to the code. Can you take a look at them?

doc/tasks.md Outdated
@@ -19,6 +19,7 @@ parameters:
gherkin: ~
git_blacklist: ~
git_commit_message: ~
git_branch_name: ~
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This list should be ordered alfabetical.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, also task link below in the same file.

README.md Outdated
@@ -102,6 +102,7 @@ parameters:
gherkin: ~
git_blacklist: ~
git_commit_message: ~
git_branch_name: ~
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This list should be ordered alfabetical.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@@ -41,6 +41,14 @@ public function getGitDir()
}

/**
* @return \Gitonomy\Git\Repository
*/
public function getGitRepository()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's better to inject the repository directly in the task constructor instead of using the configuration as additional service container. Can you remove this method?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, sorry! Removed, I'm using dependency injection now.

use GrumPHP\Task\TaskInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

abstract class AbstractRegex implements TaskInterface
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently I don't think this abstract class is the way to go. There are some people working on the git_commit_message task in e.g. #319. This will surely break the implementation and doesn't add much value since it only contains the configurable options. I think it's better to drop this class and create a separate implementation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reverted.

{
$resolver = new OptionsResolver();
$resolver->setDefaults([
'case_insensitive' => true,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if the case_insensitive and addition_modifiers are the way to go. Maybe it's better to enforce strict modifiers in the pattern. This was also mentioned in #319.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, removed in favour of already existing additional_modifiers option

*
* @throws RuntimeException
*/
protected function runMatcher(array $config, $name, $rule, $ruleName)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can mark this one as private

*
* @return string
*/
public function getCurrentBranchName()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can mark this one as private

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

public function getCurrentBranchName()
{
$gitRepository = $this->grumPHP->getGitRepository();
$branch = new Branch($gitRepository, $gitRepository->getHead()->getRevision());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure this will work in all cases. A commit can be in multiple branches. How does this code handle these?
Maybe it's better to execute the git symbolic-ref --short HEAD command through the Repository::run() command?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, removed that in favour of ::run() method


/**
* Git CommitMessage Task
*/
class CommitMessage implements TaskInterface
class CommitMessage extends AbstractRegex
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you revert this class to the old version?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reverted

Copy link
Contributor

@veewee veewee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the quick update! I've added 2 more remarks.

*/
public function canRunInContext(ContextInterface $context)
{
return $context instanceof RunContext;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this also run in pre-commit context? Now it will not be triggered during a git commit.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok done, I've added the pre commit context too.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, can you add a test for this as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, done!

{
$regex = new Regex($rule);

$additionalModifiersArray = array_filter(str_split((string) $config['additional_modifiers']));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The additional modifiers will always be a string since it is enforce by the OptionsResolver.

@veewee veewee added this to the Version 0.11.4 milestone Mar 14, 2017
*/
public function run(ContextInterface $context)
{
$name = trim($this->repository->run('symbolic-ref', ['HEAD', '--short']));
Copy link
Contributor

@veewee veewee Mar 14, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the current revision is a non symbolic reference, the command will throw an exception like:

Error code: 128
Message: fatal: ref HEAD is not a symbolic ref

This can happen in detached head or if you checked out a specific commit.
This will throw a Gitonomy\Git\Exception\ProcessException.

How would you like to handle this issue on the task? Should it be configurable to allow non symbolic references or not? We might want to fetch the error message and display a user-friendly error message instead?

More info: https://git-scm.com/docs/git-symbolic-ref

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should not check for branch naming convention when you are on a detached head or you checkout a specific commit? We could just catch the exception and skip the step by returning a TaskResult::createSkipped(), does that make sense?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it's best to make this configurable through an extra configuration flag?
Some people might want to allow it, others may have something against it.

Rules:

  • If you are allowed to commit on non symbolic references: task passes
  • If you are not allowed to commit on non symbolic references: task fails with a decent error message.

Copy link
Contributor Author

@ademarco ademarco Mar 14, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok shall we call the boolean option allow_symbolic_references? Should it default to true?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

something like 4f95d27 ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. I've added some remarks.
Can you add documentation and tests for this new flag?

]);

$resolver->addAllowedTypes('matchers', ['array']);
$resolver->addAllowedTypes('additional_modifiers', ['string']);
$resolver->addAllowedTypes('allow_symbolic_references', ['boolean']);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are trying to search the branch name based on the symbolic reference 'HEAD'. Since in detached mode there is no symbolic reference HEAD, you retrieve the error. So I don't think the naming is correct here.
Maybe something like allow_detached_head is easier to understand?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I'll go for that one.

if ($config['allow_symbolic_references'] === false) {
$message = "Branch naming convention task is not allowed to run on symbolic references.";
return TaskResult::createFailed($this, $context, $message);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the command fails and the detached head is allowed, you'll have to return a success result. Otherwise the matchers will fail.
If the detached head is not allowed, you can return the error message. Maybe it should be a bit more clear for less experienced users?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@veewee veewee merged commit 6fac607 into phpro:master Mar 16, 2017
@veewee
Copy link
Contributor

veewee commented Mar 16, 2017

Thanks for your work!

@drupol
Copy link
Contributor

drupol commented Mar 16, 2017

👍

@ademarco
Copy link
Contributor Author

Thanks for merging @veewee !

@ademarco ademarco deleted the 328-branch-names branch March 16, 2017 07:11
@jfhovinne
Copy link

👍

@netlooker
Copy link

👍 Massive feature :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants