-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
lint: collect unused files #22
base: master
Are you sure you want to change the base?
Changes from 6 commits
8f274b0
010cf6f
83602ea
8460b42
02a4c9a
07ed3a8
5c70bc6
20de275
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
module.exports = function collectFiles(flow, callback){ | ||
var stack = [flow.files.queue[0]]; | ||
var collectedFiles = {}; | ||
var handled = new WeakSet(); | ||
var cursor; | ||
|
||
while (cursor = stack.pop()) | ||
{ | ||
// mark file as handled | ||
handled.add(cursor); | ||
callback(cursor); | ||
cursor.linkTo.forEach(function(link){ | ||
// prevent handling files that are already handled | ||
if (link[0] && !handled.has(link[0])) { | ||
stack.push(link[0]); | ||
} | ||
}); | ||
} | ||
|
||
return collectedFiles; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
var path = require('path'); | ||
var fs = require('fs'); | ||
|
||
module.exports = function(base, extFilter){ | ||
var stack = [base]; | ||
var cursor; | ||
var collectedFiles = {}; | ||
|
||
while (cursor = stack.pop()) | ||
{ | ||
if (!fs.existsSync(cursor)) | ||
continue; | ||
|
||
var stat = fs.lstatSync(cursor); | ||
|
||
if (stat.isSymbolicLink()) | ||
{ | ||
var resolvedLink = path.resolve(cursor, fs.readlinkSync(cursor)); | ||
|
||
stack.push(resolvedLink); | ||
} | ||
else if (stat.isDirectory()) | ||
{ | ||
var items = fs.readdirSync(cursor); | ||
|
||
for (var i = 0; i < items.length; i++) | ||
stack.push(path.join(cursor, items[i])); | ||
} | ||
else | ||
{ | ||
if (extFilter) | ||
{ | ||
var fileExt = path.extname(cursor); | ||
|
||
if (fileExt.toLowerCase() === extFilter.toLowerCase()) | ||
collectedFiles[cursor] = true; | ||
} | ||
else | ||
collectedFiles[cursor] = true; | ||
} | ||
} | ||
|
||
return collectedFiles; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
var collectFiles = require('../helpers/fs-files-collector'); | ||
|
||
module.exports = function handleUnusedFiles(tasks){ | ||
var basePaths = {}; | ||
var usedFiles = {}; | ||
var unusedFiles = {}; | ||
|
||
// merge used files from tasks | ||
tasks.forEach(function(task){ | ||
if (task.result.usedFiles) | ||
{ | ||
basePaths[task.result.usedFiles.collectPath] = true; | ||
task.result.usedFiles.items.forEach(function(filename){ | ||
usedFiles[task.result.usedFiles.basePath + filename] = true; | ||
}); | ||
} | ||
}); | ||
|
||
if (Object.keys(basePaths).length) | ||
{ | ||
var task = { name: 'unused files', result: { warnings: [] } }; | ||
|
||
// collect unused files | ||
for (var basePath in basePaths) | ||
{ | ||
var files = collectFiles(basePath); | ||
|
||
for (var fileName in files) | ||
if (!usedFiles.hasOwnProperty(fileName)) | ||
unusedFiles[fileName] = true; | ||
} | ||
|
||
// warn about unused files | ||
for (var unusedFile in unusedFiles) | ||
{ | ||
unusedFile = unusedFile.slice(process.cwd().length); | ||
task.result.warnings.push({ | ||
file: unusedFile | ||
}); | ||
} | ||
|
||
tasks.push(task); | ||
} | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
var flowFilesCollector = require('../helpers/flow-file-collector'); | ||
var collectFiles = require('../helpers/fs-files-collector'); | ||
|
||
function isTarget(basePath, collectPath, file){ | ||
return file.filename && (basePath + file.filename).indexOf(collectPath + '/') === 0; | ||
} | ||
|
||
exports.collectUsed = function(flow){ | ||
var options = flow.options; | ||
var basePath = options.base; | ||
var collectPath = flow.files.abspath(basePath, options.warnUnusedFiles); | ||
var usedFiles = {}; | ||
|
||
flowFilesCollector(flow, function(file){ | ||
if (isTarget(basePath, collectPath, file)) | ||
usedFiles[file.filename] = true; | ||
|
||
if (file.type == 'template') | ||
{ | ||
if (file.decl.deps) | ||
{ | ||
file.decl.deps.forEach(function(resource){ | ||
if (!resource.virtual && isTarget(basePath, collectPath, { filename: resource.url })) | ||
usedFiles[resource.url] = true; | ||
}); | ||
} | ||
if (file.decl.l10n) | ||
{ | ||
file.decl.l10n.forEach(function(item){ | ||
var l10nInfo = item.split('@'); | ||
var dictFilename = l10nInfo[1]; | ||
|
||
if (isTarget(basePath, collectPath, { filename: dictFilename })) | ||
usedFiles[dictFilename] = true; | ||
}); | ||
} | ||
if (file.decl.styles) | ||
{ | ||
file.decl.styles.forEach(function(style){ | ||
if (!style.resource && isTarget(basePath, collectPath, { filename: style.sourceUrl })) | ||
usedFiles[style.sourceUrl] = true; | ||
}); | ||
} | ||
} | ||
}); | ||
|
||
return { | ||
basePath: basePath, | ||
collectPath: collectPath, | ||
items: Object.keys(usedFiles) | ||
}; | ||
}; | ||
|
||
exports.warn = function(flow){ | ||
if (flow.options.warnUnusedFiles && flow.usedFiles) | ||
{ | ||
var usedFilesInfo = flow.usedFiles; | ||
var usedFiles = {}; | ||
var basePath = usedFilesInfo.collectPath; | ||
var collectedFiles = collectFiles(basePath); | ||
|
||
usedFilesInfo.items.forEach(function(filename){ | ||
usedFiles[usedFilesInfo.basePath + filename] = true; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. cause it will affect |
||
}); | ||
|
||
for (var usedFile in usedFiles) | ||
delete collectedFiles[usedFile]; | ||
|
||
for (var unusedName in collectedFiles) { | ||
unusedName = unusedName.slice(process.cwd().length); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
flow.warn({ | ||
file: 'unused files', | ||
message: unusedName | ||
}); | ||
} | ||
} | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this loop doesn't needed and
unusedFiles
map is redundant