package se.bjurr.sbcc.settings; import static com.google.common.base.MoreObjects.firstNonNull; import static com.google.common.base.Optional.fromNullable; import static com.google.common.base.Strings.emptyToNull; import static com.google.common.base.Strings.isNullOrEmpty; import static com.google.common.base.Strings.nullToEmpty; import static com.google.common.collect.Lists.newArrayList; import static java.lang.Boolean.FALSE; import static java.lang.Boolean.TRUE; import static java.lang.Integer.MAX_VALUE; import static java.lang.Integer.parseInt; import static java.util.regex.Pattern.compile; import static se.bjurr.sbcc.settings.SbccGroup.sbccGroup; import static se.bjurr.sbcc.settings.SbccRule.sbccRule; import java.util.List; import java.util.regex.PatternSyntaxException; import com.atlassian.bitbucket.setting.Settings; import com.google.common.base.Optional; import com.google.gson.GsonBuilder; public class SbccSettings { public static final String SETTING_ACCEPT_MESSAGE = "acceptMessage"; public static final String SETTING_BRANCHES = "branches"; public static final String SETTING_DRY_RUN = "dryRun"; public static final String SETTING_DRY_RUN_MESSAGE = "dryRunMessage"; public static final String SETTING_EXCLUDE_MERGE_COMMITS = "excludeMergeCommits"; public static final String SETTING_EXCLUDE_TAG_COMMITS = "excludeTagCommits"; public static final String SETTING_GROUP_ACCEPT = "groupAccept"; public static final String SETTING_GROUP_MATCH = "groupMatch"; public static final String SETTING_GROUP_MESSAGE = "groupMessage"; public static final String SETTING_REJECT_MESSAGE = "rejectMessage"; public static final String SETTING_REQUIRE_MATCHING_COMMITTER_EMAIL = "requireMatchingCommitterEmail"; public static final String SETTING_REQUIRE_MATCHING_AUTHOR_EMAIL = "requireMatchingAuthorEmail"; public static final String SETTING_REQUIRE_MATCHING_AUTHOR_EMAIL_BITBUCKET = "requireMatchingAuthorEmailInBitbucket"; public static final String SETTING_REQUIRE_MATCHING_AUTHOR_EMAIL_REGEXP = "requireMatchingAuthorEmailRegexp"; public static final String SETTING_REQUIRE_MATCHING_AUTHOR_EMAIL_MESSAGE = "requireMatchingAuthorEmailMessage"; public static final String SETTING_REQUIRE_MATCHING_AUTHOR_NAME = "requireMatchingAuthorName"; public static final String SETTING_REQUIRE_MATCHING_AUTHOR_NAME_SLUG = "requireMatchingAuthorNameSlug"; public static final String SETTING_REQUIRE_MATCHING_AUTHOR_NAME_BITBUCKET = "requireMatchingAuthorNameInBitbucket"; public static final String SETTING_REQUIRE_MATCHING_AUTHOR_NAME_BITBUCKET_SLUG = "requireMatchingAuthorNameInBitbucketSlug"; public static final String SETTING_REQUIRE_MATCHING_COMMITTER_NAME = "requireMatchingCommitterName"; public static final String SETTING_REQUIRE_MATCHING_COMMITTER_NAME_SLUG = "requireMatchingCommitterNameSlug"; public static final String SETTING_REQUIRE_MATCHING_AUTHOR_NAME_MESSAGE = "requireMatchingAuthorNameMessage"; public static final String SETTING_RULE_MESSAGE = "ruleMessage"; public static final String SETTING_RULE_REGEXP = "ruleRegexp"; public static final String SETTING_DIFF_REGEXP = "checkCommitDiffRegexp"; public static final String SETTING_DIFF_REGEXP_MESSAGE = "checkCommitDiffRegexpMessage"; public static final String SETTING_SIZE = "checkCommitSize"; public static final String SETTING_SIZE_MESSAGE = "checkCommitSizeMessage"; public static final String SETTING_BRANCH_REJECTION_REGEXP = "branchRejectionRegexp"; public static final String SETTING_BRANCH_REJECTION_REGEXP_MESSAGE = "branchRejectionRegexpMessage"; public static final String SETTING_ALLOW_SERVICE_USERS = "allowServiceUsers"; public static final String SETTING_JQL_CHECK = "jqlCheck"; public static final String SETTING_JQL_CHECK_MESSAGE = "jqlCheckMessage"; public static final String SETTING_COMMIT_REGEXP = "commitRegexp"; public static final String SETTING_JQL_CHECK_QUERY = "jqlCheckQuery"; public static final String SETTING_CHECK_PULLREQUESTS = "shouldCheckPullrequests"; public static final String SETTING_CHECK_PULLREQUESTS_MESSAGE = "shouldCheckPullrequestsMessage"; public static final String SETTING_IGNORE_USERS_PATTERN = "ignoreUsersPattern"; private String commitDiffRegexp; private String commitDiffRegexpMessage; private String commitSizeMessage; private int commitSize; private String acceptMessage; private String branches; private boolean dryRun; private String dryRunMessage; private boolean excludeMergeCommits; private Boolean excludeTagCommits; private final List<SbccGroup> groups = newArrayList(); private String rejectMessage; private boolean requireMatchingAuthorEmail; private boolean requireMatchingCommitterEmail; private String requireMatchingAuthorEmailMessage; private boolean requireMatchingAuthorName; private boolean requireMatchingAuthorNameSlug; private boolean requireMatchingCommitterName; private boolean requireMatchingCommitterNameSlug; private String requireMatchingAuthorNameMessage; private boolean requireOnlyOneIssue; private String requireOnlyOneIssueMessage; private String branchRejectionRegexp; private String branchRejectionRegexpMessage; private boolean allowServiceUsers; private String requireMatchingAuthorEmailRegexp; private Boolean jqlCheck; private String jqlCheckMessage; private String jqlCheckQuery; private String commitRegexp; private Boolean requireMatchingAuthorEmailInBitbucket; private Boolean requireMatchingAuthorNameInBitbucket; private Boolean requireMatchingAuthorNameInBitbucketSlug; private boolean shouldCheckPullRequests; private String shouldCheckPullRequestsMessage; private String ignoreUsersPattern; public static SbccSettings sscSettings(Settings settings) throws ValidationException { final SbccSettings sbccSettings = new SbccSettings(); sbccSettings .withAcceptMessage( // settings.getString(SETTING_ACCEPT_MESSAGE)) .withBranches(validateRegExp(SETTING_BRANCHES, settings.getString(SETTING_BRANCHES))) .withDryRun(settings.getBoolean(SETTING_DRY_RUN)) .withDryRunMessage(settings.getString(SETTING_DRY_RUN_MESSAGE)) .withExcludeMergeCommits(settings.getBoolean(SETTING_EXCLUDE_MERGE_COMMITS)) .withExcludeTagCommits(settings.getBoolean(SETTING_EXCLUDE_TAG_COMMITS)) .withRejectMessage(settings.getString(SETTING_REJECT_MESSAGE)) .withRequireMatchingAuthorEmail(settings.getBoolean(SETTING_REQUIRE_MATCHING_AUTHOR_EMAIL)) .withRequireMatchingAuthorEmailInBitbucket( settings.getBoolean(SETTING_REQUIRE_MATCHING_AUTHOR_EMAIL_BITBUCKET)) .withRequireMatchingCommitterEmail( settings.getBoolean(SETTING_REQUIRE_MATCHING_COMMITTER_EMAIL)) .withRequireMatchingAuthorEmailMessage( settings.getString(SETTING_REQUIRE_MATCHING_AUTHOR_EMAIL_MESSAGE)) .withRequireMatchingAuthorEmailRegexp( settings.getString(SETTING_REQUIRE_MATCHING_AUTHOR_EMAIL_REGEXP)) .withRequireMatchingAuthorName(settings.getBoolean(SETTING_REQUIRE_MATCHING_AUTHOR_NAME)) .withRequireMatchingAuthorNameInBitbucket( settings.getBoolean(SETTING_REQUIRE_MATCHING_AUTHOR_NAME_BITBUCKET)) .withRequireMatchingAuthorNameSlug( settings.getBoolean(SETTING_REQUIRE_MATCHING_AUTHOR_NAME_SLUG)) .withRequireMatchingAuthorNameInBitbucketSlug( settings.getBoolean(SETTING_REQUIRE_MATCHING_AUTHOR_NAME_BITBUCKET_SLUG)) .withRequireMatchingCommitterName( settings.getBoolean(SETTING_REQUIRE_MATCHING_COMMITTER_NAME)) .withRequireMatchingCommitterNameSlug( settings.getBoolean(SETTING_REQUIRE_MATCHING_COMMITTER_NAME_SLUG)) .withRequireMatchingAuthorNameMessage( settings.getString(SETTING_REQUIRE_MATCHING_AUTHOR_NAME_MESSAGE)) .withCheckCommitDiffRegexp( validateRegExp(SETTING_DIFF_REGEXP, settings.getString(SETTING_DIFF_REGEXP))) .withCheckCommitDiffRegexpMessage(settings.getString(SETTING_DIFF_REGEXP_MESSAGE)) .withCheckCommitSizeMessage(settings.getString(SETTING_SIZE_MESSAGE)) .withBranchRejectionRegexp( validateRegExp( SETTING_BRANCH_REJECTION_REGEXP, settings.getString(SETTING_BRANCH_REJECTION_REGEXP))) .withBranchRejectionRegexpMessage( settings.getString(SETTING_BRANCH_REJECTION_REGEXP_MESSAGE)) .withAllowServiceUsers(settings.getBoolean(SETTING_ALLOW_SERVICE_USERS)) .withJqlCheck(settings.getBoolean(SETTING_JQL_CHECK)) .withJqlCheckMessage(settings.getString(SETTING_JQL_CHECK_MESSAGE)) .withCommitRegexp(settings.getString(SETTING_COMMIT_REGEXP)) .withJqlCheckQuery(settings.getString(SETTING_JQL_CHECK_QUERY)) .withShouldCheckPullRequests(settings.getBoolean(SETTING_CHECK_PULLREQUESTS)) .withShouldCheckPullRequestsMessage(settings.getString(SETTING_CHECK_PULLREQUESTS_MESSAGE)) .withIgnoreUsersPattern(settings.getString(SETTING_IGNORE_USERS_PATTERN)); try { if (!isNullOrEmpty(settings.getString(SETTING_SIZE))) { sbccSettings.withCheckCommitSize(parseInt(settings.getString(SETTING_SIZE))); } } catch (Exception e) { throw new ValidationException(SETTING_SIZE, "Not an integer!"); } for (int g = 0; g < 1000; g++) { final Optional<String> accept = fromNullable(settings.getString(SETTING_GROUP_ACCEPT + "[" + g + "]")); final Optional<String> match = fromNullable(settings.getString(SETTING_GROUP_MATCH + "[" + g + "]")); final String message = settings.getString(SETTING_GROUP_MESSAGE + "[" + g + "]"); if (accept.isPresent() || match.isPresent()) { if (accept.isPresent() && !match.isPresent()) { throw new ValidationException( SETTING_GROUP_MATCH + "[" + g + "]", "Cannot add a rule group without matching criteria!"); } else if (!accept.isPresent() && match.isPresent()) { throw new ValidationException( SETTING_GROUP_ACCEPT + "[" + g + "]", "Cannot add a rule group without acceptance criteria!"); } final List<SbccRule> rules = newArrayList(); for (int r = 0; r < 1000; r++) { final String ruleRegexpField = SETTING_RULE_REGEXP + "[" + g + "][" + r + "]"; final Optional<String> ruleRegexp = fromNullable(settings.getString(ruleRegexpField)); final Optional<String> ruleMessage = fromNullable(settings.getString(SETTING_RULE_MESSAGE + "[" + g + "][" + r + "]")); if (ruleRegexp.isPresent()) { rules.add( sbccRule() // .withRegexp(validateRegExp(ruleRegexpField, ruleRegexp.get())) // .withMessage(ruleMessage.orNull())); } else if (ruleMessage.isPresent()) { throw new ValidationException(ruleRegexpField, "Cannot add a rule without regexp!"); } } sbccSettings.withGroup( // sbccGroup() // .withAccept(accept.get()) // .withMatch(match.get()) // .withMessage(message) // .withRules(rules)); } } return sbccSettings; } private SbccSettings withRequireMatchingAuthorNameInBitbucketSlug( Boolean requireMatchingAuthorNameInBitbucketSlug) { this.requireMatchingAuthorNameInBitbucketSlug = firstNonNull(requireMatchingAuthorNameInBitbucketSlug, FALSE); return this; } private SbccSettings withRequireMatchingAuthorNameSlug(Boolean requireMatchingAuthorNameSlug) { this.requireMatchingAuthorNameSlug = firstNonNull(requireMatchingAuthorNameSlug, FALSE); return this; } private SbccSettings withRequireMatchingCommitterNameSlug( Boolean requireMatchingCommitterNameSlug) { this.requireMatchingCommitterNameSlug = firstNonNull(requireMatchingCommitterNameSlug, FALSE); return this; } private void withIgnoreUsersPattern(String string) { this.ignoreUsersPattern = emptyToNull(string); } private SbccSettings withShouldCheckPullRequestsMessage(String string) { this.shouldCheckPullRequestsMessage = emptyToNull(nullToEmpty(string).trim()); return this; } public Optional<String> getShouldCheckPullRequestsMessage() { return fromNullable(shouldCheckPullRequestsMessage); } private SbccSettings withJqlCheck(Boolean b) { this.jqlCheck = firstNonNull(b, FALSE); return this; } private SbccSettings withJqlCheckMessage(String string) { this.jqlCheckMessage = emptyToNull(nullToEmpty(string).trim()); return this; } private SbccSettings withCommitRegexp(String string) { this.commitRegexp = emptyToNull(nullToEmpty(string).trim()); return this; } private SbccSettings withJqlCheckQuery(String string) { this.jqlCheckQuery = nullToEmpty(string).trim(); return this; } public Boolean shouldCheckJql() { return jqlCheck; } public Optional<String> getJqlCheckMessage() { return fromNullable(jqlCheckMessage); } public Optional<String> getCommitRegexp() { return fromNullable(commitRegexp); } public String getJqlCheckQuery() { return jqlCheckQuery; } private SbccSettings withRequireMatchingAuthorEmailRegexp(String string) { this.requireMatchingAuthorEmailRegexp = emptyToNull(string); return this; } private SbccSettings withAllowServiceUsers(Boolean allowServiceUsers) { this.allowServiceUsers = firstNonNull(allowServiceUsers, FALSE); return this; } private SbccSettings withCheckCommitDiffRegexp(String string) { this.commitDiffRegexp = emptyToNull(nullToEmpty(string).trim()); return this; } private SbccSettings withCheckCommitDiffRegexpMessage(String string) { this.commitDiffRegexpMessage = emptyToNull(nullToEmpty(string).trim()); return this; } private SbccSettings withBranchRejectionRegexp(String string) { this.branchRejectionRegexp = emptyToNull(nullToEmpty(string).trim()); return this; } private SbccSettings withBranchRejectionRegexpMessage(String string) { this.branchRejectionRegexpMessage = emptyToNull(nullToEmpty(string).trim()); return this; } private SbccSettings withCheckCommitSize(int commitSize) { this.commitSize = commitSize; return this; } private SbccSettings withCheckCommitSizeMessage(String string) { this.commitSizeMessage = emptyToNull(nullToEmpty(string).trim()); return this; } private static String validateRegExp(String field, String regexp) throws ValidationException { if (regexp == null) { return null; } try { compile(regexp); } catch (final PatternSyntaxException ex) { throw new ValidationException( field, "Invalid Regexp: " + ex.getMessage().replaceAll("\n", " ")); } return regexp; } private SbccSettings() {} public Optional<String> getAcceptMessage() { return fromNullable(acceptMessage); } public Optional<String> getBranches() { return fromNullable(branches); } public Optional<String> getDryRunMessage() { return fromNullable(dryRunMessage); } public List<SbccGroup> getGroups() { return groups; } public Optional<String> getRejectMessage() { return fromNullable(rejectMessage); } public Optional<String> getRequireMatchingAuthorEmailMessage() { return fromNullable(requireMatchingAuthorEmailMessage); } public Optional<String> getRequireMatchingAuthorEmailRegexp() { return fromNullable(requireMatchingAuthorEmailRegexp); } public Optional<String> getRequireMatchingAuthorNameMessage() { return fromNullable(requireMatchingAuthorNameMessage); } public boolean getRequireOnlyOneIssue() { return requireOnlyOneIssue; } public Optional<String> getRequireOnlyOneIssueMessage() { return fromNullable(requireOnlyOneIssueMessage); } public boolean isDryRun() { return dryRun; } public boolean shouldExcludeMergeCommits() { return excludeMergeCommits; } public Boolean shouldExcludeTagCommits() { return excludeTagCommits; } public boolean shouldRequireMatchingAuthorEmail() { return requireMatchingAuthorEmail; } public boolean shouldRequireMatchingAuthorName() { return requireMatchingAuthorName; } public boolean shouldRequireMatchingCommitterEmail() { return requireMatchingCommitterEmail; } public boolean shouldRequireMatchingCommitterName() { return requireMatchingCommitterName; } public Optional<String> getCommitDiffRegexp() { return fromNullable(commitDiffRegexp); } public Optional<String> getCommitDiffRegexpMessage() { return fromNullable(commitDiffRegexpMessage); } public int getCommitSizeKb() { if (commitSize == 0) { return MAX_VALUE; } else { return commitSize; } } public Optional<String> getCommitSizeMessage() { return fromNullable(commitSizeMessage); } @Override public String toString() { return new GsonBuilder().setPrettyPrinting().create().toJson(this); } private SbccSettings withAcceptMessage(String acceptMessage) { this.acceptMessage = emptyToNull(acceptMessage); return this; } private SbccSettings withBranches(String branches) { this.branches = emptyToNull(branches); return this; } private SbccSettings withDryRun(Boolean dryRun) { this.dryRun = firstNonNull(dryRun, FALSE); return this; } private SbccSettings withDryRunMessage(String dryRunMessage) { this.dryRunMessage = emptyToNull(dryRunMessage); return this; } private SbccSettings withExcludeMergeCommits(Boolean excludeMergeCommits) { this.excludeMergeCommits = firstNonNull(excludeMergeCommits, TRUE); return this; } private SbccSettings withExcludeTagCommits(Boolean excludeTagCommits) { this.excludeTagCommits = firstNonNull(excludeTagCommits, TRUE); return this; } private SbccSettings withGroup(SbccGroup sbccGroup) { this.groups.add(sbccGroup); return this; } private SbccSettings withRejectMessage(String rejectMessage) { this.rejectMessage = emptyToNull(rejectMessage); return this; } private SbccSettings withRequireMatchingAuthorEmail(Boolean requireMatchingAuthorEmail) { this.requireMatchingAuthorEmail = firstNonNull(requireMatchingAuthorEmail, FALSE); return this; } private SbccSettings withRequireMatchingAuthorEmailInBitbucket( Boolean requireMatchingAuthorEmailInBitbucket) { this.requireMatchingAuthorEmailInBitbucket = firstNonNull(requireMatchingAuthorEmailInBitbucket, FALSE); return this; } public Boolean getRequireMatchingAuthorEmailInBitbucket() { return requireMatchingAuthorEmailInBitbucket; } private SbccSettings withRequireMatchingCommitterEmail(Boolean requireMatchingCommitterEmail) { this.requireMatchingCommitterEmail = firstNonNull(requireMatchingCommitterEmail, FALSE); return this; } private SbccSettings withRequireMatchingAuthorEmailMessage( String requireMatchingAuthorEmailMessage) { this.requireMatchingAuthorEmailMessage = emptyToNull(requireMatchingAuthorEmailMessage); return this; } private SbccSettings withRequireMatchingAuthorName(Boolean requireMatchingAuthorName) { this.requireMatchingAuthorName = firstNonNull(requireMatchingAuthorName, FALSE); return this; } private SbccSettings withRequireMatchingAuthorNameInBitbucket( Boolean requireMatchingAuthorNameInBitbucket) { this.requireMatchingAuthorNameInBitbucket = firstNonNull(requireMatchingAuthorNameInBitbucket, FALSE); return this; } public Boolean getRequireMatchingAuthorNameInBitbucket() { return requireMatchingAuthorNameInBitbucket; } public Boolean isRequireMatchingAuthorNameInBitbucketSlug() { return requireMatchingAuthorNameInBitbucketSlug; } public boolean isRequireMatchingAuthorNameSlug() { return requireMatchingAuthorNameSlug; } public boolean isRequireMatchingCommitterNameSlug() { return requireMatchingCommitterNameSlug; } private SbccSettings withRequireMatchingCommitterName(Boolean requireMatchingCommitterName) { this.requireMatchingCommitterName = firstNonNull(requireMatchingCommitterName, FALSE); return this; } private SbccSettings withRequireMatchingAuthorNameMessage( String requireMatchingAuthorNameMessage) { this.requireMatchingAuthorNameMessage = emptyToNull(requireMatchingAuthorNameMessage); return this; } public Optional<String> getBranchRejectionRegexp() { return fromNullable(branchRejectionRegexp); } public Optional<String> getBranchRejectionRegexpMessage() { return fromNullable(branchRejectionRegexpMessage); } public boolean allowServiceUsers() { return allowServiceUsers; } private SbccSettings withShouldCheckPullRequests(Boolean shouldCheckPullRequests) { this.shouldCheckPullRequests = firstNonNull(shouldCheckPullRequests, FALSE); return this; } public boolean shouldCheckPullRequests() { return shouldCheckPullRequests; } public boolean shouldCheckCommitSize() { return commitSize != 0 && commitSize != MAX_VALUE; } public Optional<String> getIgnoreUsersPattern() { return fromNullable(ignoreUsersPattern); } }