Last portion of refactoring

This commit is contained in:
Victor Baranov 2018-09-06 16:48:46 +03:00
parent c1009573eb
commit 6596c73b68
14 changed files with 126 additions and 107 deletions

View File

@ -30,7 +30,7 @@ npm start
Expected result:
```
Success! Flat file is generated to ./out directory
Success! Flat file ORIGINAL_FILE_NAME_flat.sol is generated to ./out directory
```
`./flatContract.sol` - flat .sol file is created in output directory (`./out/` by default)

View File

@ -1,9 +1,9 @@
pragma solidity ^0.4.11;
import "./owned.sol";
import "oracles-contract-key/KeyClass.sol";
import "oracles-contract-validator/ValidatorClass.sol";
import "oracles-contract-ballot/BallotClass.sol";
import "oracles-contract-key/src/KeyClass.sol";
import "oracles-contract-validator/src/ValidatorClass.sol";
import "oracles-contract-ballot/src/BallotClass.sol";
contract KeysManager is owned, KeyClass, ValidatorClass, BallotClass {
int8 internal initialKeysIssued = 0;

View File

@ -1,6 +1,6 @@
pragma solidity ^0.4.11;
import "oracles-contract-validator/ValidatorClass.sol";
import "oracles-contract-validator/src/ValidatorClass.sol";
import "./KeysManager.sol";
contract ValidatorsManager is ValidatorClass, KeysManager {

View File

@ -1,25 +1,34 @@
const fs = require('fs')
const path = require('path')
const constants = require('./constants')
const cleanPath = require('./clean-path')
/*
* Replaces relative paths to absolute path for imports
*/
async function changeRelativePathToAbsolute(dir, fileContent) {
let fileContentNew = fileContent
const findAllImportPaths = require('./find-all-import-paths')
const importObjs = await findAllImportPaths(dir, fileContent)
importObjs.forEach((importObj) => {
let isAbsolutePath = !importObj.dependencyPath.startsWith(constants.DOT)
if (!isAbsolutePath) {
const { dependencyPath, fullImportStatement } = importObj
let dependencyPathNew = dir + constants.SLASH + dependencyPath
dependencyPathNew = cleanPath(dependencyPathNew)
let fullImportStatementNew = fullImportStatement.split(dependencyPath).join(dependencyPathNew)
fileContentNew = fileContentNew.split(fullImportStatement).join(fullImportStatementNew)
const changeRelativePathToAbsolute = (filePath) => {
const dir = path.dirname(filePath)
const fileContent = fs.readFileSync(filePath, constants.UTF8)
return new Promise(async (resolve) => {
let fileContentNew = fileContent
const findAllImportPaths = require('./find-all-import-paths')
const importObjs = await findAllImportPaths(dir, fileContent)
if (!importObjs || importObjs.length == 0) {
resolve(fileContentNew)
}
})
importObjs.forEach((importObj) => {
const { dependencyPath, fullImportStatement } = importObj
const isAbsolutePath = !dependencyPath.startsWith(constants.DOT)
if (!isAbsolutePath) {
let dependencyPathNew = dir + constants.SLASH + dependencyPath
dependencyPathNew = cleanPath(dependencyPathNew)
let fullImportStatementNew = fullImportStatement.split(dependencyPath).join(dependencyPathNew)
fileContentNew = fileContentNew.split(fullImportStatement).join(fullImportStatementNew)
}
})
return fileContentNew
resolve(fileContentNew)
})
}
module.exports = changeRelativePathToAbsolute

View File

@ -3,13 +3,18 @@ const constants = require('./constants')
function cleanPath(path) {
let cleanedPath
if (path.includes(constants.DIRTY_PATH)) {
const re = new RegExp(constants.DIRTY_PATH, 'g')
cleanedPath = path.replace(re, constants.SLASH)
cleanedPath = path.split(constants.DIRTY_PATH).join(constants.SLASH)
} else {
cleanedPath = path
}
if (cleanedPath.includes(constants.DIRTY_PATH)) {
if (path.includes(constants.DIRTY_PATH_2)) {
const pathPartBefore = path.substring(0, path.indexOf(constants.DIRTY_PATH_2))
const folderBack = pathPartBefore.split(constants.SLASH).slice(-1)[0]
cleanedPath = path.split(folderBack + constants.DIRTY_PATH_2).join(constants.EMPTY)
}
if (cleanedPath.includes(constants.DIRTY_PATH || constants.DIRTY_PATH_2)) {
return cleanPath(cleanedPath)
} else {
return cleanedPath

View File

@ -8,6 +8,8 @@ const _IMPORT = 'import '
const _CONTRACT = 'contract '
const _DOT = '.'
const _DIRTY_PATH = '/./'
const _DIRTY_PATH_2 = '/../'
const _SOL = '/**/*.sol'
module.exports = {
UTF8: _UTF8,
@ -19,5 +21,7 @@ module.exports = {
IMPORT: _IMPORT,
CONTRACT: _CONTRACT,
DOT: _DOT,
DIRTY_PATH: _DIRTY_PATH
SOL: _SOL,
DIRTY_PATH: _DIRTY_PATH,
DIRTY_PATH_2: _DIRTY_PATH_2
}

View File

@ -12,16 +12,19 @@ function findAllImportPaths(dir, content) {
//strip comments from content
content = decomment(content, {safe: true})
let allImports = []
let regex = new RegExp(constants.IMPORT,'gi')
let importsCount = (content.match(regex) || []).length
const regex = new RegExp(constants.IMPORT,'gi')
const importsCount = (content.match(regex) || []).length
let importsIterator = 0
let result
while ( (result = regex.exec(content)) ) {
let startImport = result.index
let endImport = startImport + content.substr(startImport).indexOf(constants.SEMICOLON) + 1
let fullImportStatement = content.substring(startImport, endImport)
let dependencyPath = fullImportStatement.split('"').length > 1 ? fullImportStatement.split('"')[1] : fullImportStatement.split('\'')[1]
let alias = fullImportStatement.split(constants.AS).length > 1 ? fullImportStatement.split(constants.AS)[1].split(constants.SEMICOLON)[0] : null
const startImport = result.index
const endImport = startImport + content.substr(startImport).indexOf(constants.SEMICOLON) + 1
const fullImportStatement = content.substring(startImport, endImport)
const fullImportParts = fullImportStatement.split('"')
const fullImportPartsAlt = fullImportStatement.split('\'')
const dependencyPath = fullImportParts.length > 1 ? fullImportParts[1] : fullImportPartsAlt[1]
const fullImportPartsByAs = fullImportStatement.split(constants.AS)
let alias = fullImportPartsByAs.length > 1 ? fullImportPartsByAs[1].split(constants.SEMICOLON)[0] : null
let importObj = {
startIndex: startImport,
@ -34,28 +37,20 @@ function findAllImportPaths(dir, content) {
if (alias) {
alias = alias.replace(/\s/g,constants.EMPTY)
let fileExists = fs.existsSync(dependencyPath, fs.F_OK)
let fileContent
if (fileExists) {
importsIterator++
let fileContent = fs.readFileSync(dependencyPath, constants.UTF8)
if (fileContent.includes(constants.CONTRACT)) {
importObj.contractName = getContractName(fileContent)
}
allImports.push(importObj)
fileContent = fs.readFileSync(dependencyPath, constants.UTF8)
} else {
const fileName = dir.substring(0, dir.lastIndexOf(constants.SLASH))
const fileContent = await findFile.byName(fileName, path.basename(dependencyPath))
importsIterator++
if (fileContent.includes(constants.CONTRACT)) {
importObj.contractName = getContractName(fileContent)
}
allImports.push(importObj)
if (importsIterator == importsCount) resolve(allImports)
dir = dir.substring(0, dir.lastIndexOf(constants.SLASH))
fileContent = await findFile.byName(dir, path.basename(dependencyPath))
}
if (fileContent.includes(constants.CONTRACT)) {
importObj.contractName = getContractName(fileContent)
}
} else {
importsIterator++
allImports.push(importObj)
}
importsIterator++
allImports.push(importObj)
}
if (importsIterator == importsCount) resolve(allImports)
})

View File

@ -12,7 +12,7 @@ function byName(dir, fileName) {
}
async function byNameInner(dir, fileName, resolve) {
const srcFiles = await glob(dir + '/**/*.sol')
const srcFiles = await glob(dir + constants.SOL)
for (let j = 0; j < srcFiles.length; j++) {
if (path.basename(srcFiles[j]) == fileName) {
let fileContent = fs.readFileSync(srcFiles[j], constants.UTF8)
@ -32,7 +32,7 @@ async function byNameAndReplace(dir, dependencyPath, updatedFileContent, importS
}
async function byNameAndReplaceInner(dir, dependencyPath, updatedFileContent, importStatement, resolve, reject) {
const srcFiles = await glob(dir + '/**/*.sol')
const srcFiles = await glob(dir + constants.SOL)
let result = await byNameAndReplaceInnerRecursively(importStatement, updatedFileContent, dir, dependencyPath, srcFiles, 0)
let { flattenFileContent, importIsReplacedBefore } = result
if (importIsReplacedBefore) {
@ -59,32 +59,31 @@ async function byNameAndReplaceInnerRecursivelyInner(importStatement, updatedFil
if (j >= srcFiles.length) return resolve({ flattenFileContent: updatedFileContent, importIsReplacedBefore })
let isAbsolutePath = !dependencyPath.startsWith(constants.DOT)
const srcFile = srcFiles[j]
const filePath = srcFiles[j]
const { importedSrcFiles } = variables
if (isAbsolutePath && srcFile.includes(dependencyPath)) {
if (isAbsolutePath && filePath.includes(dependencyPath)) {
let flattenFileContent = constants.EMPTY
if (!importedSrcFiles.hasOwnProperty(path.basename(srcFile)) || fs.existsSync(dependencyPath)) {
if (!importedSrcFiles.hasOwnProperty(path.basename(filePath)) || fs.existsSync(dependencyPath)) {
let importFileContent
if (fs.existsSync(dependencyPath)) {
importFileContent = fs.readFileSync(dependencyPath, constants.UTF8)
importFileContent = await changeRelativePathToAbsolute(dependencyPath)
} else {
importFileContent = fs.readFileSync(srcFile, constants.UTF8)
importFileContent = await changeRelativePathToAbsolute(filePath)
}
importFileContent = await changeRelativePathToAbsolute(dir, importFileContent)
if (importFileContent.includes(constants.IS)) {
flattenFileContent = updatedFileContent.replace(importStatement, importFileContent)
} else {
flattenFileContent = importFileContent + updatedFileContent.replace(importStatement, constants.EMPTY)
}
importedSrcFiles[path.basename(srcFile)] = importFileContent
importedSrcFiles[path.basename(filePath)] = importFileContent
resolve({ flattenFileContent, importIsReplacedBefore: true })
} else {
flattenFileContent = updatedFileContent.replace(importStatement, constants.EMPTY)
//issue #2.
const fileName = importedSrcFiles[path.basename(dir + dependencyPath)]
if (flattenFileContent.includes(fileName) && flattenFileContent.includes(constants.IMPORT)) {
let importFileContent = fs.readFileSync(srcFile, constants.UTF8)
let importFileContent = fs.readFileSync(filePath, constants.UTF8)
flattenFileContent = importFileContent + flattenFileContent.replace(fileName, constants.EMPTY)
}
importIsReplacedBefore = true

View File

@ -3,7 +3,6 @@ const path = require('path')
const variables = require('./variables')
const constants = require('./constants')
const findFile = require('./find-file')
const replaceRelativeImportPaths = require('./replace-relative-import-paths')
const updateImportObjectLocationInTarget = require('./update-import-object-location-in-target')
const changeRelativePathToAbsolute = require('./change-relative-path-to-absolute')
const cleanPath = require('./clean-path')
@ -20,6 +19,8 @@ async function replaceAllImportsInCurrentLayerInner(i, importObjs, updatedFileCo
return resolve(updatedFileContent)
}
// console.log(importObjs)
// console.log(dir)
let importObj = importObjs[i]
importObj = updateImportObjectLocationInTarget(importObj, updatedFileContent)
const { alias, contractName, startIndex, endIndex } = importObj
@ -34,23 +35,18 @@ async function replaceAllImportsInCurrentLayerInner(i, importObjs, updatedFileCo
_updatedFileContent = updatedFileContent
}
console.log(`dependencyPath before: ${dependencyPath}`)
dependencyPath = cleanPath(dependencyPath)
console.log(`dependencyPath after: ${dependencyPath}`)
let isRelativePath = dependencyPath.startsWith(constants.DOT)
let filePath = isRelativePath ? dir + dependencyPath : dependencyPath
console.log(`filePath before: ${filePath}`)
let isAbsolutePath = !dependencyPath.startsWith(constants.DOT)
let filePath = isAbsolutePath ? dependencyPath : (dir + dependencyPath)
filePath = cleanPath(filePath)
console.log(`filePath after: ${filePath}`)
const importStatement = updatedFileContent.substring(startIndex, endIndex)
const fileBaseName = path.basename(filePath)
const fileExists = fs.existsSync(filePath, fs.F_OK)
if (fileExists) {
log.info(`### ${dependencyPath} SOURCE FILE WAS FOUND###`)
let importedFileContent = fs.readFileSync(filePath, constants.UTF8)
importedFileContent = await changeRelativePathToAbsolute(dir, importedFileContent)
const importedFileContentUpdated = await replaceRelativeImportPaths(importedFileContent, path.dirname(dependencyPath) + constants.SLASH)
log.info(`${filePath} SOURCE FILE WAS FOUND`)
const importedFileContentUpdated = await changeRelativePathToAbsolute(filePath)
//const importedFileContentUpdated = await replaceRelativeImportPaths(path.dirname(dependencyPath) + constants.SLASH, importedFileContent)
if (!importedSrcFiles.hasOwnProperty(fileBaseName)) {
importedSrcFiles[fileBaseName] = importedFileContentUpdated
if (importedFileContentUpdated.includes(constants.IS)) {
@ -67,11 +63,11 @@ async function replaceAllImportsInCurrentLayerInner(i, importObjs, updatedFileCo
}
} else {
if (!importedSrcFiles.hasOwnProperty(fileBaseName)) {
log.info(`!!! ${dependencyPath} SOURCE FILE WAS NOT FOUND. TRY TO FIND IT RECURSIVELY!!!`)
log.warn(`!!! ${filePath} SOURCE FILE WAS NOT FOUND. I'M TRYING TO FIND IT RECURSIVELY !!!`)
const directorySeperator = process.platform === 'win32' ? '\\' : constants.SLASH
const dirNew = dir.substring(0, dir.lastIndexOf(directorySeperator))
_updatedFileContent = await findFile.byNameAndReplace(dirNew, dependencyPath, _updatedFileContent, importStatement)
log.info(`### ${dependencyPath} SOURCE FILE WAS FOUND###`)
log.info(`${filePath} SOURCE FILE WAS FOUND`)
} else {
_updatedFileContent = _updatedFileContent.replace(importStatement, constants.EMPTY)
}

View File

@ -1,27 +0,0 @@
const updateImportObjectLocationInTarget = require('./update-import-object-location-in-target')
const findAllImportPaths = require('./find-all-import-paths')
function replaceRelativeImportPaths(fileContent, curDir) {
return new Promise(async (resolve) => {
let updatedFileContent = fileContent
const importObjs = await findAllImportPaths(curDir, fileContent)
if (!importObjs || importObjs.length == 0) {
resolve(updatedFileContent)
}
importObjs.forEach((importObj) => {
importObj = updateImportObjectLocationInTarget(importObj, updatedFileContent)
const { startIndex, endIndex, dependencyPath } = importObj
const importStatement = updatedFileContent.substring(startIndex, endIndex)
const isRelativePath = dependencyPath.startsWith('../') || dependencyPath.startsWith('./')
const newPath = isRelativePath ? (curDir + dependencyPath) : dependencyPath
const importStatementNew = importStatement.replace(dependencyPath, newPath)
updatedFileContent = updatedFileContent.replace(importStatement, importStatementNew)
})
resolve(updatedFileContent)
})
}
module.exports = replaceRelativeImportPaths

View File

@ -3,6 +3,8 @@ const fs = require('fs')
const glob = require('glob-promise')
const variables = require('./helpers/variables')
const log = require('./helpers/logger')
const constants = require('./helpers/constants')
const cleanPath = require('./helpers/clean-path')
const removeDoubledSolidityVersion = require('./helpers/remove-doubled-solidity-version')
const replaceAllImportsRecursively = require('./helpers/replace-all-imports-recursively')
@ -10,8 +12,13 @@ flatten()
async function flatten() {
const inputFileContent = await fs.readFileSync(variables.inputFilePath, 'utf8')
const dir = variables.parentDir + '/'
const path = variables.parentDir + '/**/*.sol'
let dir = variables.parentDir + constants.SLASH
const isAbsolutePath = !dir.startsWith(constants.DOT)
if (!isAbsolutePath) {
dir = __dirname + constants.SLASH + dir
}
dir = cleanPath(dir)
const path = variables.parentDir + constants.SOL
const srcFiles = await getSourceFiles(dir, path)
variables.srcFiles = srcFiles
await replaceImports(inputFileContent, dir)
@ -25,6 +32,8 @@ async function replaceImports(inputFileContent, dir) {
let outputFileContent = await replaceAllImportsRecursively(inputFileContent, dir)
outputFileContent = removeDoubledSolidityVersion(outputFileContent)
if (!fs.existsSync(variables.outDir)) fs.mkdirSync(variables.outDir)
fs.writeFileSync(variables.outDir + '/' + variables.flatContractPrefix + '_flat.sol', outputFileContent)
log.info('Success! Flat file is generated to ' + variables.outDir + ' directory')
}
const fileName = `${variables.flatContractPrefix}_flat.sol`
const filePath = `${variables.outDir}/${fileName}`
fs.writeFileSync(filePath, outputFileContent)
log.info(`Success! Flat file ${fileName} is generated to ${variables.outDir} directory`)
}

View File

@ -6,12 +6,11 @@ const changeRelativePathToAbsolute = require('../../helpers/change-relative-path
const dir = './test/contracts'
const filePath = dir + '/test.sol'
const editedFilePath = dir + '/testMock1.sol'
const fileContent = fs.readFileSync(filePath, constants.UTF8)
const expectedFileContentNew = fs.readFileSync(editedFilePath, constants.UTF8)
describe('changeRelativePathToAbsolute', () => {
it('should change relative path to absolute for imports', async () => {
const fileContentNew = await changeRelativePathToAbsolute(dir, fileContent)
it('should change relative path to absolute one for imports', async () => {
const fileContentNew = await changeRelativePathToAbsolute(filePath)
assert.equal(fileContentNew, expectedFileContentNew)
})
})

View File

@ -0,0 +1,28 @@
const assert = require('assert')
const cleanPath = require('../../helpers/clean-path.js')
const path = './././././ta/fgfd/./gfd/gfd/./g/dfg/dfgdf/./gd/fg/././df/gdf/g/js'
const expectedCleanedPath = './ta/fgfd/gfd/gfd/g/dfg/dfgdf/gd/fg/df/gdf/g/js'
const path2 = '../gfdgfdgfd/../gdfgdfgdfgdfgd'
const expectedCleanedPath2 = '../gdfgdfgdfgdfgd'
const path3 = './abc/def/gedfg/test.js'
describe('cleanPath', () => {
it('should clean path to file from all occurrences of /./', async () => {
assert.equal(cleanPath(path), expectedCleanedPath)
})
it('should not clean relative path f/../', async () => {
assert.equal(cleanPath(path2), expectedCleanedPath2)
})
it('should not clean already cleaned path', async () => {
assert.equal(cleanPath(path3), path3)
})
it('should handle a empty string', async () => {
assert.equal(cleanPath(''), '')
})
})

View File

@ -1,2 +1,4 @@
// eslint-disable-next-line no-unused-vars
const changeRelativePathToAbsoluteTest = require('./helpers/change-relative-path-to-absolute.js')
const changeRelativePathToAbsoluteTest = require('./helpers/change-relative-path-to-absolute')
// eslint-disable-next-line no-unused-vars
const cleantPath = require('./helpers/clean-path')