Skip to content

Commit 328a58a

Browse files
committed
Revert "refactor: use path.join from stdlib instead of custom join (isomorphic-git#1861)"
This reverts commit bbcdda7.
1 parent 6445267 commit 328a58a

File tree

5 files changed

+95
-36
lines changed

5 files changed

+95
-36
lines changed

__tests__/test-utils-join.js

Lines changed: 55 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ const path = require('path').posix || require('path')
44
const { join } = require('isomorphic-git/internal-apis')
55

66
describe('utils/join', () => {
7-
describe('when "internal join" generates paths the same as "path.join"', () => {
8-
// Tests adapted from path-browserify
7+
it('should join "good" paths the same as path.join', async () => {
98
const fixtures = [
109
['/foo/bar', 'baz'],
1110
['foo/bar', 'baz'],
@@ -19,39 +18,60 @@ describe('utils/join', () => {
1918
['/', '.'],
2019
['/', '.git'],
2120
['.', '.git'],
22-
[],
23-
['foo/x', './bar'],
24-
['foo/x/', './bar'],
25-
['foo/x/', '.', 'bar'],
26-
['.', '.', '.'],
27-
['.', './', '.'],
28-
['.', '/./', '.'],
29-
['.', '/////./', '.'],
30-
['.'],
31-
['', '.'],
32-
['foo', '/bar'],
33-
['foo', ''],
34-
['foo', '', '/bar'],
35-
['/'],
36-
['/', '.'],
37-
[''],
38-
['', ''],
39-
['', 'foo'],
40-
['', '', 'foo'],
41-
[' /foo'],
42-
[' ', 'foo'],
43-
[' ', '.'],
44-
[' ', ''],
45-
['/', '/foo'],
46-
['/', '//foo'],
47-
['/', '', '/foo'],
4821
]
49-
fixtures.forEach(fixture => {
50-
it(`"${JSON.stringify(fixture)}" should join to "${path.join(
51-
...fixture
52-
)}"`, () => {
53-
expect(join(...fixture)).toEqual(path.join(...fixture))
54-
})
55-
})
22+
for (const fixture of fixtures) {
23+
expect(join(...fixture)).toEqual(path.join(...fixture))
24+
}
25+
})
26+
it('should join degenerate paths the same as path.join in these cases', async () => {
27+
// Tests adapted from path-browserify
28+
const fixtures = [
29+
[[], '.'],
30+
[['foo/x', './bar'], 'foo/x/bar'],
31+
[['foo/x/', './bar'], 'foo/x/bar'],
32+
[['foo/x/', '.', 'bar'], 'foo/x/bar'],
33+
[['.', '.', '.'], '.'],
34+
[['.', './', '.'], '.'],
35+
[['.', '/./', '.'], '.'],
36+
[['.', '/////./', '.'], '.'],
37+
[['.'], '.'],
38+
[['', '.'], '.'],
39+
[['foo', '/bar'], 'foo/bar'],
40+
[['foo', ''], 'foo'],
41+
[['foo', '', '/bar'], 'foo/bar'],
42+
[['/'], '/'],
43+
[['/', '.'], '/'],
44+
[[''], '.'],
45+
[['', ''], '.'],
46+
[['', 'foo'], 'foo'],
47+
[['', '', 'foo'], 'foo'],
48+
[[' /foo'], ' /foo'],
49+
[[' ', 'foo'], ' /foo'],
50+
[[' ', '.'], ' '],
51+
[[' ', ''], ' '],
52+
[['/', '/foo'], '/foo'],
53+
[['/', '//foo'], '/foo'],
54+
[['/', '', '/foo'], '/foo'],
55+
]
56+
for (const [args, result] of fixtures) {
57+
expect(join(...args)).toEqual(result)
58+
expect(join(...args)).toEqual(path.join(...args))
59+
}
60+
})
61+
it('should join degenerate paths differently from path.join in these cases', async () => {
62+
// Tests adapted from path-browserify
63+
const disagreeFixtures = [
64+
[['./'], '.'],
65+
[['.', './'], '.'],
66+
[['', '/foo'], 'foo'],
67+
[['', '', '/foo'], 'foo'],
68+
[['foo/', ''], 'foo'],
69+
[['', '/', 'foo'], 'foo'],
70+
[['', '/', '/foo'], 'foo'],
71+
]
72+
for (const [args, result] of disagreeFixtures) {
73+
expect(join(...args)).toEqual(result)
74+
expect(join(...args)).not.toEqual(path.join(...args))
75+
}
5676
})
5777
})

src/internal-apis.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export * from './utils/mergeFile'
4141
export * from './utils/mergeTree'
4242
export * from './utils/modified'
4343
export * from './utils/padHex'
44+
export * from './utils/path'
4445
export * from './utils/pkg'
4546
export * from './utils/resolveTree'
4647
export * from './utils/shasum'

src/utils/join.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,7 @@
1-
export { join } from 'path'
1+
// For some reason path.posix.join is undefined in webpack
2+
// Also, this is just much smaller
3+
import { normalizePath } from './normalizePath.js'
4+
5+
export function join(...parts) {
6+
return normalizePath(parts.map(normalizePath).join('/'))
7+
}

src/utils/normalizePath.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
const memo = new Map()
2+
export function normalizePath(path) {
3+
let normalizedPath = memo.get(path)
4+
if (!normalizedPath) {
5+
normalizedPath = normalizePathInternal(path)
6+
memo.set(path, normalizedPath)
7+
}
8+
return normalizedPath
9+
}
10+
11+
function normalizePathInternal(path) {
12+
path = path
13+
.split('/./')
14+
.join('/') // Replace '/./' with '/'
15+
.replace(/\/{2,}/g, '/') // Replace consecutive '/'
16+
17+
if (path === '/.') return '/' // if path === '/.' return '/'
18+
if (path === './') return '.' // if path === './' return '.'
19+
20+
if (path.startsWith('./')) path = path.slice(2) // Remove leading './'
21+
if (path.endsWith('/.')) path = path.slice(0, -2) // Remove trailing '/.'
22+
if (path.length > 1 && path.endsWith('/')) path = path.slice(0, -1) // Remove trailing '/'
23+
24+
if (path === '') return '.' // if path === '' return '.'
25+
26+
return path
27+
}

src/utils/path.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// This module is necessary because Webpack doesn't ship with
2+
// a version of path-browserify that includes path.posix, yet path-browserify IS path.posix
3+
import _path from 'path'
4+
5+
export const path = _path.posix === undefined ? _path : _path.posix

0 commit comments

Comments
 (0)