Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions .github/check-self-contained.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#!/usr/bin/env bash
#
# Verifies that this API can be compiled on its own, without the CommonCapabilities mod
# and without loader-specific CyclopsCore classes.
#
# CyclopsCore consumes this repo as a submodule in a dedicated source set that only sees
# Minecraft, NeoForge and CyclopsCore's loader-common. Anything outside of that breaks its
# build, which is what this check guards against.
#
# Usage: .github/check-self-contained.sh [path-to-cyclopscore-checkout]

set -euo pipefail

API_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
CYCLOPSCORE_DIR="${1:-}"
CYCLOPSCORE_COMMON=""

if [[ -n "${CYCLOPSCORE_DIR}" ]]; then
CYCLOPSCORE_COMMON="${CYCLOPSCORE_DIR}/loader-common/src/main/java"
if [[ ! -d "${CYCLOPSCORE_COMMON}" ]]; then
echo "error: ${CYCLOPSCORE_COMMON} does not exist" >&2
exit 1
fi
fi

failures=0

fail() {
echo " $1" >&2
failures=$((failures + 1))
}

# Reduce a dotted name to its top-level class, e.g. a.b.C.D.FIELD -> a.b.C
top_level_class() {
local name="$1" out="" segment
local IFS='.'
for segment in ${name}; do
out="${out:+${out}.}${segment}"
if [[ "${segment}" =~ ^[A-Z] ]]; then
echo "${out}"
return
fi
done
echo ""
}

# Collect every org.cyclops.* reference, both imports and inline fully-qualified usages.
# Only this repo's own tracked sources are scanned, so a CyclopsCore checkout that happens to
# sit inside the working directory is not picked up.
sources="$(git -C "${API_DIR}" ls-files '*.java')"
if [[ -z "${sources}" ]]; then
echo "error: no java sources found in ${API_DIR}" >&2
exit 1
fi
references="$(echo "${sources}" \
| sed -E "s|^|${API_DIR}/|" \
| xargs grep -hoE 'org\.cyclops\.[A-Za-z0-9_.]+' \
| sed -E 's/\.$//' \
| sort -u)"

while IFS= read -r reference; do
[[ -n "${reference}" ]] || continue
class="$(top_level_class "${reference}")"

if [[ "${reference}" == org.cyclops.commoncapabilities.* ]]; then
if [[ "${reference}" != org.cyclops.commoncapabilities.api.* ]]; then
fail "${reference} lives in the CommonCapabilities mod, not in this API"
fi
continue
fi

if [[ "${reference}" == org.cyclops.cyclopscore.* ]]; then
if [[ -z "${class}" ]]; then
# A wildcard import or a bare package reference, nothing to resolve
continue
fi
if [[ -z "${CYCLOPSCORE_COMMON}" ]]; then
echo " skipping ${class}, no CyclopsCore checkout given" >&2
continue
fi
if [[ ! -f "${CYCLOPSCORE_COMMON}/${class//.//}.java" ]]; then
fail "${class} is not in CyclopsCore's loader-common, so it is loader-specific"
fi
continue
fi

fail "${reference} is not part of this API, CyclopsCore's loader-common, Minecraft or NeoForge"
done <<< "${references}"

if [[ "${failures}" -gt 0 ]]; then
echo "" >&2
echo "${failures} disallowed reference(s) found, this API is no longer self-contained." >&2
exit 1
fi

echo "This API is self-contained."
24 changes: 24 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: CI

on:
push:
pull_request:

jobs:
self-contained:
name: Check self-containment
runs-on: ubuntu-latest
steps:
- name: Checkout API
uses: actions/checkout@v4

- name: Checkout CyclopsCore
uses: actions/checkout@v4
with:
repository: CyclopsMC/CyclopsCore
# The branch that consumes this API branch as a submodule
ref: master-26
path: cyclopscore

- name: Check
run: .github/check-self-contained.sh cyclopscore
4 changes: 2 additions & 2 deletions capability/itemhandler/ItemMatch.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import net.minecraft.core.component.DataComponentMap;
import net.minecraft.world.item.ItemStack;
import org.cyclops.commoncapabilities.ingredient.DataComparator;
import org.cyclops.commoncapabilities.api.ingredient.IDataComparator;

/**
* Item matching flags to be used in {@link ISlotlessItemHandler}.
Expand Down Expand Up @@ -34,7 +34,7 @@ public final class ItemMatch {
/**
* A comparator for data components. (This is set in GeneralConfig)
*/
public static DataComparator DATA_COMPARATOR;
public static IDataComparator DATA_COMPARATOR;

public static boolean areItemStacksEqual(ItemStack a, ItemStack b, int matchFlags) {
if (matchFlags == ANY) {
Expand Down
3 changes: 1 addition & 2 deletions capability/recipehandler/RecipeDefinition.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import net.minecraft.world.level.Level;
import org.cyclops.commoncapabilities.api.ingredient.*;
import org.cyclops.cyclopscore.helper.IModHelpers;
import org.cyclops.cyclopscore.helper.IModHelpersNeoForge;

import javax.annotation.Nullable;
import java.util.*;
Expand Down Expand Up @@ -64,7 +63,7 @@ public RecipeDefinition(Map<IngredientComponent<?, ?>, List<IPrototypedIngredien
public static RecipeDefinition fromRecipeId(Level level, ResourceKey<Recipe<?>> recipeId) {
Optional<RecipeHolder<?>> recipeHolder;
if (IModHelpers.get().getMinecraftHelpers().isClientSide()) {
recipeHolder = Optional.ofNullable(IModHelpersNeoForge.get().getMinecraftClientHelpers().getRecipes().byKey(recipeId));
recipeHolder = Optional.ofNullable(IModHelpers.get().getMinecraftClientHelpers().getRecipes().byKey(recipeId));
} else {
recipeHolder = IModHelpers.get().getCraftingHelpers().getRecipeManager().byKey(recipeId);
}
Expand Down
18 changes: 18 additions & 0 deletions ingredient/IDataComparator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.cyclops.commoncapabilities.api.ingredient;

import net.minecraft.core.component.DataComponentMap;

import java.util.Comparator;

/**
* A comparator for data component maps that can ignore certain data component types.
* @author rubensworks
*/
public interface IDataComparator extends Comparator<DataComponentMap> {

/**
* @return If at least one data component type is being ignored.
*/
public boolean hasIgnoreDataComponentTypes();

}
Loading