Skip to content

Commit b5dd2b4

Browse files
authored
feat: add support for files and folders beginning with a dot (#206)
1 parent f28c984 commit b5dd2b4

2 files changed

Lines changed: 123 additions & 3 deletions

File tree

src/upload-helper.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ export class UploadHelper {
123123
metadata?: Metadata,
124124
): Promise<UploadResponse[]> {
125125
// by default we just use directoryPath with empty glob '', which globby evaluates to directory/**/*
126-
const filesList = await globby([path.posix.join(directoryPath, glob)]);
126+
const filesList = await expandGlob(directoryPath, glob);
127127
const uploader = async (filePath: string): Promise<UploadResponse> => {
128128
const destination = await getDestinationFromPath(
129129
filePath,
@@ -145,3 +145,34 @@ export class UploadHelper {
145145
return await pMap(filesList, uploader, { concurrency });
146146
}
147147
}
148+
149+
/**
150+
* expandGlob compiles the list of all files in the given directory for
151+
* the provided glob.
152+
*
153+
* @param directoryPath The path to the directory.
154+
* @param glob Glob pattern to use for searching. If the empty string, a
155+
* match-all pattern is used instead.
156+
* @return Sorted list of files in posix form.
157+
*/
158+
export async function expandGlob(
159+
directoryPath: string,
160+
glob: string,
161+
): Promise<string[]> {
162+
const pth = toPosixPath(path.posix.join(directoryPath, glob));
163+
const filesList = await globby([pth], {
164+
dot: true,
165+
});
166+
return filesList.sort();
167+
}
168+
169+
/**
170+
* toPosixPath converts the given path to the posix form. On Windows, \\ will be
171+
* replaced with /.
172+
*
173+
* @param pth. Path to transform.
174+
* @return Posix-path.
175+
*/
176+
export function toPosixPath(pth: string): string {
177+
return pth.split(path.sep).join(path.posix.sep);
178+
}

tests/upload-helper.test.ts

Lines changed: 91 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,11 @@
1717
import 'mocha';
1818
import { expect } from 'chai';
1919

20-
import * as sinon from 'sinon';
20+
import { promises as fs } from 'fs';
21+
import * as os from 'os';
2122
import * as path from 'path';
23+
import * as sinon from 'sinon';
24+
2225
import { Storage, Bucket } from '@google-cloud/storage';
2326

2427
import {
@@ -33,7 +36,7 @@ import {
3336
TXT_FILES_IN_DIR,
3437
TXT_FILES_IN_TOP_DIR,
3538
} from './constants.test';
36-
import { UploadHelper } from '../src/upload-helper';
39+
import { UploadHelper, expandGlob, toPosixPath } from '../src/upload-helper';
3740
/**
3841
* Unit Test uploadFile method in uploadHelper.
3942
*/
@@ -216,6 +219,7 @@ describe('Unit Test uploadDir', function () {
216219
expect(destination.split('/')[0]).eq(EXAMPLE_PREFIX);
217220
});
218221
});
222+
219223
it('uploads a dir at bucket root with globstar txt', async function () {
220224
const uploader = new UploadHelper(new Storage());
221225
await uploader.uploadDirectory(
@@ -272,3 +276,88 @@ describe('Unit Test uploadDir', function () {
272276
expect(destinations).to.have.members(TXT_FILES_IN_TOP_DIR);
273277
});
274278
});
279+
280+
describe('#expandGlob', () => {
281+
beforeEach(async function () {
282+
// Make a temporary directory and make the path relative to cwd, then make
283+
// it posix.
284+
const tmp = os.tmpdir();
285+
this.tmpdir = await fs.mkdtemp(path.join(tmp, 'gha-'));
286+
this.tmpdir = path.relative(process.cwd(), this.tmpdir);
287+
});
288+
289+
afterEach(async function () {
290+
if (this.tmpdir) {
291+
try {
292+
// TODO(sethvargo): switch to just fs.rm once we upgrade to Node 16
293+
// only. This function is deprecated in 16, but the replacement doesn't
294+
// exist in 12.
295+
await fs.rmdir(this.tmpdir, { recursive: true });
296+
} catch (err) {
297+
console.error(`failed to remove directory: ${err}`);
298+
}
299+
}
300+
});
301+
302+
it('returns the empty list when the directory is empty', async function () {
303+
const list = await expandGlob(this.tmpdir, '');
304+
expect(list).to.eql([]);
305+
});
306+
307+
it('returns one file', async function () {
308+
const a = path.join(this.tmpdir, 'a');
309+
await fs.writeFile(a, 'test');
310+
const list = await expandGlob(this.tmpdir, '');
311+
expect(list).to.eql([toPosixPath(a)]);
312+
});
313+
314+
it('returns multiple files', async function () {
315+
const a = path.join(this.tmpdir, 'a');
316+
await fs.writeFile(a, 'test');
317+
318+
const b = path.join(this.tmpdir, 'b');
319+
await fs.writeFile(b, 'test');
320+
321+
const list = await expandGlob(this.tmpdir, '');
322+
expect(list).to.eql([toPosixPath(a), toPosixPath(b)]);
323+
});
324+
325+
it('returns files in subdirectories', async function () {
326+
const a = path.join(this.tmpdir, 'a');
327+
await fs.writeFile(a, 'test');
328+
329+
const pth = path.join(this.tmpdir, 'sub', 'directory');
330+
await fs.mkdir(pth, { recursive: true });
331+
const b = path.join(pth, 'b');
332+
await fs.writeFile(b, 'test');
333+
334+
const list = await expandGlob(this.tmpdir, '');
335+
expect(list).to.eql([toPosixPath(a), toPosixPath(b)]);
336+
});
337+
338+
it('returns files beginning with a dot', async function () {
339+
const a = path.join(this.tmpdir, '.a');
340+
await fs.writeFile(a, 'test');
341+
342+
const pth = path.join(this.tmpdir, 'sub', 'directory');
343+
await fs.mkdir(pth, { recursive: true });
344+
const b = path.join(pth, '.b');
345+
await fs.writeFile(b, 'test');
346+
347+
const list = await expandGlob(this.tmpdir, '');
348+
expect(list).to.eql([toPosixPath(a), toPosixPath(b)]);
349+
});
350+
351+
it('returns files with non-ascii characters', async function () {
352+
const a = path.join(this.tmpdir, '🚀');
353+
await fs.writeFile(a, 'test');
354+
355+
const pth = path.join(this.tmpdir, 'sub', 'directory');
356+
await fs.mkdir(pth, { recursive: true });
357+
const b = path.join(pth, '.🚀');
358+
await fs.writeFile(b, 'test');
359+
360+
const list = await expandGlob(this.tmpdir, '');
361+
expect(list).to.eql([toPosixPath(b), toPosixPath(a)]);
362+
});
363+
});

0 commit comments

Comments
 (0)