in java/com/google/gerrit/plugins/codeowners/validation/CodeOwnerConfigValidator.java [913:1038]
private Optional<CommitValidationMessage> validateCodeOwnerConfigReference(
BranchNameKey branchNameKey,
Path codeOwnerConfigFilePath,
CodeOwnerConfig.Key keyOfImportingCodeOwnerConfig,
RevCommit codeOwnerConfigRevision,
CodeOwnerConfigImportType importType,
CodeOwnerConfigReference codeOwnerConfigReference) {
CodeOwnerConfig.Key keyOfImportedCodeOwnerConfig =
PathCodeOwners.createKeyForImportedCodeOwnerConfig(
keyOfImportingCodeOwnerConfig, codeOwnerConfigReference);
if (isSelfImport(keyOfImportingCodeOwnerConfig, keyOfImportedCodeOwnerConfig)) {
return nonResolvableImport(
importType,
codeOwnerConfigFilePath,
"code owner config imports itself",
ValidationMessage.Type.WARNING);
}
Optional<ProjectState> projectState = projectCache.get(keyOfImportedCodeOwnerConfig.project());
if (!projectState.isPresent() || !isProjectReadable(keyOfImportedCodeOwnerConfig)) {
// we intentionally use the same error message for non-existing and non-readable projects so
// that uploaders cannot probe for the existence of projects (e.g. deduce from the error
// message whether a project exists)
return nonResolvableImport(
codeOwnerConfigRevision,
branchNameKey,
importType,
codeOwnerConfigReference,
codeOwnerConfigFilePath,
String.format("project '%s' not found", keyOfImportedCodeOwnerConfig.project().get()));
}
if (!projectState.get().statePermitsRead()) {
return nonResolvableImport(
codeOwnerConfigRevision,
branchNameKey,
importType,
codeOwnerConfigReference,
codeOwnerConfigFilePath,
String.format(
"project '%s' has state '%s' that doesn't permit read",
keyOfImportedCodeOwnerConfig.project().get(),
projectState.get().getProject().getState().name()));
}
Optional<ObjectId> revision =
getRevision(
keyOfImportingCodeOwnerConfig, codeOwnerConfigRevision, keyOfImportedCodeOwnerConfig);
if (!revision.isPresent() || !isBranchReadable(keyOfImportedCodeOwnerConfig)) {
// we intentionally use the same error message for non-existing and non-readable branches so
// that uploaders cannot probe for the existence of branches (e.g. deduce from the error
// message whether a branch exists)
return nonResolvableImport(
codeOwnerConfigRevision,
branchNameKey,
importType,
codeOwnerConfigReference,
codeOwnerConfigFilePath,
String.format(
"branch '%s' not found in project '%s'",
keyOfImportedCodeOwnerConfig.shortBranchName(),
keyOfImportedCodeOwnerConfig.project().get()));
}
CodeOwnerBackend codeOwnerBackend =
codeOwnersPluginConfiguration
.getProjectConfig(keyOfImportedCodeOwnerConfig.project())
.getBackend(keyOfImportedCodeOwnerConfig.branchNameKey().branch());
if (!codeOwnerBackend.isCodeOwnerConfigFile(
keyOfImportedCodeOwnerConfig.project(), codeOwnerConfigReference.fileName())) {
return nonResolvableImport(
codeOwnerConfigRevision,
branchNameKey,
importType,
codeOwnerConfigReference,
codeOwnerConfigFilePath,
String.format(
"'%s' is not a code owner config file", codeOwnerConfigReference.filePath()));
}
try {
// If a code owner config is imported from the same project, we must use the provided rev
// walk, otherwise the revision may not be visible yet and trying to load a code owner config
// from it could fail with MissingObjectException.
Optional<CodeOwnerConfig> importedCodeOwnerConfig =
keyOfImportedCodeOwnerConfig.project().equals(branchNameKey.project())
? codeOwnerBackend.getCodeOwnerConfig(keyOfImportedCodeOwnerConfig, revision.get())
: codeOwnerBackend.getCodeOwnerConfig(keyOfImportedCodeOwnerConfig, revision.get());
if (!importedCodeOwnerConfig.isPresent()) {
return nonResolvableImport(
codeOwnerConfigRevision,
branchNameKey,
importType,
codeOwnerConfigReference,
codeOwnerConfigFilePath,
String.format(
"'%s' does not exist (project = %s, branch = %s, revision = %s)",
codeOwnerConfigReference.filePath(),
keyOfImportedCodeOwnerConfig.branchNameKey().project().get(),
keyOfImportedCodeOwnerConfig.branchNameKey().shortName(),
revision.get().name()));
}
} catch (CodeOwnersInternalServerErrorException codeOwnersInternalServerErrorException) {
if (getInvalidCodeOwnerConfigCause(codeOwnersInternalServerErrorException).isPresent()) {
// The imported code owner config is non-parseable.
return nonResolvableImport(
codeOwnerConfigRevision,
branchNameKey,
importType,
codeOwnerConfigReference,
codeOwnerConfigFilePath,
String.format(
"'%s' is not parseable (project = %s, branch = %s)",
codeOwnerConfigReference.filePath(),
keyOfImportedCodeOwnerConfig.branchNameKey().project().get(),
keyOfImportedCodeOwnerConfig.branchNameKey().shortName()));
}
// Propagate any exception that was not caused by the content of the code owner config.
throw codeOwnersInternalServerErrorException;
}
// no issue found
return Optional.empty();
}