From 8851e0f19b69ef46947b81250ad64391c1bfe09d Mon Sep 17 00:00:00 2001 From: mrmlnc Date: Fri, 21 Feb 2020 23:17:55 +0300 Subject: [PATCH] refactor(utils): add leading dot segment removal utility --- src/utils/path.spec.ts | 19 +++++++++++++++++++ src/utils/path.ts | 15 +++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/src/utils/path.spec.ts b/src/utils/path.spec.ts index 5c290d2c..d8a588e9 100644 --- a/src/utils/path.spec.ts +++ b/src/utils/path.spec.ts @@ -54,4 +54,23 @@ describe('Utils → Path', () => { assert.strictEqual(util.escape('abc@'), 'abc@'); }); }); + + describe('.removeLeadingDotCharacters', () => { + it('should return path without changes', () => { + assert.strictEqual(util.removeLeadingDotSegment('../a/b'), '../a/b'); + assert.strictEqual(util.removeLeadingDotSegment('~/a/b'), '~/a/b'); + assert.strictEqual(util.removeLeadingDotSegment('/a/b'), '/a/b'); + assert.strictEqual(util.removeLeadingDotSegment('a/b'), 'a/b'); + + assert.strictEqual(util.removeLeadingDotSegment('..\\a\\b'), '..\\a\\b'); + assert.strictEqual(util.removeLeadingDotSegment('~\\a\\b'), '~\\a\\b'); + assert.strictEqual(util.removeLeadingDotSegment('\\a\\b'), '\\a\\b'); + assert.strictEqual(util.removeLeadingDotSegment('a\\b'), 'a\\b'); + }); + + it('should return path without leading dit characters', () => { + assert.strictEqual(util.removeLeadingDotSegment('./a/b'), 'a/b'); + assert.strictEqual(util.removeLeadingDotSegment('.\\a\\b'), 'a\\b'); + }); + }); }); diff --git a/src/utils/path.ts b/src/utils/path.ts index 02e33030..3a6e9951 100644 --- a/src/utils/path.ts +++ b/src/utils/path.ts @@ -2,6 +2,7 @@ import * as path from 'path'; import { Pattern } from '../types'; +const LEADING_DOT_SEGMENT_CHARACTERS_COUNT = 2; // ./ or .\\ const UNESCAPED_GLOB_SYMBOLS_RE = /(\\?)([()*?[\]{|}]|^!|[!+@](?=\())/g; /** @@ -18,3 +19,17 @@ export function makeAbsolute(cwd: string, filepath: string): string { export function escape(pattern: Pattern): Pattern { return pattern.replace(UNESCAPED_GLOB_SYMBOLS_RE, '\\$2'); } + +export function removeLeadingDotSegment(entry: string): string { + // We do not use `startsWith` because this is 10x slower than current implementation for some cases. + // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with + if (entry.charAt(0) === '.') { + const secondCharactery = entry.charAt(1); + + if (secondCharactery === '/' || secondCharactery === '\\') { + return entry.slice(LEADING_DOT_SEGMENT_CHARACTERS_COUNT); + } + } + + return entry; +}