Skip to content

Commit

Permalink
Merge pull request #14 from Aniket-Engg/github
Browse files Browse the repository at this point in the history
import from github added
  • Loading branch information
Aniket-Engg committed May 10, 2019
2 parents 1fad418 + 98cced4 commit d220137
Show file tree
Hide file tree
Showing 10 changed files with 203 additions and 18 deletions.
2 changes: 1 addition & 1 deletion lib/straighten.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const { getPragma, processFile } = require('./../utils/file');

module.exports.straighten = async (filePath) => {
const pragma = await getPragma(filePath);
let contractSource = await processFile(filePath, true);
let contractSource = await processFile(filePath, false, true);
contractSource = pragma + '\n\n' + contractSource;
return contractSource;
};
28 changes: 25 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "Straighten/Flatten Solidity file from js file",
"main": "index.js",
"scripts": {
"test": "nyc mocha --timeout 10000",
"test": "nyc mocha --timeout 40000",
"coverage": "nyc report --reporter=text-lcov | coveralls",
"lint": "eslint .",
"lint:fix": "eslint . --fix"
Expand Down Expand Up @@ -33,5 +33,8 @@
"eslint": "^5.16.0",
"mocha": "^6.1.4",
"nyc": "^14.1.0"
},
"dependencies": {
"axios": "^0.18.0"
}
}
15 changes: 15 additions & 0 deletions test/contracts/MultiImportFromGithub.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
pragma solidity ^0.5.7;

import "github.com/Aniket-Engg/sol-straightener/test/contracts/SampleWithMultiImport.sol";

contract MultiImportFromGithub {
uint public n;

function set(uint _n) public returns (uint) {
n = _n;
}

function get() public view returns (uint) {
return n;
}
}
15 changes: 15 additions & 0 deletions test/contracts/NestedImportFromGithub.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
pragma solidity ^0.5.7;

import "github.com/Aniket-Engg/sol-straightener/test/contracts/SampleWithNestedImport.sol";

contract NestedImportFromGithub {
uint public n;

function set(uint _n) public returns (uint) {
n = _n;
}

function get() public view returns (uint) {
return n;
}
}
10 changes: 10 additions & 0 deletions test/contracts/SampleWithImportNotExisting.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
pragma solidity ^0.5.7;

import "./Sample3.sol";

contract SampleWithImportNotExisting is Sample3{

function increment(uint _n) public pure returns (uint) {
return _n++;
}
}
40 changes: 40 additions & 0 deletions test/contracts/straightened/MultiImportFromGithub.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
pragma solidity ^0.5.7;

contract Sample {
uint public n;

function set(uint _n) public returns (uint) {
n = _n;
}

function get() public view returns (uint) {
return n;
}
}

contract Sample2 {

function double(uint _n) public pure returns (uint) {
return 2*_n;
}

}

contract SampleWithMultiImport is Sample, Sample2{

function half(uint _n) public pure returns (uint) {
return _n/2;
}
}

contract MultiImportFromGithub {
uint public n;

function set(uint _n) public returns (uint) {
n = _n;
}

function get() public view returns (uint) {
return n;
}
}
39 changes: 39 additions & 0 deletions test/contracts/straightened/NestedImportFromGithub.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
pragma solidity ^0.5.7;

contract Sample {
uint public n;

function set(uint _n) public returns (uint) {
n = _n;
}

function get() public view returns (uint) {
return n;
}
}

contract SampleWithImport is Sample{

function increment(uint _n) public pure returns (uint) {
return _n++;
}
}

contract SampleWithNestedImport is SampleWithImport{

function decrement(uint _n) public pure returns (uint) {
return _n--;
}
}

contract NestedImportFromGithub {
uint public n;

function set(uint _n) public returns (uint) {
n = _n;
}

function get() public view returns (uint) {
return n;
}
}
20 changes: 20 additions & 0 deletions test/straighten.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@ describe('sol-straightener', () => {
expect(Buffer.from(strtnFile)).to.deep.equal(strtnContent);
});

it('Fails for contract with non existing file import', async () => {
try{
await Straightener.straighten(__dirname + '/contracts/SampleWithImportNotExisting.sol');
}catch(error){
expect(error.message).to.include('no such file or directory');
}
});

it('Contract with nested imports', async () => {
const strtnFile = await Straightener.straighten(__dirname + '/contracts/SampleWithNestedImport.sol');
const strtnContent = fs.readFileSync(__dirname + '/contracts/straightened/SampleWithNestedImport.sol');
Expand All @@ -27,6 +35,18 @@ describe('sol-straightener', () => {
it('Contract with imports from node_modules', async () => {
const strtnFile = await Straightener.straighten(__dirname + '/contracts/ImportFromNodeModules.sol');
const strtnContent = fs.readFileSync(__dirname + '/contracts/straightened/ImportFromNodeModules.sol');
// expect(Buffer.from(strtnFile)).to.deep.equal(strtnContent);
});

it('Contract with multiple imports from Github', async () => {
const strtnFile = await Straightener.straighten(__dirname + '/contracts/MultiImportFromGithub.sol');
const strtnContent = fs.readFileSync(__dirname + '/contracts/straightened/MultiImportFromGithub.sol');
expect(Buffer.from(strtnFile)).to.deep.equal(strtnContent);
});

it('Contract with nested imports from Github', async () => {
const strtnFile = await Straightener.straighten(__dirname + '/contracts/NestedImportFromGithub.sol');
const strtnContent = fs.readFileSync(__dirname + '/contracts/straightened/NestedImportFromGithub.sol');
expect(Buffer.from(strtnFile)).to.deep.equal(strtnContent);
});
});
47 changes: 34 additions & 13 deletions utils/file.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,18 @@

const path = require('path'),
{ execSync } = require('child_process'),
axios = require('axios'),
fs = require('fs');

const regEx = {
pragma : /(pragma solidity (.+?);)/g,
import : /import ['"](.+?)['"];/g,
github : /^(https?:\/\/)?(www.)?github.com\/([^/]*\/[^/]*)\/(.*)/,
};

let processedFiles = [];

const processFile = async (file, root = false) => {
const processFile = async (file, fromGithub, root = false) => {
try{
if(root)
processedFiles = [];
Expand All @@ -21,11 +23,22 @@ const processFile = async (file, root = false) => {

processedFiles.push(file);
let result = '';
let contents;
let imports;

let contents = fs.readFileSync(file, { encoding: 'utf-8' });
contents = contents.replace(regEx.pragma, '').trim();
const imports = await processImports(file, contents);

if(fromGithub){
const metadata = regEx.github.exec(file);
const url = 'https://api.github.com/repos/' + metadata[3] + '/contents/' + metadata[4];
contents = Buffer.from((await axios.get(url)).data.content, 'base64').toString();
contents = contents.replace(regEx.pragma, '').trim();
imports = await processImports(file, contents, path.dirname(metadata[0]));
}
else
{
contents = fs.readFileSync(file, { encoding: 'utf-8' });
contents = contents.replace(regEx.pragma, '').trim();
imports = await processImports(file, contents);
}
for (let i = 0; i < imports.length; i++) {
result += imports[i] + '\n\n';
}
Expand All @@ -38,20 +51,28 @@ const processFile = async (file, root = false) => {
}
};

const processImports = async (file, content) => {
const processImports = async (file, content, githubPrefix = false) => {
try{
let group='';
const result = [];
let fileContents;
regEx.import.exec(''); // Resetting state of RegEx
while (group = regEx.import.exec(content)) {
const _importFile = group[1];
let filePath = path.join(path.dirname(file), _importFile);
if(!fs.existsSync(filePath)){
const nodeModulesPath = (await execSync('npm root', { cwd: path.dirname(file) })).toString().trim();
filePath = path.join(nodeModulesPath, _importFile);
let importFile = group[1];
if(githubPrefix)
importFile = path.join(githubPrefix, importFile); // for imports in github file

if(importFile.substring(0, 10) == 'github.com'){
fileContents = await processFile(importFile, true);
}else{
let filePath = path.join(path.dirname(file), importFile);
if(!fs.existsSync(filePath)){
const nodeModulesPath = (await execSync('npm root', { cwd: path.dirname(file) })).toString().trim();
filePath = path.join(nodeModulesPath, importFile);
}
filePath = path.normalize(filePath);
fileContents = await processFile(filePath, false);
}
filePath = path.normalize(filePath);
const fileContents = await processFile(filePath);
if (fileContents) {
result.push(fileContents);
}
Expand Down

0 comments on commit d220137

Please sign in to comment.