implements packer PR-03 declaration parsing and details
This commit is contained in:
parent
42e7331d62
commit
12f2311d08
@ -0,0 +1,29 @@
|
||||
package p.packer.declarations;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public record PackerAssetDeclaration(
|
||||
int schemaVersion,
|
||||
String name,
|
||||
String type,
|
||||
Map<String, List<String>> inputsByRole,
|
||||
String outputFormat,
|
||||
String outputCodec,
|
||||
boolean preloadEnabled) {
|
||||
|
||||
public PackerAssetDeclaration {
|
||||
if (schemaVersion <= 0) {
|
||||
throw new IllegalArgumentException("schemaVersion must be positive");
|
||||
}
|
||||
name = Objects.requireNonNull(name, "name").trim();
|
||||
type = Objects.requireNonNull(type, "type").trim();
|
||||
inputsByRole = Map.copyOf(Objects.requireNonNull(inputsByRole, "inputsByRole"));
|
||||
outputFormat = Objects.requireNonNull(outputFormat, "outputFormat").trim();
|
||||
outputCodec = Objects.requireNonNull(outputCodec, "outputCodec").trim();
|
||||
if (name.isBlank() || type.isBlank() || outputFormat.isBlank() || outputCodec.isBlank()) {
|
||||
throw new IllegalArgumentException("declaration fields must not be blank");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
package p.packer.declarations;
|
||||
|
||||
import p.packer.api.diagnostics.PackerDiagnostic;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public record PackerAssetDeclarationParseResult(
|
||||
PackerAssetDeclaration declaration,
|
||||
List<PackerDiagnostic> diagnostics) {
|
||||
|
||||
public PackerAssetDeclarationParseResult {
|
||||
diagnostics = List.copyOf(Objects.requireNonNull(diagnostics, "diagnostics"));
|
||||
}
|
||||
|
||||
public boolean valid() {
|
||||
return declaration != null && diagnostics.stream().noneMatch(PackerDiagnostic::blocking);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,140 @@
|
||||
package p.packer.declarations;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import p.packer.api.diagnostics.PackerDiagnostic;
|
||||
import p.packer.api.diagnostics.PackerDiagnosticCategory;
|
||||
import p.packer.api.diagnostics.PackerDiagnosticSeverity;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public final class PackerAssetDeclarationParser {
|
||||
private static final ObjectMapper MAPPER = new ObjectMapper();
|
||||
private static final int SUPPORTED_SCHEMA_VERSION = 1;
|
||||
|
||||
public PackerAssetDeclarationParseResult parse(Path assetManifestPath) {
|
||||
final Path manifestPath = Objects.requireNonNull(assetManifestPath, "assetManifestPath").toAbsolutePath().normalize();
|
||||
final List<PackerDiagnostic> diagnostics = new ArrayList<>();
|
||||
final JsonNode root;
|
||||
try {
|
||||
root = MAPPER.readTree(manifestPath.toFile());
|
||||
} catch (IOException exception) {
|
||||
diagnostics.add(new PackerDiagnostic(
|
||||
PackerDiagnosticSeverity.ERROR,
|
||||
PackerDiagnosticCategory.STRUCTURAL,
|
||||
"Unable to parse asset.json: " + exception.getMessage(),
|
||||
manifestPath,
|
||||
true));
|
||||
return new PackerAssetDeclarationParseResult(null, diagnostics);
|
||||
}
|
||||
|
||||
final Integer schemaVersion = requiredInt(root, "schema_version", diagnostics, manifestPath);
|
||||
final String name = requiredText(root, "name", diagnostics, manifestPath);
|
||||
final String type = requiredText(root, "type", diagnostics, manifestPath);
|
||||
final Map<String, List<String>> inputsByRole = requiredInputs(root.path("inputs"), diagnostics, manifestPath);
|
||||
final String outputFormat = requiredText(root.path("output"), "format", diagnostics, manifestPath);
|
||||
final String outputCodec = requiredText(root.path("output"), "codec", diagnostics, manifestPath);
|
||||
final Boolean preloadEnabled = requiredBoolean(root.path("preload"), "enabled", diagnostics, manifestPath);
|
||||
|
||||
if (schemaVersion != null && schemaVersion != SUPPORTED_SCHEMA_VERSION) {
|
||||
diagnostics.add(new PackerDiagnostic(
|
||||
PackerDiagnosticSeverity.ERROR,
|
||||
PackerDiagnosticCategory.VERSIONING,
|
||||
"Unsupported asset.json schema_version: " + schemaVersion,
|
||||
manifestPath,
|
||||
true));
|
||||
}
|
||||
|
||||
if (diagnostics.stream().anyMatch(PackerDiagnostic::blocking)) {
|
||||
return new PackerAssetDeclarationParseResult(null, diagnostics);
|
||||
}
|
||||
|
||||
return new PackerAssetDeclarationParseResult(
|
||||
new PackerAssetDeclaration(
|
||||
schemaVersion,
|
||||
name,
|
||||
type,
|
||||
inputsByRole,
|
||||
outputFormat,
|
||||
outputCodec,
|
||||
preloadEnabled),
|
||||
diagnostics);
|
||||
}
|
||||
|
||||
private Integer requiredInt(JsonNode node, String fieldName, List<PackerDiagnostic> diagnostics, Path manifestPath) {
|
||||
final JsonNode field = node.path(fieldName);
|
||||
if (!field.isInt()) {
|
||||
diagnostics.add(missingOrInvalid(fieldName, "integer", manifestPath));
|
||||
return null;
|
||||
}
|
||||
return field.intValue();
|
||||
}
|
||||
|
||||
private String requiredText(JsonNode node, String fieldName, List<PackerDiagnostic> diagnostics, Path manifestPath) {
|
||||
final JsonNode field = node.path(fieldName);
|
||||
if (!field.isTextual() || field.asText().isBlank()) {
|
||||
diagnostics.add(missingOrInvalid(fieldName, "non-blank string", manifestPath));
|
||||
return null;
|
||||
}
|
||||
return field.asText().trim();
|
||||
}
|
||||
|
||||
private Boolean requiredBoolean(JsonNode node, String fieldName, List<PackerDiagnostic> diagnostics, Path manifestPath) {
|
||||
final JsonNode field = node.path(fieldName);
|
||||
if (!field.isBoolean()) {
|
||||
diagnostics.add(missingOrInvalid(fieldName, "boolean", manifestPath));
|
||||
return null;
|
||||
}
|
||||
return field.booleanValue();
|
||||
}
|
||||
|
||||
private Map<String, List<String>> requiredInputs(JsonNode inputsNode, List<PackerDiagnostic> diagnostics, Path manifestPath) {
|
||||
if (!inputsNode.isObject()) {
|
||||
diagnostics.add(missingOrInvalid("inputs", "object of input roles", manifestPath));
|
||||
return Map.of();
|
||||
}
|
||||
|
||||
final Map<String, List<String>> result = new LinkedHashMap<>();
|
||||
inputsNode.fields().forEachRemaining(entry -> {
|
||||
if (!entry.getValue().isArray()) {
|
||||
diagnostics.add(new PackerDiagnostic(
|
||||
PackerDiagnosticSeverity.ERROR,
|
||||
PackerDiagnosticCategory.STRUCTURAL,
|
||||
"Input role '" + entry.getKey() + "' must be an array of relative paths.",
|
||||
manifestPath,
|
||||
true));
|
||||
return;
|
||||
}
|
||||
final List<String> values = new ArrayList<>();
|
||||
entry.getValue().forEach(value -> {
|
||||
if (!value.isTextual() || value.asText().isBlank()) {
|
||||
diagnostics.add(new PackerDiagnostic(
|
||||
PackerDiagnosticSeverity.ERROR,
|
||||
PackerDiagnosticCategory.STRUCTURAL,
|
||||
"Input role '" + entry.getKey() + "' must contain only non-blank path strings.",
|
||||
manifestPath,
|
||||
true));
|
||||
return;
|
||||
}
|
||||
values.add(value.asText().trim());
|
||||
});
|
||||
result.put(entry.getKey(), List.copyOf(values));
|
||||
});
|
||||
return Map.copyOf(result);
|
||||
}
|
||||
|
||||
private PackerDiagnostic missingOrInvalid(String fieldName, String expected, Path manifestPath) {
|
||||
return new PackerDiagnostic(
|
||||
PackerDiagnosticSeverity.ERROR,
|
||||
PackerDiagnosticCategory.STRUCTURAL,
|
||||
"Field '" + fieldName + "' must be a " + expected + ".",
|
||||
manifestPath,
|
||||
true);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,172 @@
|
||||
package p.packer.declarations;
|
||||
|
||||
import p.packer.api.PackerOperationStatus;
|
||||
import p.packer.api.PackerProjectContext;
|
||||
import p.packer.api.assets.PackerAssetDetails;
|
||||
import p.packer.api.assets.PackerAssetIdentity;
|
||||
import p.packer.api.assets.PackerAssetState;
|
||||
import p.packer.api.assets.PackerAssetSummary;
|
||||
import p.packer.api.diagnostics.PackerDiagnostic;
|
||||
import p.packer.api.diagnostics.PackerDiagnosticCategory;
|
||||
import p.packer.api.diagnostics.PackerDiagnosticSeverity;
|
||||
import p.packer.api.workspace.GetAssetDetailsRequest;
|
||||
import p.packer.api.workspace.GetAssetDetailsResult;
|
||||
import p.packer.foundation.PackerRegistryEntry;
|
||||
import p.packer.foundation.PackerRegistryLookup;
|
||||
import p.packer.foundation.PackerRegistryState;
|
||||
import p.packer.foundation.PackerWorkspaceFoundation;
|
||||
import p.packer.foundation.PackerWorkspacePaths;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
public final class PackerAssetDetailsService {
|
||||
private final PackerWorkspaceFoundation workspaceFoundation;
|
||||
private final PackerAssetDeclarationParser parser;
|
||||
|
||||
public PackerAssetDetailsService() {
|
||||
this(new PackerWorkspaceFoundation(), new PackerAssetDeclarationParser());
|
||||
}
|
||||
|
||||
public PackerAssetDetailsService(
|
||||
PackerWorkspaceFoundation workspaceFoundation,
|
||||
PackerAssetDeclarationParser parser) {
|
||||
this.workspaceFoundation = Objects.requireNonNull(workspaceFoundation, "workspaceFoundation");
|
||||
this.parser = Objects.requireNonNull(parser, "parser");
|
||||
}
|
||||
|
||||
public GetAssetDetailsResult getAssetDetails(GetAssetDetailsRequest request) {
|
||||
final PackerProjectContext project = Objects.requireNonNull(request, "request").project();
|
||||
final PackerRegistryState registry = workspaceFoundation.loadRegistry(project);
|
||||
final ResolvedAssetReference resolved = resolveReference(project, registry, request.assetReference());
|
||||
final Path manifestPath = resolved.assetRoot().resolve("asset.json");
|
||||
final List<PackerDiagnostic> diagnostics = new ArrayList<>(resolved.diagnostics());
|
||||
|
||||
if (!Files.isRegularFile(manifestPath)) {
|
||||
diagnostics.add(new PackerDiagnostic(
|
||||
PackerDiagnosticSeverity.ERROR,
|
||||
PackerDiagnosticCategory.STRUCTURAL,
|
||||
"asset.json was not found for the requested asset root.",
|
||||
manifestPath,
|
||||
true));
|
||||
return failureResult(resolved, diagnostics);
|
||||
}
|
||||
|
||||
final PackerAssetDeclarationParseResult parsed = parser.parse(manifestPath);
|
||||
diagnostics.addAll(parsed.diagnostics());
|
||||
if (!parsed.valid()) {
|
||||
return failureResult(resolved, diagnostics);
|
||||
}
|
||||
|
||||
final PackerAssetDeclaration declaration = parsed.declaration();
|
||||
final PackerAssetSummary summary = new PackerAssetSummary(
|
||||
new PackerAssetIdentity(
|
||||
resolved.registryEntry().map(PackerRegistryEntry::assetId).orElse(null),
|
||||
resolved.registryEntry().map(PackerRegistryEntry::assetUuid).orElse(null),
|
||||
declaration.name(),
|
||||
resolved.assetRoot()),
|
||||
resolved.registryEntry().isPresent() ? PackerAssetState.MANAGED : PackerAssetState.ORPHAN,
|
||||
declaration.type(),
|
||||
declaration.preloadEnabled(),
|
||||
!diagnostics.isEmpty());
|
||||
final PackerAssetDetails details = new PackerAssetDetails(
|
||||
summary,
|
||||
declaration.outputFormat(),
|
||||
declaration.outputCodec(),
|
||||
resolveInputs(resolved.assetRoot(), declaration.inputsByRole()),
|
||||
diagnostics);
|
||||
return new GetAssetDetailsResult(
|
||||
diagnostics.isEmpty() ? PackerOperationStatus.SUCCESS : PackerOperationStatus.PARTIAL,
|
||||
"Asset details resolved from packer declaration state.",
|
||||
details,
|
||||
diagnostics);
|
||||
}
|
||||
|
||||
private GetAssetDetailsResult failureResult(ResolvedAssetReference resolved, List<PackerDiagnostic> diagnostics) {
|
||||
final PackerAssetSummary summary = new PackerAssetSummary(
|
||||
new PackerAssetIdentity(
|
||||
resolved.registryEntry().map(PackerRegistryEntry::assetId).orElse(null),
|
||||
resolved.registryEntry().map(PackerRegistryEntry::assetUuid).orElse(null),
|
||||
resolved.assetRoot().getFileName().toString(),
|
||||
resolved.assetRoot()),
|
||||
PackerAssetState.INVALID,
|
||||
"unknown",
|
||||
false,
|
||||
true);
|
||||
final PackerAssetDetails details = new PackerAssetDetails(summary, "unknown", "unknown", Map.of(), diagnostics);
|
||||
return new GetAssetDetailsResult(
|
||||
PackerOperationStatus.FAILED,
|
||||
"Asset declaration is invalid or unreadable.",
|
||||
details,
|
||||
diagnostics);
|
||||
}
|
||||
|
||||
private Map<String, List<Path>> resolveInputs(Path assetRoot, Map<String, List<String>> inputsByRole) {
|
||||
final Map<String, List<Path>> resolved = new LinkedHashMap<>();
|
||||
inputsByRole.forEach((role, inputs) -> resolved.put(
|
||||
role,
|
||||
inputs.stream().map(input -> assetRoot.resolve(input).toAbsolutePath().normalize()).toList()));
|
||||
return Map.copyOf(resolved);
|
||||
}
|
||||
|
||||
private ResolvedAssetReference resolveReference(PackerProjectContext project, PackerRegistryState registry, String reference) {
|
||||
final PackerRegistryLookup lookup = workspaceFoundation.lookup();
|
||||
final Optional<PackerRegistryEntry> byId = parseAssetId(reference).flatMap(assetId -> lookup.findByAssetId(registry, assetId));
|
||||
if (byId.isPresent()) {
|
||||
return new ResolvedAssetReference(
|
||||
PackerWorkspacePaths.assetRoot(project, byId.get().root()),
|
||||
byId,
|
||||
List.of());
|
||||
}
|
||||
|
||||
final Optional<PackerRegistryEntry> byUuid = lookup.findByAssetUuid(registry, reference);
|
||||
if (byUuid.isPresent()) {
|
||||
return new ResolvedAssetReference(
|
||||
PackerWorkspacePaths.assetRoot(project, byUuid.get().root()),
|
||||
byUuid,
|
||||
List.of());
|
||||
}
|
||||
|
||||
final Path candidateRoot = PackerWorkspacePaths.assetRoot(project, reference);
|
||||
if (Files.isDirectory(candidateRoot) || Files.isRegularFile(candidateRoot.resolve("asset.json"))) {
|
||||
return new ResolvedAssetReference(candidateRoot, lookup.findByRoot(project, registry, candidateRoot), List.of());
|
||||
}
|
||||
|
||||
final Path missingRoot = candidateRoot;
|
||||
return new ResolvedAssetReference(
|
||||
missingRoot,
|
||||
Optional.empty(),
|
||||
List.of(new PackerDiagnostic(
|
||||
PackerDiagnosticSeverity.ERROR,
|
||||
PackerDiagnosticCategory.STRUCTURAL,
|
||||
"Requested asset reference could not be resolved.",
|
||||
missingRoot,
|
||||
true)));
|
||||
}
|
||||
|
||||
private Optional<Integer> parseAssetId(String reference) {
|
||||
try {
|
||||
return Optional.of(Integer.parseInt(reference.trim()));
|
||||
} catch (NumberFormatException ignored) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
private record ResolvedAssetReference(
|
||||
Path assetRoot,
|
||||
Optional<PackerRegistryEntry> registryEntry,
|
||||
List<PackerDiagnostic> diagnostics) {
|
||||
|
||||
private ResolvedAssetReference {
|
||||
assetRoot = Objects.requireNonNull(assetRoot, "assetRoot").toAbsolutePath().normalize();
|
||||
registryEntry = Objects.requireNonNull(registryEntry, "registryEntry");
|
||||
diagnostics = List.copyOf(Objects.requireNonNull(diagnostics, "diagnostics"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,51 @@
|
||||
package p.packer.declarations;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import p.packer.api.diagnostics.PackerDiagnosticCategory;
|
||||
import p.packer.testing.PackerFixtureLocator;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
final class PackerAssetDeclarationParserTest {
|
||||
private final PackerAssetDeclarationParser parser = new PackerAssetDeclarationParser();
|
||||
|
||||
@Test
|
||||
void parsesValidDeclarationFixture() {
|
||||
final var result = parser.parse(PackerFixtureLocator.fixtureRoot("workspaces/managed-basic/assets/ui/atlas/asset.json"));
|
||||
|
||||
assertTrue(result.valid());
|
||||
assertNotNull(result.declaration());
|
||||
assertEquals(1, result.declaration().schemaVersion());
|
||||
assertEquals("ui_atlas", result.declaration().name());
|
||||
assertEquals("image_bank", result.declaration().type());
|
||||
assertEquals("TILES/indexed_v1", result.declaration().outputFormat());
|
||||
assertEquals("RAW", result.declaration().outputCodec());
|
||||
assertTrue(result.declaration().preloadEnabled());
|
||||
}
|
||||
|
||||
@Test
|
||||
void rejectsMalformedJsonWithStructuralDiagnostic() {
|
||||
final var result = parser.parse(PackerFixtureLocator.fixtureRoot("workspaces/invalid-malformed/assets/bad/asset.json"));
|
||||
|
||||
assertFalse(result.valid());
|
||||
assertNull(result.declaration());
|
||||
assertTrue(result.diagnostics().stream().anyMatch(diagnostic -> diagnostic.category() == PackerDiagnosticCategory.STRUCTURAL));
|
||||
}
|
||||
|
||||
@Test
|
||||
void rejectsMissingRequiredFields() {
|
||||
final var result = parser.parse(PackerFixtureLocator.fixtureRoot("workspaces/invalid-missing-fields/assets/bad/asset.json"));
|
||||
|
||||
assertFalse(result.valid());
|
||||
assertTrue(result.diagnostics().stream().anyMatch(diagnostic -> diagnostic.message().contains("name")));
|
||||
assertTrue(result.diagnostics().stream().anyMatch(diagnostic -> diagnostic.message().contains("format")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void rejectsUnsupportedSchemaVersion() {
|
||||
final var result = parser.parse(PackerFixtureLocator.fixtureRoot("workspaces/invalid-version/assets/bad/asset.json"));
|
||||
|
||||
assertFalse(result.valid());
|
||||
assertTrue(result.diagnostics().stream().anyMatch(diagnostic -> diagnostic.category() == PackerDiagnosticCategory.VERSIONING));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,90 @@
|
||||
package p.packer.declarations;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
import p.packer.api.PackerOperationStatus;
|
||||
import p.packer.api.PackerProjectContext;
|
||||
import p.packer.api.assets.PackerAssetState;
|
||||
import p.packer.api.workspace.GetAssetDetailsRequest;
|
||||
import p.packer.testing.PackerFixtureLocator;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Comparator;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
final class PackerAssetDetailsServiceTest {
|
||||
@TempDir
|
||||
Path tempDir;
|
||||
|
||||
@Test
|
||||
void returnsManagedDetailsForRegisteredAssetReferenceById() throws Exception {
|
||||
final Path projectRoot = copyFixture("workspaces/managed-basic", tempDir.resolve("managed"));
|
||||
final PackerAssetDetailsService service = new PackerAssetDetailsService();
|
||||
|
||||
final var result = service.getAssetDetails(new GetAssetDetailsRequest(project(projectRoot), "1"));
|
||||
|
||||
assertEquals(PackerOperationStatus.SUCCESS, result.status());
|
||||
assertEquals(PackerAssetState.MANAGED, result.details().summary().state());
|
||||
assertEquals("ui_atlas", result.details().summary().identity().assetName());
|
||||
assertEquals("TILES/indexed_v1", result.details().outputFormat());
|
||||
assertTrue(result.diagnostics().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
void returnsOrphanDetailsForValidUnregisteredRootReference() throws Exception {
|
||||
final Path projectRoot = copyFixture("workspaces/orphan-valid", tempDir.resolve("orphan"));
|
||||
final PackerAssetDetailsService service = new PackerAssetDetailsService();
|
||||
|
||||
final var result = service.getAssetDetails(new GetAssetDetailsRequest(project(projectRoot), "orphans/ui_sounds"));
|
||||
|
||||
assertEquals(PackerOperationStatus.SUCCESS, result.status());
|
||||
assertEquals(PackerAssetState.ORPHAN, result.details().summary().state());
|
||||
assertEquals("ui_sounds", result.details().summary().identity().assetName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void returnsInvalidDetailsForInvalidDeclaration() throws Exception {
|
||||
final Path projectRoot = copyFixture("workspaces/invalid-missing-fields", tempDir.resolve("invalid"));
|
||||
final PackerAssetDetailsService service = new PackerAssetDetailsService();
|
||||
|
||||
final var result = service.getAssetDetails(new GetAssetDetailsRequest(project(projectRoot), "bad"));
|
||||
|
||||
assertEquals(PackerOperationStatus.FAILED, result.status());
|
||||
assertEquals(PackerAssetState.INVALID, result.details().summary().state());
|
||||
assertFalse(result.diagnostics().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
void returnsFailureWhenReferenceCannotBeResolved() {
|
||||
final PackerAssetDetailsService service = new PackerAssetDetailsService();
|
||||
|
||||
final var result = service.getAssetDetails(new GetAssetDetailsRequest(project(tempDir.resolve("empty")), "missing/root"));
|
||||
|
||||
assertEquals(PackerOperationStatus.FAILED, result.status());
|
||||
assertEquals(PackerAssetState.INVALID, result.details().summary().state());
|
||||
assertTrue(result.diagnostics().stream().anyMatch(diagnostic -> diagnostic.message().contains("could not be resolved")));
|
||||
}
|
||||
|
||||
private PackerProjectContext project(Path root) {
|
||||
return new PackerProjectContext("main", root);
|
||||
}
|
||||
|
||||
private Path copyFixture(String relativePath, Path targetRoot) throws Exception {
|
||||
final Path sourceRoot = PackerFixtureLocator.fixtureRoot(relativePath);
|
||||
try (var stream = Files.walk(sourceRoot)) {
|
||||
for (Path source : stream.sorted(Comparator.naturalOrder()).toList()) {
|
||||
final Path target = targetRoot.resolve(sourceRoot.relativize(source).toString());
|
||||
if (Files.isDirectory(source)) {
|
||||
Files.createDirectories(target);
|
||||
} else {
|
||||
Files.createDirectories(target.getParent());
|
||||
Files.copy(source, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
return targetRoot;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
{ nope
|
||||
@ -0,0 +1,11 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"type": "image_bank",
|
||||
"inputs": "wrong",
|
||||
"output": {
|
||||
"codec": ""
|
||||
},
|
||||
"preload": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
{
|
||||
"schema_version": 9,
|
||||
"name": "future_asset",
|
||||
"type": "image_bank",
|
||||
"inputs": {
|
||||
"sprites": ["future.png"]
|
||||
},
|
||||
"output": {
|
||||
"format": "TILES/indexed_v1",
|
||||
"codec": "RAW"
|
||||
},
|
||||
"preload": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"name": "ui_sounds",
|
||||
"type": "sound_bank",
|
||||
"inputs": {
|
||||
"sources": ["confirm.wav"]
|
||||
},
|
||||
"output": {
|
||||
"format": "SOUND/bank_v1",
|
||||
"codec": "RAW"
|
||||
},
|
||||
"preload": {
|
||||
"enabled": false
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user