Skip to content
Open
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
69 changes: 67 additions & 2 deletions packages/databricks-vscode/src/bundle/BundleFileSet.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ describe(__filename, async function () {
await tmpdir.cleanup();
});

function getWorkspaceFolderManagerMock() {
function getWorkspaceFolderManagerMock(projectDir?: string) {
const mockWorkspaceFolderManager = mock<WorkspaceFolderManager>();
const mockWorkspaceFolder = mock<WorkspaceFolder>();
const uri = Uri.file(tmpdir.path);
const uri = Uri.file(projectDir ?? tmpdir.path);
when(mockWorkspaceFolder.uri).thenReturn(uri);
when(mockWorkspaceFolderManager.activeWorkspaceFolder).thenReturn(
instance(mockWorkspaceFolder)
Expand Down Expand Up @@ -73,6 +73,71 @@ describe(__filename, async function () {
expect(await bundleFileSet.getRootFile()).to.be.undefined;
});

describe("parent-directory includes", async () => {
it("getIncludedFiles should find files referenced via .. paths", async () => {
// Structure: tmpdir/shared/config.yml (included), tmpdir/project/sub/ (project root)
const sharedDir = path.join(tmpdir.path, "shared");
const projectDir = path.join(tmpdir.path, "project", "sub");
await fs.mkdir(sharedDir, {recursive: true});
await fs.mkdir(projectDir, {recursive: true});

const sharedFile = path.join(sharedDir, "config.yml");
const sharedFile2 = path.join(sharedDir, "config2.yml");
await fs.writeFile(sharedFile, "");
await fs.writeFile(sharedFile2, "");

const rootBundleData: BundleSchema = {
include: ["../../shared/config.yml", "../../shared/config2.yml"],
};
await fs.writeFile(
path.join(projectDir, "databricks.yml"),
yaml.stringify(rootBundleData)
);

const bundleFileSet = new BundleFileSet(
getWorkspaceFolderManagerMock(projectDir)
);

const files = await bundleFileSet.getIncludedFiles();
expect(files).to.not.be.undefined;
expect(files!.map((f) => f.fsPath).sort()).to.deep.equal(
[sharedFile, sharedFile2].sort()
);
});

it("isIncludedBundleFile should return true for files referenced via .. paths", async () => {
const sharedDir = path.join(tmpdir.path, "shared");
const projectDir = path.join(tmpdir.path, "project", "sub");
await fs.mkdir(sharedDir, {recursive: true});
await fs.mkdir(projectDir, {recursive: true});

const sharedFile = path.join(sharedDir, "config.yml");
await fs.writeFile(sharedFile, "");

const rootBundleData: BundleSchema = {
include: ["../../shared/config.yml", "local.yml"],
};
await fs.writeFile(
path.join(projectDir, "databricks.yml"),
yaml.stringify(rootBundleData)
);

const bundleFileSet = new BundleFileSet(
getWorkspaceFolderManagerMock(projectDir)
);

expect(
await bundleFileSet.isIncludedBundleFile(Uri.file(sharedFile))
).to.be.true;

expect(
await bundleFileSet.isIncludedBundleFile(
Uri.file(path.join(projectDir, "other.yml"))
)
).to.be.false;
});
});

describe("file listing", async () => {
beforeEach(async () => {
const rootBundleData: BundleSchema = {
Expand Down
65 changes: 40 additions & 25 deletions packages/databricks-vscode/src/bundle/BundleFileSet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,33 +88,47 @@ export class BundleFileSet {
return Uri.file(rootFile[0]);
}

async getIncludedFilesGlob() {
private async getIncludePatterns(): Promise<string[]> {
const rootFile = await this.getRootFile();
if (rootFile === undefined) {
return undefined;
return [];
}
const bundle = await parseBundleYaml(rootFile);
if (!bundle?.include?.length) {
return [];
}
const bundle = await parseBundleYaml(Uri.file(rootFile.fsPath));
if (bundle?.include === undefined || bundle?.include.length === 0) {
return bundle.include;
}

async getIncludedFilesGlob() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it used anywhere now?

const patterns = await this.getIncludePatterns();
if (patterns.length === 0) {
return undefined;
}
if (bundle?.include.length === 1) {
return bundle.include[0];
if (patterns.length === 1) {
return patterns[0];
}
return `{${bundle.include.join(",")}}`;
return `{${patterns.join(",")}}`;
}

async getIncludedFiles() {
const includedFilesGlob = await this.getIncludedFilesGlob();
if (includedFilesGlob !== undefined) {
return (
await glob.glob(
toGlobPath(
path.join(this.projectRoot.fsPath, includedFilesGlob)
),
{nocase: process.platform === "win32"}
)
).map((i) => Uri.file(i));
const patterns = await this.getIncludePatterns();
if (patterns.length === 0) {
return undefined;
}

const allFiles: string[] = [];
for (const pattern of patterns) {
const absolutePattern = toGlobPath(
path.resolve(this.projectRoot.fsPath, pattern)
);
const files = await glob.glob(absolutePattern, {
nocase: process.platform === "win32",
});
allFiles.push(...files);
}

return [...new Set(allFiles)].map((f) => Uri.file(f));
}

async allFiles() {
Expand Down Expand Up @@ -152,15 +166,16 @@ export class BundleFileSet {
}

async isIncludedBundleFile(e: Uri) {
let includedFilesGlob = await this.getIncludedFilesGlob();
if (includedFilesGlob === undefined) {
return false;
const patterns = await this.getIncludePatterns();
for (const pattern of patterns) {
const absolutePattern = toGlobPath(
path.resolve(this.projectRoot.fsPath, pattern)
);
if (minimatch(toGlobPath(e.fsPath), absolutePattern)) {
return true;
}
}
includedFilesGlob = getAbsoluteGlobPath(
includedFilesGlob,
this.projectRoot
);
return minimatch(e.fsPath, toGlobPath(includedFilesGlob));
return false;
}

async isBundleFile(e: Uri) {
Expand Down