blob: 8964008838a9936c3c85401039b37ddd034f6fb5 [file] [log] [blame]
// Copyright (C) 2020 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.plugins.codeowners.backend;
import static com.google.common.collect.ImmutableList.toImmutableList;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
/**
* Representation of a code owner set modification as defined by {@link #apply(ImmutableList)}.
*
* <p>Used by {@link CodeOwnerConfigUpdate} to describe how the {@link CodeOwnerSet}s in a {@link
* CodeOwnerConfig} should be changed on updated or be populated on creation.
*
* <p>This class provides a couple of static helper methods to modify {@link CodeOwnerSet}s that
* make changes to code owners sets easier for callers.
*/
@FunctionalInterface
public interface CodeOwnerSetModification {
/**
* Create a {@link CodeOwnerSetModification} instance that keeps the {@link CodeOwnerSet}s as they
* are.
*
* @return the created {@link CodeOwnerSetModification} instance
*/
public static CodeOwnerSetModification keep() {
return originalCodeOwnerSets -> originalCodeOwnerSets;
}
/**
* Create a {@link CodeOwnerSetModification} instance that clears the {@link CodeOwnerSet}s.
*
* <p>All {@link CodeOwnerSet}s are removed.
*
* @return the created {@link CodeOwnerSetModification} instance
*/
public static CodeOwnerSetModification clear() {
return originalCodeOwnerSets -> ImmutableList.of();
}
/**
* Create a {@link CodeOwnerSetModification} instance that appends the given {@link CodeOwnerSet}.
*
* @param newCodeOwnerSet the code owner set that should be appended
* @return the created {@link CodeOwnerSetModification} instance
*/
public static CodeOwnerSetModification append(CodeOwnerSet newCodeOwnerSet) {
return originalCodeOwnerSets ->
new ImmutableList.Builder<CodeOwnerSet>()
.addAll(originalCodeOwnerSets)
.add(newCodeOwnerSet)
.build();
}
/**
* Create a {@link CodeOwnerSetModification} instance that sets the given {@link CodeOwnerSet}.
*
* <p>This overrides all code owner sets which have been set before.
*
* @param newCodeOwnerSet the code owner set that should be set
* @return the created {@link CodeOwnerSetModification} instance
*/
public static CodeOwnerSetModification set(CodeOwnerSet newCodeOwnerSet) {
return set(ImmutableList.of(newCodeOwnerSet));
}
/**
* Create a {@link CodeOwnerSetModification} instance that sets the given {@link CodeOwnerSet}s.
*
* <p>This overrides all code owner sets which have been set before.
*
* @param newCodeOwnerSets the code owner sets that should be set
* @return the created {@link CodeOwnerSetModification} instance
*/
public static CodeOwnerSetModification set(ImmutableList<CodeOwnerSet> newCodeOwnerSets) {
return originalCodeOwnerSets -> newCodeOwnerSets;
}
/**
* Create a {@link CodeOwnerSetModification} instance that adds the given email to the only {@link
* CodeOwnerSet}.
*
* <p>Fails if the original list of code owners sets is empty or if it has more than 1 entry.
*
* @param email the email that should be added to the only code owner set
* @return the created {@link CodeOwnerSetModification} instance
*/
public static CodeOwnerSetModification addToOnlySet(String email) {
return addToOnlySet(CodeOwnerReference.create(email));
}
/**
* Create a {@link CodeOwnerSetModification} instance that adds the given {@link
* CodeOwnerReference} to the only {@link CodeOwnerSet}.
*
* <p>Fails if the original list of code owners sets is empty or if it has more than 1 entry.
*
* @param codeOwnerReference the code owner reference that should be added to the only code owner
* set
* @return the created {@link CodeOwnerSetModification} instance
*/
public static CodeOwnerSetModification addToOnlySet(CodeOwnerReference codeOwnerReference) {
return originalCodeOwnerSets ->
ImmutableList.of(
addToCodeOwnerSet(Iterables.getOnlyElement(originalCodeOwnerSets), codeOwnerReference));
}
/**
* Adds the given {@link CodeOwnerReference} to the given {@link CodeOwnerSet}.
*
* @param codeOwnerSet the code owner set to which the given code owner reference should be added
* @param codeOwnerReference the code owner reference that should be added to the given code owner
* set
* @return the updated code owner set
*/
public static CodeOwnerSet addToCodeOwnerSet(
CodeOwnerSet codeOwnerSet, CodeOwnerReference codeOwnerReference) {
if (codeOwnerSet.codeOwners().contains(codeOwnerReference)) {
return codeOwnerSet;
}
return codeOwnerSet.toBuilder().addCodeOwner(codeOwnerReference).build();
}
/**
* Create a {@link CodeOwnerSetModification} instance that removes the given {@link CodeOwnerSet}.
*
* <p>No-op if the given code owner set doesn't exist.
*
* @param codeOwnerSetToRemove the code owner set that should be removed
* @return the created {@link CodeOwnerSetModification} instance
*/
public static CodeOwnerSetModification remove(CodeOwnerSet codeOwnerSetToRemove) {
return originalCodeOwnerSets ->
originalCodeOwnerSets.stream()
.filter(codeOwnerSet -> !codeOwnerSet.equals(codeOwnerSetToRemove))
.collect(toImmutableList());
}
/**
* Create a {@link CodeOwnerSetModification} instance that removes the given email from the only
* {@link CodeOwnerSet}s.
*
* <p>Fails if the original list of code owners sets is empty or if it has more than 1 entry.
*
* @param email the email that should be removed from all owner sets
* @return the created {@link CodeOwnerSetModification} instance
*/
public static CodeOwnerSetModification removeFromOnlySet(String email) {
return removeFromOnlySet(CodeOwnerReference.create(email));
}
/**
* Create a {@link CodeOwnerSetModification} instance that removes the given {@link
* CodeOwnerReference} from the only {@link CodeOwnerSet}s.
*
* <p>Fails if the original list of code owners sets is empty or if it has more than 1 entry.
*
* @param codeOwnerReference the code owner reference that should be removed from all owner sets
* @return the created {@link CodeOwnerSetModification} instance
*/
public static CodeOwnerSetModification removeFromOnlySet(CodeOwnerReference codeOwnerReference) {
return originalCodeOwnerSets ->
ImmutableList.of(
removeFromCodeOwnerSet(
Iterables.getOnlyElement(originalCodeOwnerSets), codeOwnerReference));
}
/**
* Removes the given {@link CodeOwnerReference} from the given {@link CodeOwnerSet}.
*
* @param codeOwnerSet the code owner set from which the given code owner reference should be
* removed
* @param codeOwnerReference the code owner reference that should be removed from the given code
* owner set
* @return the updated code owner set
*/
public static CodeOwnerSet removeFromCodeOwnerSet(
CodeOwnerSet codeOwnerSet, CodeOwnerReference codeOwnerReference) {
if (!codeOwnerSet.codeOwners().contains(codeOwnerReference)) {
return codeOwnerSet;
}
return codeOwnerSet
.toBuilder()
.setCodeOwners(
Sets.difference(codeOwnerSet.codeOwners(), ImmutableSet.of(codeOwnerReference))
.immutableCopy())
.build();
}
/**
* Applies the modification to the given code owner sets.
*
* @param originalCodeOwnerSets the current code owner sets of the code owner config that is being
* updated. If used for a code owner config creation, this set is empty.
* @return the desired resulting code owner sets (not the diff of the code owner sets!)
*/
ImmutableList<CodeOwnerSet> apply(ImmutableList<CodeOwnerSet> originalCodeOwnerSets);
}