-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTrim.js
More file actions
138 lines (120 loc) · 4.27 KB
/
Trim.js
File metadata and controls
138 lines (120 loc) · 4.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import { join, relative } from 'node:path'
import { toPosixPath } from '@dr-js/core/module/node/fs/Path.js'
import { getDirInfoTree, getFileList } from '@dr-js/core/module/node/fs/Directory.js'
import { modifyDelete } from '@dr-js/core/module/node/fs/Modify.js'
const getRelativePosixFileList = async (pathRoot) => getFileList(pathRoot, (fileList, { path }) => {
fileList.push(toPosixPath(`./${relative(pathRoot, path)}`))
})
const trimEmptyFolder = async (
pathRootFolder
) => {
const trimFolderList = []
let found = false
do {
found = false
const { root, dirInfoListMap } = await getDirInfoTree(pathRootFolder) // TODO: just search & mark the same dirInfoListMap
for (const [ path, dirInfoList ] of dirInfoListMap.entries()) {
if (dirInfoList.length || path === root) continue
trimFolderList.push(path)
await modifyDelete(path)
found = true
}
} while (found)
return trimFolderList
}
const trimFile = async ( // TODO: NOTE: now only file will get deleted, may leave some empty folder
pathRoot,
shouldTrim = (relativeFile) => false // return true to trim
) => {
const relativeFileList = await getRelativePosixFileList(pathRoot)
const trimFileList = []
for (const relativeFile of relativeFileList) {
if (!shouldTrim(relativeFile)) continue
trimFileList.push(relativeFile)
await modifyDelete(join(pathRoot, relativeFile))
}
return trimFileList
}
// from: https://github.com/tj/node-prune/blob/v1.2.0/internal/prune/prune.go
// also: https://superuser.com/questions/126290/find-files-filtered-by-multiple-extensions
const shouldTrimNodeModules = (relativeFile) => {
relativeFile = relativeFile.toLowerCase()
// special keep
for (const mark of [
'/.bin/',
'/.local-chromium/'
]) if (relativeFile.includes(mark)) return false
// trim all dot file & folder
if (relativeFile.includes('/.')) return true
// directory
for (const pattern of [
// common pattern to remove
'/test/', '/tests/', '/__tests__/', '/powered-test/',
'/doc/', '/docs/',
'/example/', '/examples/',
'/coverage/', '/coverages/'
// trim for specific package
// '/ajv/dist/',
// '/bluebird/js/browser/',
// '/uri-js/dist/esnext/'
]) if (relativeFile.includes(pattern)) return true
// file
for (const pattern of [
// common extension to remove
'.md', '.mkd', '.markdown',
'.test.js', '.spec.js',
'.conf.js', '.config.js', '.config.json',
'.ts', '.jst', '.coffee',
'.map',
'.css', '.html', '.htm',
'.tgz', '.swp',
'.c', '.cc', '.cpp', '.h',
'.bat', '.cmd',
// file name
'/makefile', '/configure',
'/readme', '/changelog', '/changes',
'/authors', '/contributors',
'/package-lock.json', '/yarn.lock'
]) if (relativeFile.endsWith(pattern)) return true
return false // keep
}
const shouldTrimRubyGem = (relativeFile) => {
relativeFile = relativeFile.toLowerCase()
// keep all `lib` file (to keep file like `rspec-rails-6.0.1/lib/rspec/rails/example/channel_example_group.rb`)
if (relativeFile.includes('/lib/')) return false
// trim all dot file & folder
if (relativeFile.includes('/.')) return true
// directory
for (const pattern of [
// common pattern to remove
'/doc/', '/docs/',
'/test/', '/tests/',
'/spec/', '/specs/',
'/example/', '/examples/',
'/coverage/', '/coverages/',
'/benchmark/', '/benchmarks/',
'/tmp/'
]) if (relativeFile.includes(pattern)) return true
// file
for (const pattern of [
// common extension to remove
'.md', '.mkd', '.markdown',
'.rdoc',
'.c', '.cc', '.cpp', '.h',
'.bat', '.cmd',
// '.gemspec', // TODO: no use only if under "ruby/a.b.c/gems/"
// file name
'/gemfile', '/rakefile', '/brewfile', '/gemfile.lock', // https://stackoverflow.com/questions/7919913/are-you-supposed-to-include-gemfile-lock-in-a-published-gem
'/makefile', '/configure',
'/readme', '/changelog', '/changes',
'/authors', '/contributors'
]) if (relativeFile.endsWith(pattern)) return true
return false // keep
}
const trimFileNodeModules = async (pathNodeModules) => trimFile(pathNodeModules, shouldTrimNodeModules)
const trimFileRubyGem = async (pathRubyGem) => trimFile(pathRubyGem, shouldTrimRubyGem)
export {
trimEmptyFolder,
trimFile,
trimFileNodeModules, trimFileRubyGem
}