implements packer PR-04 workspace scan and studio read adapter
This commit is contained in:
parent
12f2311d08
commit
924ab587e8
@ -0,0 +1,151 @@
|
||||
package p.packer.workspace;
|
||||
|
||||
import p.packer.api.PackerOperationClass;
|
||||
import p.packer.api.PackerOperationStatus;
|
||||
import p.packer.api.PackerProjectContext;
|
||||
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.api.workspace.InitWorkspaceRequest;
|
||||
import p.packer.api.workspace.InitWorkspaceResult;
|
||||
import p.packer.api.workspace.ListAssetsRequest;
|
||||
import p.packer.api.workspace.ListAssetsResult;
|
||||
import p.packer.api.workspace.PackerWorkspaceService;
|
||||
import p.packer.declarations.PackerAssetDeclarationParseResult;
|
||||
import p.packer.declarations.PackerAssetDeclarationParser;
|
||||
import p.packer.declarations.PackerAssetDetailsService;
|
||||
import p.packer.foundation.PackerRegistryEntry;
|
||||
import p.packer.foundation.PackerRegistryState;
|
||||
import p.packer.foundation.PackerWorkspaceFoundation;
|
||||
import p.packer.foundation.PackerWorkspacePaths;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public final class FileSystemPackerWorkspaceService implements PackerWorkspaceService {
|
||||
private final PackerWorkspaceFoundation workspaceFoundation;
|
||||
private final PackerAssetDeclarationParser parser;
|
||||
private final PackerAssetDetailsService detailsService;
|
||||
|
||||
public FileSystemPackerWorkspaceService() {
|
||||
this(new PackerWorkspaceFoundation(), new PackerAssetDeclarationParser());
|
||||
}
|
||||
|
||||
public FileSystemPackerWorkspaceService(
|
||||
PackerWorkspaceFoundation workspaceFoundation,
|
||||
PackerAssetDeclarationParser parser) {
|
||||
this.workspaceFoundation = Objects.requireNonNull(workspaceFoundation, "workspaceFoundation");
|
||||
this.parser = Objects.requireNonNull(parser, "parser");
|
||||
this.detailsService = new PackerAssetDetailsService(workspaceFoundation, parser);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PackerOperationClass operationClass() {
|
||||
return PackerOperationClass.READ_ONLY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InitWorkspaceResult initWorkspace(InitWorkspaceRequest request) {
|
||||
return workspaceFoundation.initWorkspace(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListAssetsResult listAssets(ListAssetsRequest request) {
|
||||
final PackerProjectContext project = Objects.requireNonNull(request, "request").project();
|
||||
final Path assetsRoot = PackerWorkspacePaths.assetsRoot(project);
|
||||
final PackerRegistryState registry = workspaceFoundation.loadRegistry(project);
|
||||
final Map<Path, PackerRegistryEntry> registryByRoot = new HashMap<>();
|
||||
for (PackerRegistryEntry entry : registry.assets()) {
|
||||
registryByRoot.put(PackerWorkspacePaths.assetRoot(project, entry.root()), entry);
|
||||
}
|
||||
|
||||
final List<PackerAssetSummary> assets = new ArrayList<>();
|
||||
final List<PackerDiagnostic> diagnostics = new ArrayList<>();
|
||||
final Set<Path> discoveredRoots = new HashSet<>();
|
||||
|
||||
if (Files.isDirectory(assetsRoot)) {
|
||||
try (Stream<Path> paths = Files.find(assetsRoot, Integer.MAX_VALUE, (path, attrs) ->
|
||||
attrs.isRegularFile() && path.getFileName().toString().equals("asset.json"))) {
|
||||
paths.forEach(assetManifestPath -> {
|
||||
final Path assetRoot = assetManifestPath.getParent().toAbsolutePath().normalize();
|
||||
discoveredRoots.add(assetRoot);
|
||||
final PackerRegistryEntry registryEntry = registryByRoot.get(assetRoot);
|
||||
final PackerAssetDeclarationParseResult parsed = parser.parse(assetManifestPath);
|
||||
diagnostics.addAll(parsed.diagnostics());
|
||||
assets.add(buildSummary(assetRoot, registryEntry, parsed));
|
||||
});
|
||||
} catch (IOException exception) {
|
||||
diagnostics.add(new PackerDiagnostic(
|
||||
PackerDiagnosticSeverity.ERROR,
|
||||
PackerDiagnosticCategory.STRUCTURAL,
|
||||
"Unable to scan assets workspace: " + exception.getMessage(),
|
||||
assetsRoot,
|
||||
true));
|
||||
}
|
||||
}
|
||||
|
||||
for (PackerRegistryEntry entry : registry.assets()) {
|
||||
final Path registeredRoot = PackerWorkspacePaths.assetRoot(project, entry.root());
|
||||
if (!discoveredRoots.contains(registeredRoot)) {
|
||||
diagnostics.add(new PackerDiagnostic(
|
||||
PackerDiagnosticSeverity.ERROR,
|
||||
PackerDiagnosticCategory.STRUCTURAL,
|
||||
"Registered asset root is missing asset.json: " + entry.root(),
|
||||
registeredRoot.resolve("asset.json"),
|
||||
true));
|
||||
}
|
||||
}
|
||||
|
||||
assets.sort(Comparator
|
||||
.comparing((PackerAssetSummary asset) -> asset.identity().assetRoot().toString(), String.CASE_INSENSITIVE_ORDER)
|
||||
.thenComparing(summary -> summary.identity().assetName(), String.CASE_INSENSITIVE_ORDER));
|
||||
final PackerOperationStatus status = diagnostics.stream().anyMatch(PackerDiagnostic::blocking)
|
||||
? PackerOperationStatus.PARTIAL
|
||||
: PackerOperationStatus.SUCCESS;
|
||||
return new ListAssetsResult(
|
||||
status,
|
||||
"Packer asset snapshot ready.",
|
||||
assets,
|
||||
diagnostics);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GetAssetDetailsResult getAssetDetails(GetAssetDetailsRequest request) {
|
||||
return detailsService.getAssetDetails(request);
|
||||
}
|
||||
|
||||
private PackerAssetSummary buildSummary(
|
||||
Path assetRoot,
|
||||
PackerRegistryEntry registryEntry,
|
||||
PackerAssetDeclarationParseResult parsed) {
|
||||
final String assetName = parsed.declaration() != null
|
||||
? parsed.declaration().name()
|
||||
: assetRoot.getFileName().toString();
|
||||
final String assetFamily = parsed.declaration() != null
|
||||
? parsed.declaration().type()
|
||||
: "unknown";
|
||||
final boolean preload = parsed.declaration() != null && parsed.declaration().preloadEnabled();
|
||||
final boolean hasDiagnostics = !parsed.diagnostics().isEmpty();
|
||||
final PackerAssetState state = parsed.valid()
|
||||
? (registryEntry == null ? PackerAssetState.ORPHAN : PackerAssetState.MANAGED)
|
||||
: PackerAssetState.INVALID;
|
||||
return new PackerAssetSummary(
|
||||
new PackerAssetIdentity(
|
||||
registryEntry == null ? null : registryEntry.assetId(),
|
||||
registryEntry == null ? null : registryEntry.assetUuid(),
|
||||
assetName,
|
||||
assetRoot),
|
||||
state,
|
||||
assetFamily,
|
||||
preload,
|
||||
hasDiagnostics);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,76 @@
|
||||
package p.packer.workspace;
|
||||
|
||||
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.ListAssetsRequest;
|
||||
import p.packer.testing.PackerFixtureLocator;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Comparator;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
final class FileSystemPackerWorkspaceServiceTest {
|
||||
@TempDir
|
||||
Path tempDir;
|
||||
|
||||
@Test
|
||||
void listsManagedAndOrphanAssetsFromWorkspaceScan() throws Exception {
|
||||
final Path projectRoot = copyFixture("workspaces/read-mixed", tempDir.resolve("mixed"));
|
||||
final FileSystemPackerWorkspaceService service = new FileSystemPackerWorkspaceService();
|
||||
|
||||
final var result = service.listAssets(new ListAssetsRequest(project(projectRoot)));
|
||||
|
||||
assertEquals(PackerOperationStatus.SUCCESS, result.status());
|
||||
assertEquals(2, result.assets().size());
|
||||
assertTrue(result.assets().stream().anyMatch(asset -> asset.state() == PackerAssetState.MANAGED));
|
||||
assertTrue(result.assets().stream().anyMatch(asset -> asset.state() == PackerAssetState.ORPHAN));
|
||||
}
|
||||
|
||||
@Test
|
||||
void surfacesMissingRegisteredRootAsStructuralDiagnostic() throws Exception {
|
||||
final Path projectRoot = copyFixture("workspaces/read-missing-root", tempDir.resolve("missing-root"));
|
||||
final FileSystemPackerWorkspaceService service = new FileSystemPackerWorkspaceService();
|
||||
|
||||
final var result = service.listAssets(new ListAssetsRequest(project(projectRoot)));
|
||||
|
||||
assertEquals(PackerOperationStatus.PARTIAL, result.status());
|
||||
assertTrue(result.diagnostics().stream().anyMatch(diagnostic -> diagnostic.message().contains("missing asset.json")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void includesInvalidDeclarationsInSnapshotWithDiagnostics() throws Exception {
|
||||
final Path projectRoot = copyFixture("workspaces/read-invalid", tempDir.resolve("invalid"));
|
||||
final FileSystemPackerWorkspaceService service = new FileSystemPackerWorkspaceService();
|
||||
|
||||
final var result = service.listAssets(new ListAssetsRequest(project(projectRoot)));
|
||||
|
||||
assertEquals(1, result.assets().size());
|
||||
assertEquals(PackerAssetState.INVALID, result.assets().getFirst().state());
|
||||
assertTrue(result.assets().getFirst().hasDiagnostics());
|
||||
}
|
||||
|
||||
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,11 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"type": "image_bank",
|
||||
"inputs": "wrong",
|
||||
"output": {
|
||||
"codec": ""
|
||||
},
|
||||
"preload": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"next_asset_id": 2,
|
||||
"assets": [
|
||||
{
|
||||
"asset_id": 1,
|
||||
"asset_uuid": "uuid-1",
|
||||
"root": "missing/atlas"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"next_asset_id": 2,
|
||||
"assets": [
|
||||
{
|
||||
"asset_id": 1,
|
||||
"asset_uuid": "uuid-1",
|
||||
"root": "ui/atlas"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"name": "ui_atlas",
|
||||
"type": "image_bank",
|
||||
"inputs": {
|
||||
"sprites": ["sprites/confirm.png"]
|
||||
},
|
||||
"output": {
|
||||
"format": "TILES/indexed_v1",
|
||||
"codec": "RAW"
|
||||
},
|
||||
"preload": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
@ -5,6 +5,7 @@ plugins {
|
||||
|
||||
dependencies {
|
||||
implementation(project(":prometeu-infra"))
|
||||
implementation(project(":prometeu-packer"))
|
||||
implementation(project(":prometeu-compiler:prometeu-compiler-core"))
|
||||
implementation(project(":prometeu-compiler:prometeu-build-pipeline"))
|
||||
implementation(project(":prometeu-compiler:prometeu-frontend-registry"))
|
||||
|
||||
@ -56,7 +56,7 @@ public final class AssetWorkspace implements Workspace {
|
||||
private String searchQuery = "";
|
||||
|
||||
public AssetWorkspace(ProjectReference projectReference) {
|
||||
this(projectReference, new FileSystemAssetWorkspaceService(), new FileSystemAssetWorkspaceMutationService());
|
||||
this(projectReference, new PackerBackedAssetWorkspaceService(), new FileSystemAssetWorkspaceMutationService());
|
||||
}
|
||||
|
||||
public AssetWorkspace(
|
||||
|
||||
@ -0,0 +1,101 @@
|
||||
package p.studio.workspaces.assets;
|
||||
|
||||
import p.packer.api.PackerProjectContext;
|
||||
import p.packer.api.assets.PackerAssetDetails;
|
||||
import p.packer.api.assets.PackerAssetState;
|
||||
import p.packer.api.assets.PackerAssetSummary;
|
||||
import p.packer.api.diagnostics.PackerDiagnostic;
|
||||
import p.packer.api.diagnostics.PackerDiagnosticSeverity;
|
||||
import p.packer.api.workspace.GetAssetDetailsRequest;
|
||||
import p.packer.api.workspace.ListAssetsRequest;
|
||||
import p.packer.workspace.FileSystemPackerWorkspaceService;
|
||||
import p.studio.projects.ProjectReference;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public final class PackerBackedAssetWorkspaceService implements AssetWorkspaceService {
|
||||
private final FileSystemPackerWorkspaceService packerWorkspaceService;
|
||||
|
||||
public PackerBackedAssetWorkspaceService() {
|
||||
this(new FileSystemPackerWorkspaceService());
|
||||
}
|
||||
|
||||
public PackerBackedAssetWorkspaceService(FileSystemPackerWorkspaceService packerWorkspaceService) {
|
||||
this.packerWorkspaceService = Objects.requireNonNull(packerWorkspaceService, "packerWorkspaceService");
|
||||
}
|
||||
|
||||
@Override
|
||||
public AssetWorkspaceSnapshot loadWorkspace(ProjectReference projectReference) {
|
||||
final var result = packerWorkspaceService.listAssets(new ListAssetsRequest(project(projectReference)));
|
||||
final List<AssetWorkspaceAssetSummary> assets = result.assets().stream()
|
||||
.map(this::mapSummary)
|
||||
.toList();
|
||||
return new AssetWorkspaceSnapshot(assets);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AssetWorkspaceAssetDetails loadAssetDetails(ProjectReference projectReference, AssetWorkspaceSelectionKey selectionKey) {
|
||||
final String assetReference = switch (selectionKey) {
|
||||
case AssetWorkspaceSelectionKey.ManagedAsset managedAsset -> Integer.toString(managedAsset.assetId());
|
||||
case AssetWorkspaceSelectionKey.OrphanAsset orphanAsset -> relativeAssetRoot(projectReference, orphanAsset.assetRoot());
|
||||
};
|
||||
final var result = packerWorkspaceService.getAssetDetails(new GetAssetDetailsRequest(project(projectReference), assetReference));
|
||||
return mapDetails(result.details());
|
||||
}
|
||||
|
||||
private AssetWorkspaceAssetSummary mapSummary(PackerAssetSummary summary) {
|
||||
final AssetWorkspaceAssetState state = toStudioState(summary);
|
||||
final AssetWorkspaceSelectionKey selectionKey = state == AssetWorkspaceAssetState.MANAGED
|
||||
? new AssetWorkspaceSelectionKey.ManagedAsset(summary.identity().assetId())
|
||||
: new AssetWorkspaceSelectionKey.OrphanAsset(summary.identity().assetRoot());
|
||||
return new AssetWorkspaceAssetSummary(
|
||||
selectionKey,
|
||||
summary.identity().assetName(),
|
||||
state,
|
||||
summary.identity().assetId(),
|
||||
summary.assetFamily(),
|
||||
summary.identity().assetRoot(),
|
||||
summary.preloadEnabled(),
|
||||
summary.hasDiagnostics());
|
||||
}
|
||||
|
||||
private AssetWorkspaceAssetDetails mapDetails(PackerAssetDetails details) {
|
||||
return new AssetWorkspaceAssetDetails(
|
||||
mapSummary(details.summary()),
|
||||
details.outputFormat(),
|
||||
details.outputCodec(),
|
||||
details.inputsByRole(),
|
||||
details.diagnostics().stream().map(this::mapDiagnostic).toList());
|
||||
}
|
||||
|
||||
private AssetWorkspaceDiagnostic mapDiagnostic(PackerDiagnostic diagnostic) {
|
||||
return new AssetWorkspaceDiagnostic(
|
||||
switch (diagnostic.severity()) {
|
||||
case ERROR -> AssetWorkspaceDiagnosticSeverity.BLOCKER;
|
||||
case WARNING -> AssetWorkspaceDiagnosticSeverity.WARNING;
|
||||
case INFO -> AssetWorkspaceDiagnosticSeverity.HINT;
|
||||
},
|
||||
diagnostic.message());
|
||||
}
|
||||
|
||||
private AssetWorkspaceAssetState toStudioState(PackerAssetSummary summary) {
|
||||
if (summary.state() == PackerAssetState.MANAGED) {
|
||||
return AssetWorkspaceAssetState.MANAGED;
|
||||
}
|
||||
return summary.identity().assetId() != null ? AssetWorkspaceAssetState.MANAGED : AssetWorkspaceAssetState.ORPHAN;
|
||||
}
|
||||
|
||||
private PackerProjectContext project(ProjectReference projectReference) {
|
||||
final ProjectReference reference = Objects.requireNonNull(projectReference, "projectReference");
|
||||
return new PackerProjectContext(reference.name(), reference.rootPath());
|
||||
}
|
||||
|
||||
private String relativeAssetRoot(ProjectReference projectReference, Path assetRoot) {
|
||||
return projectReference.rootPath().resolve("assets").toAbsolutePath().normalize()
|
||||
.relativize(assetRoot.toAbsolutePath().normalize())
|
||||
.toString()
|
||||
.replace('\\', '/');
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,93 @@
|
||||
package p.studio.workspaces.assets;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
import p.studio.projects.ProjectReference;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
final class PackerBackedAssetWorkspaceServiceTest {
|
||||
@TempDir
|
||||
Path tempDir;
|
||||
|
||||
@Test
|
||||
void loadsWorkspaceThroughPackerBackedSnapshot() throws Exception {
|
||||
final Path projectRoot = tempDir.resolve("main");
|
||||
final Path managedRoot = projectRoot.resolve("assets/ui/atlas");
|
||||
final Path orphanRoot = projectRoot.resolve("assets/orphans/ui_sounds");
|
||||
Files.createDirectories(managedRoot);
|
||||
Files.createDirectories(orphanRoot);
|
||||
Files.createDirectories(projectRoot.resolve("assets/.prometeu"));
|
||||
Files.writeString(managedRoot.resolve("asset.json"), """
|
||||
{
|
||||
"schema_version": 1,
|
||||
"name": "ui_atlas",
|
||||
"type": "image_bank",
|
||||
"inputs": { "sprites": ["sprites/confirm.png"] },
|
||||
"output": { "format": "TILES/indexed_v1", "codec": "RAW" },
|
||||
"preload": { "enabled": true }
|
||||
}
|
||||
""");
|
||||
Files.writeString(orphanRoot.resolve("asset.json"), """
|
||||
{
|
||||
"schema_version": 1,
|
||||
"name": "ui_sounds",
|
||||
"type": "sound_bank",
|
||||
"inputs": { "sources": ["confirm.wav"] },
|
||||
"output": { "format": "SOUND/bank_v1", "codec": "RAW" },
|
||||
"preload": { "enabled": false }
|
||||
}
|
||||
""");
|
||||
Files.writeString(projectRoot.resolve("assets/.prometeu/index.json"), """
|
||||
{
|
||||
"schema_version": 1,
|
||||
"next_asset_id": 2,
|
||||
"assets": [
|
||||
{
|
||||
"asset_id": 1,
|
||||
"asset_uuid": "uuid-1",
|
||||
"root": "ui/atlas"
|
||||
}
|
||||
]
|
||||
}
|
||||
""");
|
||||
|
||||
final PackerBackedAssetWorkspaceService service = new PackerBackedAssetWorkspaceService();
|
||||
|
||||
final AssetWorkspaceSnapshot snapshot = service.loadWorkspace(project("Main", projectRoot));
|
||||
|
||||
assertEquals(2, snapshot.assets().size());
|
||||
assertTrue(snapshot.assets().stream().anyMatch(asset -> asset.state() == AssetWorkspaceAssetState.MANAGED));
|
||||
assertTrue(snapshot.assets().stream().anyMatch(asset -> asset.state() == AssetWorkspaceAssetState.ORPHAN));
|
||||
}
|
||||
|
||||
@Test
|
||||
void mapsInvalidDetailsToStudioDiagnostics() throws Exception {
|
||||
final Path projectRoot = tempDir.resolve("main");
|
||||
final Path invalidRoot = projectRoot.resolve("assets/bad");
|
||||
Files.createDirectories(invalidRoot);
|
||||
Files.writeString(invalidRoot.resolve("asset.json"), """
|
||||
{
|
||||
"schema_version": 1,
|
||||
"type": "image_bank"
|
||||
}
|
||||
""");
|
||||
|
||||
final PackerBackedAssetWorkspaceService service = new PackerBackedAssetWorkspaceService();
|
||||
|
||||
final AssetWorkspaceAssetDetails details = service.loadAssetDetails(
|
||||
project("Main", projectRoot),
|
||||
new AssetWorkspaceSelectionKey.OrphanAsset(invalidRoot));
|
||||
|
||||
assertEquals("unknown", details.outputFormat());
|
||||
assertFalse(details.diagnostics().isEmpty());
|
||||
assertEquals(AssetWorkspaceDiagnosticSeverity.BLOCKER, details.diagnostics().getFirst().severity());
|
||||
}
|
||||
|
||||
private ProjectReference project(String name, Path root) {
|
||||
return new ProjectReference(name, "1.0.0", "pbs", 1, root);
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user