in java/com/google/gerrit/plugins/codeowners/validation/CodeOwnerConfigValidator.java [344:467]
private Optional<ValidationResult> validateCodeOwnerConfig(
BranchNameKey branchNameKey,
RevCommit revCommit,
IdentifiedUser user,
boolean force,
ImmutableListMultimap<String, String> pushOptions) {
CodeOwnersPluginProjectConfigSnapshot codeOwnersConfig =
codeOwnersPluginConfiguration.getProjectConfig(branchNameKey.project());
logger.atFine().log("force = %s", force);
if (!force && codeOwnersConfig.isDisabled(branchNameKey.branch())) {
return Optional.of(
ValidationResult.create(
pluginName,
"skipping validation of code owner config files",
new CommitValidationMessage(
"code-owners functionality is disabled", ValidationMessage.Type.HINT)));
}
try {
if (skipCodeOwnerConfigValidationPushOption.skipValidation(pushOptions)) {
logger.atFine().log("skip validation requested");
return Optional.of(
ValidationResult.create(
pluginName,
"skipping validation of code owner config files",
new CommitValidationMessage(
String.format(
"the validation is skipped due to the --%s~%s push option",
pluginName, SkipCodeOwnerConfigValidationPushOption.NAME),
ValidationMessage.Type.HINT)));
}
} catch (AuthException e) {
logger.atFine().withCause(e).log("Not allowed to skip code owner config validation");
return Optional.of(
ValidationResult.create(
pluginName,
"skipping code owner config validation not allowed",
new CommitValidationMessage(e.getMessage(), ValidationMessage.Type.ERROR)));
} catch (SkipCodeOwnerConfigValidationPushOption.InvalidValueException e) {
logger.atFine().log("%s", e.getMessage());
return Optional.of(
ValidationResult.create(
pluginName,
"invalid push option",
new CommitValidationMessage(e.getMessage(), ValidationMessage.Type.ERROR)));
}
if (codeOwnersConfig.areCodeOwnerConfigsReadOnly()) {
return Optional.of(
ValidationResult.create(
pluginName,
"modifying code owner config files not allowed",
new CommitValidationMessage(
"code owner config files are configured to be read-only",
ValidationMessage.Type.ERROR)));
}
try {
CodeOwnerBackend codeOwnerBackend = codeOwnersConfig.getBackend(branchNameKey.branch());
// For merge commits, always do the comparison against the destination branch
// (MergeCommitStrategy.ALL_CHANGED_FILES). Doing the comparison against the auto-merge
// (MergeCommitStrategy.FILES_WITH_CONFLICT_RESOLUTION) is not possible because loading the
// auto-merge cannot reuse the rev walk that can see newly created merge commits and hence
// trying to get the auto merge would fail with a missing object exception. This is why we
// use MergeCommitStrategy.ALL_CHANGED_FILES here even if
// MergeCommitStrategy.FILES_WITH_CONFLICT_RESOLUTION is configured.
ImmutableList<ChangedFile> modifiedCodeOwnerConfigFiles =
changedFiles
.getFromDiffCache(
branchNameKey.project(), revCommit, MergeCommitStrategy.ALL_CHANGED_FILES)
.stream()
// filter out deletions (files without new path)
.filter(changedFile -> changedFile.newPath().isPresent())
// filter out non code owner config files
.filter(
changedFile ->
codeOwnerBackend.isCodeOwnerConfigFile(
branchNameKey.project(),
Paths.get(changedFile.newPath().get().toString())
.getFileName()
.toString()))
.collect(toImmutableList());
if (modifiedCodeOwnerConfigFiles.isEmpty()) {
return Optional.empty();
}
// validate the code owner config files
return Optional.of(
ValidationResult.create(
pluginName,
modifiedCodeOwnerConfigFiles.stream()
.flatMap(
changedFile ->
validateCodeOwnerConfig(
user, codeOwnerBackend, branchNameKey, changedFile, revCommit))));
} catch (InvalidPluginConfigurationException e) {
// If the code-owners plugin configuration is invalid we cannot get the code owners backend
// and hence we are not able to detect and validate code owner config files. Instead of
// failing in this case (which would block all change uploads) we only log a warning and
// accept that it's possible to add invalid code owner configs while the plugin configuration
// is invalid.
logger.atWarning().log(
"cannot validate code owner config files due to invalid code-owners plugin"
+ " configuration: %s",
e.getMessage());
return Optional.of(
ValidationResult.create(
pluginName,
"skipping validation of code owner config files",
new CommitValidationMessage(
"code-owners plugin configuration is invalid,"
+ " cannot validate code owner config files",
ValidationMessage.Type.WARNING)));
} catch (IOException | DiffNotAvailableException e) {
String errorMessage =
String.format(
"failed to validate code owner config files in revision %s"
+ " (project = %s, branch = %s)",
revCommit.getName(), branchNameKey.project(), branchNameKey.branch());
throw new CodeOwnersInternalServerErrorException(errorMessage, e);
}
}