-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
29d4831
commit 73ba13e
Showing
14 changed files
with
395 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,3 +8,4 @@ examples | |
.gitignore | ||
.prettierignore | ||
.prettierrc | ||
assets |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
const path = require('path'); | ||
const { default: readdir } = require('../../src/readdir'); | ||
|
||
const sourceDirectory = path.join(__dirname, '..', '..', 'src'); | ||
const sourceDirectories = [sourceDirectory]; | ||
|
||
describe('readdir', () => { | ||
test('should list all files recursively', async () => { | ||
const files = await readdir(sourceDirectories); | ||
expect(files[0].sort()).toEqual([ | ||
path.join(sourceDirectory, 'index.js'), | ||
path.join(sourceDirectory, 'readdir', 'index.js'), | ||
path.join(sourceDirectory, 'reporter', 'index.js'), | ||
path.join(sourceDirectory, 'resolver', 'index.js'), | ||
]); | ||
}); | ||
}); |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
#!/usr/bin/env node | ||
/* eslint-disable */ | ||
require = require('esm')(module); | ||
module.exports = require('./src/index'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import path from 'path'; | ||
import yargs from 'yargs'; | ||
import ora from 'ora'; | ||
import { filesReport, dependenciesReport } from './reporter'; | ||
import resolve from './resolver'; | ||
import readdir from './readdir'; | ||
|
||
const { argv } = yargs.array('sourceDirectories'); | ||
|
||
const { | ||
projectRoot: relativeRoot = process.cwd(), | ||
sourceDirectories = [], | ||
} = argv; | ||
|
||
const projectRoot = path.resolve(relativeRoot); | ||
const manifest = require(path.join(projectRoot, 'package.json')); | ||
|
||
if (!sourceDirectories.length) { | ||
process.stderr.write('Missing required argument --sourceDirectories\n'); | ||
process.exit(1); | ||
} | ||
|
||
const spinner = ora('Looking for remnants').start(); | ||
|
||
const { usedFiles, usedDependencies } = resolve(projectRoot); | ||
|
||
(async () => { | ||
const files = await readdir(sourceDirectories); | ||
const unusedDependencies = [ | ||
...Object.keys(manifest.dependencies || {}), | ||
].filter(item => !usedDependencies[item]); | ||
const unusedFiles = files.map(item => item.filter(filePath => !usedFiles[path.join(projectRoot, filePath)])); | ||
spinner.stop(); | ||
filesReport(projectRoot, sourceDirectories, unusedFiles); | ||
dependenciesReport(unusedDependencies); | ||
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import recursive from 'recursive-readdir'; | ||
|
||
export default (sources, exclude) => Promise.all(sources.map(directory => recursive(directory, exclude))); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import path from 'path'; | ||
import chalk from 'chalk'; | ||
|
||
export const filesReport = ( | ||
projectRoot, | ||
sourceDirectories, | ||
filesByDirectory, | ||
) => { | ||
const allFiles = filesByDirectory.reduce( | ||
(array, item) => array.concat(item), | ||
[], | ||
); | ||
if (!allFiles.length) { | ||
process.stdout.write(chalk.green('\n✅ No unused source files found\n')); | ||
return; | ||
} | ||
process.stdout.write( | ||
chalk.red(`\n❌ ${allFiles.length} unused source files found.\n`), | ||
); | ||
filesByDirectory.forEach((files, index) => { | ||
const directory = sourceDirectories[index]; | ||
const relative = path.relative(projectRoot, directory); | ||
process.stdout.write(chalk.blue(`\n● ${relative}\n`)); | ||
files.map(file => process.stdout.write( | ||
chalk.yellow(` • ${path.relative(directory, file)}\n`), | ||
)); | ||
}); | ||
}; | ||
|
||
export const dependenciesReport = (unusedDependencies) => { | ||
if (!unusedDependencies.length) { | ||
process.stdout.write(chalk.green('\n✅ No unused dependencies found.\n')); | ||
return; | ||
} | ||
process.stdout.write( | ||
chalk.red( | ||
`\n❌ ${unusedDependencies.length} unused dependencies found.\n\n`, | ||
), | ||
); | ||
unusedDependencies.forEach(dep => process.stdout.write(chalk.yellow(` • ${dep}\n`))); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import path from 'path'; | ||
import fs from 'fs'; | ||
import { compose } from 'conductor'; | ||
|
||
const extensions = ['.js', '.json', '.graphql', '.jsx']; | ||
const imageExtensions = ['.png', '.jpg', '.jpeg']; | ||
const indexFiles = [ | ||
'index.js', | ||
'index.android.js', | ||
'index.ios.js', | ||
'index.web.js', | ||
]; | ||
const importRegex = /from '(.*)'/g; | ||
const requireRegex = /require\('(.*)'\)/g; | ||
const commentRegex = /\/\/.*|\/\*.*\*\//g; | ||
const graphqlImportRegex = /#import "(.*)"/g; | ||
const usedFiles = {}; | ||
const usedDependencies = {}; | ||
|
||
const withExtensions = absolutePath => extensions.map(extension => `${absolutePath}${extension}`); | ||
const withIndex = absolutePath => indexFiles.map(file => path.join(absolutePath, file)); | ||
|
||
const resolve = sourcePath => (relativePath) => { | ||
const absolutePath = path.join(sourcePath, relativePath); | ||
let paths = []; | ||
// isFile | ||
try { | ||
fs.readdirSync(absolutePath); | ||
} catch (e) { | ||
paths.push(absolutePath); | ||
const ext = path.extname(absolutePath); | ||
if (imageExtensions.includes(ext)) { | ||
paths.push(absolutePath.replace(ext, `@2x${ext}`)); | ||
paths.push(absolutePath.replace(ext, `@3x${ext}`)); | ||
} | ||
} | ||
paths = [ | ||
...paths, | ||
...withExtensions(absolutePath), | ||
...withIndex(absolutePath), | ||
]; | ||
const founds = paths.filter(fs.existsSync); | ||
return founds; | ||
}; | ||
|
||
const findImports = filePaths => filePaths.map((filePath) => { | ||
if (usedFiles[filePath]) { | ||
return []; | ||
} | ||
usedFiles[filePath] = true; | ||
const content = fs | ||
.readFileSync(filePath, { encoding: 'utf8' }) | ||
.replace(commentRegex, ''); | ||
const founds = []; | ||
let found = importRegex.exec(content); | ||
while (found) { | ||
if (found[1][0] === '.') { | ||
founds.push(found[1]); | ||
} else { | ||
usedDependencies[found[1]] = true; | ||
} | ||
found = importRegex.exec(content); | ||
} | ||
found = requireRegex.exec(content); | ||
while (found) { | ||
if (found[1][0] === '.') { | ||
founds.push(found[1]); | ||
} else { | ||
usedDependencies[found[1]] = true; | ||
} | ||
found = requireRegex.exec(content); | ||
} | ||
found = graphqlImportRegex.exec(content); | ||
while (found) { | ||
founds.push(found[1]); | ||
found = graphqlImportRegex.exec(content); | ||
} | ||
return founds.map(resolveImports(path.dirname(filePath))); | ||
}); | ||
|
||
function resolveImports(dirname) { | ||
return compose( | ||
findImports, | ||
resolve(dirname), | ||
); | ||
} | ||
|
||
export default (projectRoot) => { | ||
resolveImports(projectRoot)(''); | ||
return { | ||
usedFiles, | ||
usedDependencies, | ||
}; | ||
}; |
Oops, something went wrong.