Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FIX] Do not prefix excludes when creating a reader #504

Merged
merged 7 commits into from
May 22, 2023
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
28 changes: 24 additions & 4 deletions lib/resourceFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import Resource from "./Resource.js";
import WriterCollection from "./WriterCollection.js";
import Filter from "./readers/Filter.js";
import Link from "./readers/Link.js";
import {getLogger} from "@ui5/logger";
const log = getLogger("resources:resourceFactory");

/**
* @module @ui5/fs/resourceFactory
Expand Down Expand Up @@ -58,14 +60,32 @@ export function createAdapter({fsBasePath, virBasePath, project, excludes, useGi
* @returns {@ui5/fs/ReaderCollection} Reader collection wrapping an adapter
*/
export function createReader({fsBasePath, virBasePath, project, excludes = [], name}) {
const normalizedExcludes = excludes.map((pattern) => {
return prefixGlobPattern(pattern, virBasePath);
});
if (!fsBasePath) {
// Creating a reader with a memory adapter seems pointless right now
// since there would be no way to fill the adapter with resources
throw new Error(`Unable to create reader: Missing parameter "fsBasePath"`);
}
let normalizedExcludes = excludes;
// If a project is supplied, and that project is of type application,
// Prefix all exclude patterns with the virtual base path (unless it already starts with that)
// TODO 4.0: // TODO specVersion 4.0: Disallow excludes without namespaced prefix in configuration
// Specifying an exclude for "/test" is disambigous as it neither reflects the source path nor the
// ui5 runtime path of the excluded resources. Therefore, only allow paths like /resources/<namespace>/test
// starting with specVersion 4.0
if (excludes.length && project && project.getType() === "application") {
normalizedExcludes = excludes.map((pattern) => {
if (pattern.startsWith(virBasePath) || pattern.startsWith("!" + virBasePath)) {
return pattern;
}
log.verbose(
`Prefixing exclude pattern defined in application project ${project.getName()}: ${pattern}`);
return prefixGlobPattern(pattern, virBasePath);
});
// Flatten list of patterns
normalizedExcludes = Array.prototype.concat.apply([], normalizedExcludes);
log.verbose(`Effective exclude patterns for application project ${project.getName()}:\n` +
normalizedExcludes.join(", "));
}
return new ReaderCollection({
name,
readers: [createAdapter({
Expand Down Expand Up @@ -256,5 +276,5 @@ export function prefixGlobPattern(virPattern, virBaseDir) {
}
resultGlobs.push(resultPattern);
}
return Array.prototype.concat.apply([], resultGlobs);
return resultGlobs;
}
87 changes: 84 additions & 3 deletions test/lib/resourceFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,22 @@ test("createAdapter: Memory", async (t) => {
t.is(resources[0].getPath(), "/resources/app/File.js", "Found correct resource");
});

test("createReader", async (t) => {
test("createReader: application project", async (t) => {
const reader = createReader({
fsBasePath: "./test/fixtures/application.a/webapp",
virBasePath: "/resources/app/",
project: {
getName: () => "my.project"
getName: () => "my.project",
getType: () => "application"
},
excludes: ["**/*.html"],
excludes: [
"**/*.html",
"/resources/app/test/**",
"/test/**",
"test/**",
"!/resources/app/test/**",
"!/test/**/*.html"
],
name: "reader name"
});

Expand All @@ -105,6 +113,79 @@ test("createReader", async (t) => {
const resources = await reader.byGlob("**/*");
t.is(resources.length, 1, "Found one resource");
t.is(resources[0].getPath(), "/resources/app/test.js", "Found correct resource");

t.deepEqual(reader._readers[0]._excludes, [
"/resources/app/**/*.html",
"/resources/app/test/**", // Was already prefixed correctly
"/resources/app/test/**",
"/resources/app/test/**",
"!/resources/app/test/**",
"!/resources/app/test/**/*.html",
], "Some excludes got prefixed.");
});

test("createReader: library project", async (t) => {
const reader = createReader({
fsBasePath: "./test/fixtures/application.a/webapp",
virBasePath: "/resources/lib/",
project: {
getName: () => "my.project",
getType: () => "library"
},
excludes: [
"**/*.html",
"/resources/lib/dir/**",
"/test-resources/lib/dir/**",
"/test/**",
"test/**"
],
name: "reader name"
});

t.true(reader instanceof ReaderCollection, "Returned a ReaderCollection");
t.is(reader._name, "reader name", "Reader has correct name");

const resources = await reader.byGlob("**/*");
t.is(resources.length, 1, "Found one resource");
t.is(resources[0].getPath(), "/resources/lib/test.js", "Found correct resource");

t.deepEqual(reader._readers[0]._excludes, [
"**/*.html",
"/resources/lib/dir/**",
"/test-resources/lib/dir/**",
"/test/**",
"test/**",
], "Excludes do not get prefixed.");
});

test("createReader: No project", async (t) => {
const reader = createReader({
fsBasePath: "./test/fixtures/application.a/webapp",
virBasePath: "/resources/app/",
excludes: [
"**/*.html",
"/resources/app/dir/**",
"/test-resources/app/dir/**",
"/test/**",
"test/**"
],
name: "reader name"
});

t.true(reader instanceof ReaderCollection, "Returned a ReaderCollection");
t.is(reader._name, "reader name", "Reader has correct name");

const resources = await reader.byGlob("**/*");
t.is(resources.length, 1, "Found one resource");
t.is(resources[0].getPath(), "/resources/app/test.js", "Found correct resource");

t.deepEqual(reader._readers[0]._excludes, [
"**/*.html",
"/resources/app/dir/**",
"/test-resources/app/dir/**",
"/test/**",
"test/**"
], "Excludes do not get prefixed.");
});

test("createReader: Throw error missing 'fsBasePath'", (t) => {
Expand Down