Clean-up scripts. (#6832)
This commit is contained in:
		
							parent
							
								
									3a01068747
								
							
						
					
					
						commit
						aa929fe6ae
					
				| @ -24,15 +24,12 @@ | ||||
|     "build": "npm run build:lib && npm run build:app", | ||||
|     "build:app": "webpack --progress --config webpack/app", | ||||
|     "build:lib": "webpack --progress --config webpack/libraries", | ||||
|     "build:markdown": "babel-node ./scripts/build-rpc-markdown.js", | ||||
|     "build:json": "babel-node ./scripts/build-rpc-json.js", | ||||
|     "build:embed": "EMBED=1 node webpack/embed", | ||||
|     "build:i18n": "npm run clean && npm run build && babel-node ./scripts/build-i18n.js", | ||||
|     "ci:build": "npm run ci:build:lib && npm run ci:build:app && npm run ci:build:embed", | ||||
|     "ci:build:app": "NODE_ENV=production webpack --progress --config webpack/app", | ||||
|     "ci:build:lib": "NODE_ENV=production webpack --progress --config webpack/libraries", | ||||
|     "ci:build:npm": "NODE_ENV=production webpack --progress --config webpack/npm", | ||||
|     "ci:build:jsonrpc": "babel-node ./scripts/build-rpc-json.js --output .npmjs/jsonrpc", | ||||
|     "ci:build:embed": "NODE_ENV=production EMBED=1 node webpack/embed", | ||||
|     "clean": "rm -rf ./.build ./.coverage ./.happypack ./build ./node_modules/.cache", | ||||
|     "coveralls": "npm run testCoverage && coveralls < coverage/lcov.info", | ||||
|  | ||||
| @ -1,70 +0,0 @@ | ||||
| // Copyright 2015-2017 Parity Technologies (UK) Ltd.
 | ||||
| // This file is part of Parity.
 | ||||
| 
 | ||||
| // Parity is free software: you can redistribute it and/or modify
 | ||||
| // it under the terms of the GNU General Public License as published by
 | ||||
| // the Free Software Foundation, either version 3 of the License, or
 | ||||
| // (at your option) any later version.
 | ||||
| 
 | ||||
| // Parity is distributed in the hope that it will be useful,
 | ||||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | ||||
| // GNU General Public License for more details.
 | ||||
| 
 | ||||
| // You should have received a copy of the GNU General Public License
 | ||||
| // along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
| 
 | ||||
| import fs from 'fs'; | ||||
| import path from 'path'; | ||||
| import yargs from 'yargs'; | ||||
| 
 | ||||
| import interfaces from '../src/jsonrpc'; | ||||
| 
 | ||||
| const argv = yargs.default('output', 'release').argv; | ||||
| 
 | ||||
| const INDEX_JSON = path.join(__dirname, `../${argv.output}/index.json`); | ||||
| const methods = []; | ||||
| 
 | ||||
| function formatDescription (obj) { | ||||
|   const optional = obj.optional ? '(optional) ' : ''; | ||||
|   const defaults = obj.default ? `(default: ${obj.default}) ` : ''; | ||||
| 
 | ||||
|   return `${obj.type.name} - ${optional}${defaults}${obj.desc}`; | ||||
| } | ||||
| 
 | ||||
| function formatType (obj) { | ||||
|   if (obj.type === Object && obj.details) { | ||||
|     const formatted = {}; | ||||
| 
 | ||||
|     Object.keys(obj.details).sort().forEach((key) => { | ||||
|       formatted[key] = formatType(obj.details[key]); | ||||
|     }); | ||||
| 
 | ||||
|     return { | ||||
|       desc: formatDescription(obj), | ||||
|       details: formatted | ||||
|     }; | ||||
|   } else if (obj.type && obj.type.name) { | ||||
|     return formatDescription(obj); | ||||
|   } | ||||
| 
 | ||||
|   return obj; | ||||
| } | ||||
| 
 | ||||
| Object.keys(interfaces).sort().forEach((group) => { | ||||
|   Object.keys(interfaces[group]).sort().forEach((name) => { | ||||
|     const method = interfaces[group][name]; | ||||
|     const deprecated = method.deprecated ? ' (Deprecated and not supported, to be removed in a future version)' : ''; | ||||
| 
 | ||||
|     methods.push({ | ||||
|       name: `${group}_${name}`, | ||||
|       desc: `${method.desc}${deprecated}`, | ||||
|       params: method.params.map(formatType), | ||||
|       returns: formatType(method.returns), | ||||
|       inputFormatters: method.params.map((param) => param.format || null), | ||||
|       outputFormatter: method.returns.format || null | ||||
|     }); | ||||
|   }); | ||||
| }); | ||||
| 
 | ||||
| fs.writeFileSync(INDEX_JSON, JSON.stringify({ methods: methods }, null, 2), 'utf8'); | ||||
| @ -1,328 +0,0 @@ | ||||
| // Copyright 2015-2017 Parity Technologies (UK) Ltd.
 | ||||
| // This file is part of Parity.
 | ||||
| 
 | ||||
| // Parity is free software: you can redistribute it and/or modify
 | ||||
| // it under the terms of the GNU General Public License as published by
 | ||||
| // the Free Software Foundation, either version 3 of the License, or
 | ||||
| // (at your option) any later version.
 | ||||
| 
 | ||||
| // Parity is distributed in the hope that it will be useful,
 | ||||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | ||||
| // GNU General Public License for more details.
 | ||||
| 
 | ||||
| // You should have received a copy of the GNU General Public License
 | ||||
| // along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
| 
 | ||||
| import fs from 'fs'; | ||||
| import path from 'path'; | ||||
| import { isPlainObject } from 'lodash'; | ||||
| 
 | ||||
| import { info, warn, error } from './helpers/log'; | ||||
| import { Dummy } from '../src/jsonrpc/helpers'; | ||||
| import interfaces from '../src/jsonrpc'; | ||||
| import rustMethods from './helpers/parsed-rpc-traits'; | ||||
| 
 | ||||
| const ROOT_DIR = path.join(__dirname, '../docs'); | ||||
| 
 | ||||
| if (!fs.existsSync(ROOT_DIR)) { | ||||
|   fs.mkdirSync(ROOT_DIR); | ||||
| } | ||||
| 
 | ||||
| Object.keys(rustMethods).forEach((group) => { | ||||
|   Object.keys(rustMethods[group]).forEach((method) => { | ||||
|     if (interfaces[group] == null || interfaces[group][method] == null) { | ||||
|       error(`${group}_${method} is defined in Rust traits, but not in js/src/jsonrpc/interfaces`); | ||||
|     } | ||||
|   }); | ||||
| }); | ||||
| 
 | ||||
| function printType (type, obj) { | ||||
|   if (!type) { | ||||
|     throw new Error(`Invalid type in ${JSON.stringify(obj)}`); | ||||
|   } | ||||
| 
 | ||||
|   return type.print || `\`${type.name}\``; | ||||
| } | ||||
| 
 | ||||
| function formatDescription (obj, prefix = '', indent = '') { | ||||
|   const optional = obj.optional ? '(optional) ' : ''; | ||||
|   const defaults = obj.default ? `(default: \`${obj.default}\`) ` : ''; | ||||
| 
 | ||||
|   return `${indent}${prefix}${printType(obj.type, obj)} - ${optional}${defaults}${obj.desc}`; | ||||
| } | ||||
| 
 | ||||
| function formatType (obj) { | ||||
|   if (obj == null || obj.type == null) { | ||||
|     return obj; | ||||
|   } | ||||
| 
 | ||||
|   const details = obj.details || obj.type.details; | ||||
| 
 | ||||
|   if (details) { | ||||
|     const sub = Object.keys(details).map((key) => { | ||||
|       return formatDescription(details[key], `\`${key}\`: `, '    - '); | ||||
|     }).join('\n'); | ||||
| 
 | ||||
|     return `${formatDescription(obj)}\n${sub}`; | ||||
|   } else if (obj.type && obj.type.name) { | ||||
|     return formatDescription(obj); | ||||
|   } | ||||
| 
 | ||||
|   return obj; | ||||
| } | ||||
| 
 | ||||
| const rpcReqTemplate = { | ||||
|   method: 'web3_clientVersion', | ||||
|   params: [], | ||||
|   id: 1, | ||||
|   jsonrpc: '2.0' | ||||
| }; | ||||
| 
 | ||||
| const { isDummy } = Dummy; | ||||
| const { isArray } = Array; | ||||
| 
 | ||||
| // Checks if a field definition has an example,
 | ||||
| // or describes an object with fields that recursively have examples of their own,
 | ||||
| // or is optional.
 | ||||
| function hasExample ({ optional, example, details } = {}) { | ||||
|   if (optional || example !== undefined) { | ||||
|     return true; | ||||
|   } | ||||
| 
 | ||||
|   if (details !== undefined) { | ||||
|     const values = Object.keys(details).map((key) => details[key]); | ||||
| 
 | ||||
|     return values.every(hasExample); | ||||
|   } | ||||
| 
 | ||||
|   return false; | ||||
| } | ||||
| 
 | ||||
| // Remove all optional (trailing) params without examples from an array
 | ||||
| function removeOptionalWithoutExamples (arr) { | ||||
|   return arr.filter(({ optional, example, details }) => { | ||||
|     return !optional || example !== undefined || details !== undefined; | ||||
|   }); | ||||
| } | ||||
| 
 | ||||
| // Grabs JSON compatible
 | ||||
| function getExample (obj) { | ||||
|   if (isArray(obj)) { | ||||
|     return removeOptionalWithoutExamples(obj).map(getExample); | ||||
|   } | ||||
| 
 | ||||
|   const { example, details } = obj; | ||||
| 
 | ||||
|   if (example === undefined && details !== undefined) { | ||||
|     const nested = {}; | ||||
| 
 | ||||
|     Object.keys(details).forEach((key) => { | ||||
|       nested[key] = getExample(details[key]); | ||||
|     }); | ||||
| 
 | ||||
|     return nested; | ||||
|   } | ||||
| 
 | ||||
|   return example; | ||||
| } | ||||
| 
 | ||||
| function stringifyExample (example, dent = '') { | ||||
|   const indent = `${dent}  `; | ||||
| 
 | ||||
|   if (isDummy(example)) { | ||||
|     return example.toString(); | ||||
|   } | ||||
| 
 | ||||
|   if (isArray(example)) { | ||||
|     const last = example.length - 1; | ||||
| 
 | ||||
|     // If all elements are dummies, print out a single line.
 | ||||
|     // Also covers empty arrays.
 | ||||
|     if (example.every(isDummy)) { | ||||
|       const dummies = example.map(d => d.toString()); | ||||
| 
 | ||||
|       return `[${dummies.join(', ')}]`; | ||||
|     } | ||||
| 
 | ||||
|     // For arrays containing just one object or string, don't unwind the array to multiline
 | ||||
|     if (last === 0 && (isPlainObject(example[0]) || typeof example[0] === 'string')) { | ||||
|       return `[${stringifyExample(example[0], dent)}]`; | ||||
|     } | ||||
| 
 | ||||
|     const elements = example.map((value, index) => { | ||||
|       const comma = index !== last ? ',' : ''; | ||||
|       const comment = value != null && value._comment ? ` // ${value._comment}` : ''; | ||||
| 
 | ||||
|       return `${stringifyExample(value, indent)}${comma}${comment}`; | ||||
|     }); | ||||
| 
 | ||||
|     return `[\n${indent}${elements.join(`\n${indent}`)}\n${dent}]`; | ||||
|   } | ||||
| 
 | ||||
|   if (isPlainObject(example)) { | ||||
|     const keys = Object.keys(example); | ||||
|     const last = keys.length - 1; | ||||
| 
 | ||||
|     // print out an empty object
 | ||||
|     if (last === -1) { | ||||
|       return '{}'; | ||||
|     } | ||||
| 
 | ||||
|     const elements = keys.map((key, index) => { | ||||
|       const value = example[key]; | ||||
|       const comma = index !== last ? ',' : ''; | ||||
|       const comment = value && value._comment ? ` // ${example[key]._comment}` : ''; | ||||
| 
 | ||||
|       return `${JSON.stringify(key)}: ${stringifyExample(value, indent)}${comma}${comment}`; | ||||
|     }); | ||||
| 
 | ||||
|     return `{\n${indent}${elements.join(`\n${indent}`)}\n${dent}}`; | ||||
|   } | ||||
| 
 | ||||
|   return JSON.stringify(example); | ||||
| } | ||||
| 
 | ||||
| function buildExample (name, method) { | ||||
|   // deprecated, don't care
 | ||||
|   if (method.deprecated) { | ||||
|     return ''; | ||||
|   } | ||||
| 
 | ||||
|   const logPostfix = method.subdoc ? ` (${method.subdoc})` : ''; | ||||
| 
 | ||||
|   const hasReqExample = method.params.every(hasExample); | ||||
|   const hasResExample = hasExample(method.returns); | ||||
| 
 | ||||
|   if (!hasReqExample && !hasResExample) { | ||||
|     error(`${name} has no examples${logPostfix}`); | ||||
| 
 | ||||
|     return ''; | ||||
|   } | ||||
| 
 | ||||
|   const examples = []; | ||||
| 
 | ||||
|   if (hasReqExample) { | ||||
|     const params = getExample(method.params); | ||||
|     const req = Dummy.stringifyJSON(Object.assign({}, rpcReqTemplate, { method: name, params })); | ||||
| 
 | ||||
|     examples.push(`Request\n\`\`\`bash\ncurl --data '${req}' -H "Content-Type: application/json" -X POST localhost:8545\n\`\`\``); | ||||
|   } else { | ||||
|     warn(`${name} has a response example but not a request example${logPostfix}`); | ||||
|   } | ||||
| 
 | ||||
|   if (hasResExample) { | ||||
|     const res = stringifyExample({ | ||||
|       id: 1, | ||||
|       jsonrpc: '2.0', | ||||
|       result: getExample(method.returns) | ||||
|     }); | ||||
| 
 | ||||
|     examples.push(`Response\n\`\`\`js\n${res}\n\`\`\``); | ||||
|   } else { | ||||
|     if (typeof method.returns === 'string') { | ||||
|       info(`${name} has a request example and only text description for response${logPostfix}`); | ||||
|     } else { | ||||
|       warn(`${name} has a request example but not a response example${logPostfix}`); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   return `\n\n#### Example\n\n${examples.join('\n\n')}`; | ||||
| } | ||||
| 
 | ||||
| function buildParameters (params) { | ||||
|   if (params.length === 0) { | ||||
|     return ''; | ||||
|   } | ||||
| 
 | ||||
|   let md = `0. ${params.map(formatType).join('\n0. ')}`; | ||||
| 
 | ||||
|   if (params.length > 0 && params.every(hasExample) && !isDummy(params[0].example)) { | ||||
|     const example = getExample(params); | ||||
| 
 | ||||
|     md = `${md}\n\n\`\`\`js\nparams: ${stringifyExample(example)}\n\`\`\``; | ||||
|   } | ||||
| 
 | ||||
|   return md; | ||||
| } | ||||
| 
 | ||||
| Object.keys(interfaces).sort().forEach((group) => { | ||||
|   const spec = interfaces[group]; | ||||
| 
 | ||||
|   for (const key in spec) { | ||||
|     const method = spec[key]; | ||||
| 
 | ||||
|     if (!method || !method.subdoc) { | ||||
|       continue; | ||||
|     } | ||||
| 
 | ||||
|     const subgroup = `${group}_${method.subdoc}`; | ||||
| 
 | ||||
|     interfaces[subgroup] = interfaces[subgroup] || {}; | ||||
| 
 | ||||
|     interfaces[subgroup][key] = method; | ||||
|     delete spec[key]; | ||||
|   } | ||||
| }); | ||||
| 
 | ||||
| Object.keys(interfaces).sort().forEach((group) => { | ||||
|   let preamble = `# The \`${group}\` Module`; | ||||
|   let markdown = `## JSON-RPC methods\n`; | ||||
| 
 | ||||
|   const spec = interfaces[group]; | ||||
| 
 | ||||
|   if (spec._preamble) { | ||||
|     preamble = `${preamble}\n\n${spec._preamble}`; | ||||
|   } | ||||
| 
 | ||||
|   const content = []; | ||||
|   const tocMain = []; | ||||
|   const tocSections = {}; | ||||
| 
 | ||||
|   // Comparator that will sort by sections first, names second
 | ||||
|   function methodComparator (a, b) { | ||||
|     const sectionA = spec[a].section || ''; | ||||
|     const sectionB = spec[b].section || ''; | ||||
| 
 | ||||
|     return sectionA.localeCompare(sectionB) || a.localeCompare(b); | ||||
|   } | ||||
| 
 | ||||
|   Object.keys(spec).sort(methodComparator).forEach((iname) => { | ||||
|     const method = spec[iname]; | ||||
|     const groupName = group.replace(/_.*$/, ''); | ||||
|     const name = `${groupName}_${iname}`; | ||||
| 
 | ||||
|     if (method.nodoc || method.deprecated) { | ||||
|       info(`Skipping ${name}: ${method.nodoc || 'Deprecated'}`); | ||||
| 
 | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|     if (rustMethods[groupName] == null || rustMethods[groupName][iname] == null) { | ||||
|       error(`${name} is defined in js/src/jsonrpc/interfaces, but not in Rust traits`); | ||||
|     } | ||||
| 
 | ||||
|     const desc = method.desc; | ||||
|     const params = buildParameters(method.params); | ||||
|     const returns = `- ${formatType(method.returns)}`; | ||||
|     const example = buildExample(name, method); | ||||
| 
 | ||||
|     const { section } = method; | ||||
|     const toc = section ? tocSections[section] = tocSections[section] || [] : tocMain; | ||||
| 
 | ||||
|     toc.push(`- [${name}](#${name.toLowerCase()})`); | ||||
|     content.push(`### ${name}\n\n${desc}\n\n#### Parameters\n\n${params || 'None'}\n\n#### Returns\n\n${returns || 'None'}${example}`); | ||||
|   }); | ||||
| 
 | ||||
|   markdown = `${markdown}\n${tocMain.join('\n')}`; | ||||
| 
 | ||||
|   Object.keys(tocSections).sort().forEach((section) => { | ||||
|     markdown = `${markdown}\n\n#### ${section}\n${tocSections[section].join('\n')}`; | ||||
|   }); | ||||
| 
 | ||||
|   markdown = `${markdown}\n\n## JSON-RPC API Reference\n\n${content.join('\n\n***\n\n')}\n\n`; | ||||
| 
 | ||||
|   const mdFile = path.join(ROOT_DIR, `${group}.md`); | ||||
| 
 | ||||
|   fs.writeFileSync(mdFile, `${preamble}\n\n${markdown}`, 'utf8'); | ||||
| }); | ||||
| @ -2,17 +2,12 @@ | ||||
| set -e | ||||
| 
 | ||||
| # variables | ||||
| PACKAGES=( "parity" "etherscan" "shapeshift" "jsonrpc" ) | ||||
| PACKAGES=( "parity" ) | ||||
| 
 | ||||
| # change into the build directory | ||||
| BASEDIR=`dirname $0` | ||||
| cd $BASEDIR/.. | ||||
| 
 | ||||
| # build jsonrpc | ||||
| echo "*** Building JSONRPC .json" | ||||
| mkdir -p .npmjs/jsonrpc | ||||
| npm run ci:build:jsonrpc | ||||
| 
 | ||||
| # build all packages | ||||
| echo "*** Building packages for npmjs" | ||||
| echo "$NPM_TOKEN" >> ~/.npmrc | ||||
|  | ||||
| @ -1,32 +0,0 @@ | ||||
| // Copyright 2015-2017 Parity Technologies (UK) Ltd.
 | ||||
| // This file is part of Parity.
 | ||||
| 
 | ||||
| // Parity is free software: you can redistribute it and/or modify
 | ||||
| // it under the terms of the GNU General Public License as published by
 | ||||
| // the Free Software Foundation, either version 3 of the License, or
 | ||||
| // (at your option) any later version.
 | ||||
| 
 | ||||
| // Parity is distributed in the hope that it will be useful,
 | ||||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | ||||
| // GNU General Public License for more details.
 | ||||
| 
 | ||||
| // You should have received a copy of the GNU General Public License
 | ||||
| // along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
| 
 | ||||
| import chalk from 'chalk'; | ||||
| 
 | ||||
| // INFO Logging helper
 | ||||
| export function info (log) { | ||||
|   console.log(chalk.blue(`INFO:\t${log}`)); | ||||
| } | ||||
| 
 | ||||
| // WARN Logging helper
 | ||||
| export function warn (log) { | ||||
|   console.warn(chalk.yellow(`WARN:\t${log}`)); | ||||
| } | ||||
| 
 | ||||
| // ERROR Logging helper
 | ||||
| export function error (log) { | ||||
|   console.error(chalk.red(`ERROR:\t${log}`)); | ||||
| } | ||||
| @ -1,81 +0,0 @@ | ||||
| // Copyright 2015-2017 Parity Technologies (UK) Ltd.
 | ||||
| // This file is part of Parity.
 | ||||
| 
 | ||||
| // Parity is free software: you can redistribute it and/or modify
 | ||||
| // it under the terms of the GNU General Public License as published by
 | ||||
| // the Free Software Foundation, either version 3 of the License, or
 | ||||
| // (at your option) any later version.
 | ||||
| 
 | ||||
| // Parity is distributed in the hope that it will be useful,
 | ||||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | ||||
| // GNU General Public License for more details.
 | ||||
| 
 | ||||
| // You should have received a copy of the GNU General Public License
 | ||||
| // along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
| 
 | ||||
| import fs from 'fs'; | ||||
| import path from 'path'; | ||||
| 
 | ||||
| // ```js
 | ||||
| // rustMethods['eth']['call'] === true
 | ||||
| // ```
 | ||||
| const rustMethods = {}; | ||||
| 
 | ||||
| export default rustMethods; | ||||
| 
 | ||||
| // Get a list of JSON-RPC from Rust trait source code
 | ||||
| function parseMethodsFromRust (source) { | ||||
|   // Matching the custom `rpc` attribute with it's doc comment
 | ||||
|   const attributePattern = /((?:\s*\/\/\/.*$)*)\s*#\[rpc\(([^)]+)\)]/gm; | ||||
|   const commentPattern = /\s*\/\/\/\s*/g; | ||||
|   const separatorPattern = /\s*,\s*/g; | ||||
|   const assignPattern = /([\S]+)\s*=\s*"([^"]*)"/; | ||||
|   const ignorePattern = /@(ignore|deprecated|unimplemented|alias)\b/i; | ||||
| 
 | ||||
|   const methods = []; | ||||
| 
 | ||||
|   source.toString().replace(attributePattern, (match, comment, props) => { | ||||
|     comment = comment.replace(commentPattern, '\n').trim(); | ||||
| 
 | ||||
|     // Skip deprecated methods
 | ||||
|     if (ignorePattern.test(comment)) { | ||||
|       return match; | ||||
|     } | ||||
| 
 | ||||
|     props.split(separatorPattern).forEach((prop) => { | ||||
|       const [, key, value] = prop.split(assignPattern) || []; | ||||
| 
 | ||||
|       if (key === 'name' && value != null) { | ||||
|         methods.push(value); | ||||
|       } | ||||
|     }); | ||||
| 
 | ||||
|     return match; | ||||
|   }); | ||||
| 
 | ||||
|   return methods; | ||||
| } | ||||
| 
 | ||||
| // Get a list of all JSON-RPC methods from all defined traits
 | ||||
| function getMethodsFromRustTraits () { | ||||
|   const traitsDir = path.join(__dirname, '../../../rpc/src/v1/traits'); | ||||
| 
 | ||||
|   return fs.readdirSync(traitsDir) | ||||
|             .filter((name) => name !== 'mod.rs' && /\.rs$/.test(name)) | ||||
|             .map((name) => fs.readFileSync(path.join(traitsDir, name))) | ||||
|             .map(parseMethodsFromRust) | ||||
|             .reduce((a, b) => a.concat(b)); | ||||
| } | ||||
| 
 | ||||
| getMethodsFromRustTraits().sort().forEach((method) => { | ||||
|   const [group, name] = method.split('_'); | ||||
| 
 | ||||
|   // Skip methods with malformed names
 | ||||
|   if (group == null || name == null) { | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
|   rustMethods[group] = rustMethods[group] || {}; | ||||
|   rustMethods[group][name] = true; | ||||
| }); | ||||
| @ -3,7 +3,7 @@ set -e | ||||
| 
 | ||||
| # variables | ||||
| UTCDATE=`date -u "+%Y%m%d-%H%M%S"` | ||||
| PACKAGES=( "parity" "etherscan" "shapeshift" "jsonrpc" ) | ||||
| PACKAGES=( "parity" ) | ||||
| BRANCH=$CI_BUILD_REF_NAME | ||||
| GIT_JS_PRECOMPILED="https://${GITHUB_JS_PRECOMPILED}:@github.com/paritytech/js-precompiled.git" | ||||
| GIT_PARITY="https://${GITHUB_JS_PRECOMPILED}:@github.com/paritytech/parity.git" | ||||
| @ -67,11 +67,6 @@ if [ "$BRANCH" == "master" ]; then | ||||
|   echo "*** Building packages for npmjs" | ||||
|   echo "$NPM_TOKEN" >> ~/.npmrc | ||||
| 
 | ||||
|   # build jsonrpc | ||||
|   echo "*** Building JSONRPC .json" | ||||
|   mkdir -p .npmjs/jsonrpc | ||||
|   npm run ci:build:jsonrpc | ||||
| 
 | ||||
|   for PACKAGE in ${PACKAGES[@]} | ||||
|   do | ||||
|     echo "*** Building $PACKAGE" | ||||
|  | ||||
| @ -1,254 +0,0 @@ | ||||
| // Copyright 2015-2017 Parity Technologies (UK) Ltd.
 | ||||
| // This file is part of Parity.
 | ||||
| 
 | ||||
| // Parity is free software: you can redistribute it and/or modify
 | ||||
| // it under the terms of the GNU General Public License as published by
 | ||||
| // the Free Software Foundation, either version 3 of the License, or
 | ||||
| // (at your option) any later version.
 | ||||
| 
 | ||||
| // Parity is distributed in the hope that it will be useful,
 | ||||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | ||||
| // GNU General Public License for more details.
 | ||||
| 
 | ||||
| // You should have received a copy of the GNU General Public License
 | ||||
| // along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
| 
 | ||||
| // Rust/Parity ABI struct autogenerator.
 | ||||
| // By Gav Wood, 2016.
 | ||||
| 
 | ||||
| var fs = require('fs'); | ||||
| 
 | ||||
| String.prototype.replaceAll = function(f, t) { return this.split(f).join(t); } | ||||
| String.prototype.toSnake = function(){ | ||||
| 	return this.replace(/([A-Z])/g, function($1){return "_"+$1.toLowerCase();}); | ||||
| }; | ||||
| 
 | ||||
| function makeContractFile(name, json, prefs) { | ||||
| 	return `// Autogenerated from JSON contract definition using Rust contract convertor.
 | ||||
| // Command line: ${process.argv.slice(2).join(' ')}
 | ||||
| #![allow(unused_imports)] | ||||
| use std::string::String; | ||||
| use std::result::Result; | ||||
| use std::fmt; | ||||
| use {util, ethabi}; | ||||
| 
 | ||||
| ${convertContract(name, json, prefs)} | ||||
| `;
 | ||||
| } | ||||
| 
 | ||||
| function convertContract(name, json, prefs) { | ||||
| 	return `${prefs._pub ? "pub " : ""}struct ${name} {
 | ||||
| 	contract: ethabi::Contract, | ||||
| 	pub address: util::Address, | ||||
| 	${prefs._explicit_do_call ? "" : `do_call: Box<Fn(util::Address, Vec<u8>) -> Result<Vec<u8>, String> + Send${prefs._sync ? " + Sync " : ""}+ 'static>,`} | ||||
| } | ||||
| impl ${name} { | ||||
| 	pub fn new${prefs._explicit_do_call ? "" : "<F>"}(address: util::Address${prefs._explicit_do_call ? "" : `, do_call: F`}) -> Self | ||||
| 		${prefs._explicit_do_call ? "" : `where F: Fn(util::Address, Vec<u8>) -> Result<Vec<u8>, String> + Send ${prefs._sync ? "+ Sync " : ""}+ 'static`} { | ||||
| 		${name} { | ||||
| 			contract: ethabi::Contract::new(ethabi::Interface::load(b"${JSON.stringify(json.filter(a => a.type == 'function')).replaceAll('"', '\\"')}").expect("JSON is autogenerated; qed")), | ||||
| 			address: address, | ||||
| 			${prefs._explicit_do_call ? "" : `do_call: Box::new(do_call),`} | ||||
| 		} | ||||
| 	} | ||||
| 	fn as_string<T: fmt::Debug>(e: T) -> String { format!("{:?}", e) } | ||||
| 	${json.filter(x => x.type == 'function').map(x => convertFunction(x, prefs)).join("\n")} | ||||
| }`;
 | ||||
| } | ||||
| 
 | ||||
| function mapType(name, type, _prefs) { | ||||
| 	let prefs = _prefs || {}; | ||||
| 	var m; | ||||
| 	if ((m = type.match(/^bytes(\d+)$/)) != null && m[1] <= 32) { | ||||
| 		if (prefs['string']) | ||||
| 			return `&str`; | ||||
| 		else | ||||
| 			return `&util::H${m[1] * 8}`; | ||||
| 	} | ||||
| 	if ((m = type.match(/^(u?)int(\d+)$/)) != null) { | ||||
| 		var n = [8, 16, 32, 64, 128, 160, 256].filter(i => m[2] <= i)[0]; | ||||
| 		if (n) { | ||||
| 			if (n <= 64) | ||||
| 				return `${m[1] == 'u' ? 'u' : 'i'}${n}`; | ||||
| 			if (m[1] == 'u') | ||||
| 				return `util::U${n}`; | ||||
| 			// ERROR - unsupported integer (signed > 32 or unsigned > 256)
 | ||||
| 		} | ||||
| 	} | ||||
| 	if (type == "address") | ||||
| 		return "&util::Address"; | ||||
| 	if (type == "bool") | ||||
| 		return "bool"; | ||||
| 	if (type == "string") | ||||
| 		return "&str"; | ||||
| 	if (type == "bytes") | ||||
| 		return "&[u8]"; | ||||
| 
 | ||||
| 	console.log(`Unsupported argument type: ${type} (${name})`); | ||||
| } | ||||
| 
 | ||||
| function mapReturnType(name, type, _prefs) { | ||||
| 	let prefs = _prefs || {}; | ||||
| 	var m; | ||||
| 	if ((m = type.match(/^bytes(\d+)$/)) != null && m[1] <= 32) { | ||||
| 		if (prefs['string']) | ||||
| 			return `String`; | ||||
| 		else | ||||
| 			return `util::H${m[1] * 8}`; | ||||
| 	} | ||||
| 	if ((m = type.match(/^(u?)int(\d+)$/)) != null) { | ||||
| 		var n = [8, 16, 32, 64, 128, 160, 256].filter(i => m[2] <= i)[0]; | ||||
| 		if (n) { | ||||
| 			if (n <= 64) | ||||
| 				return `${m[1] == 'u' ? 'u' : 'i'}${n}`; | ||||
| 			if (m[1] == 'u') | ||||
| 				return `util::U${n}`; | ||||
| 			// ERROR - unsupported integer (signed > 32 or unsigned > 256)
 | ||||
| 		} | ||||
| 	} | ||||
| 	if (type == "address") | ||||
| 		return "util::Address"; | ||||
| 	if (type == "bool") | ||||
| 		return "bool"; | ||||
| 	if (type == "string") | ||||
| 		return "String"; | ||||
| 	if (type == "bytes") | ||||
| 		return "Vec<u8>"; | ||||
| 	if (type == "address[]") | ||||
| 		return "Vec<util::Address>"; | ||||
| 
 | ||||
| 	console.log(`Unsupported return type: ${type} (${name})`); | ||||
| } | ||||
| 
 | ||||
| function convertToken(name, type, _prefs) { | ||||
| 	let prefs = _prefs || {}; | ||||
| 	var m; | ||||
| 	if ((m = type.match(/^bytes(\d+)$/)) != null && m[1] <= 32) { | ||||
| 		if (prefs['string']) | ||||
| 			return `ethabi::Token::FixedBytes(${name}.as_bytes().to_owned())`; | ||||
| 		else | ||||
| 			return `ethabi::Token::FixedBytes(${name}.as_ref().to_owned())`; | ||||
| 	} | ||||
| 	if ((m = type.match(/^(u?)int(\d+)$/)) != null) { | ||||
| 		var n = [8, 16, 32, 64, 128, 160, 256].filter(i => m[2] <= i)[0]; | ||||
| 		if (n) { | ||||
| 			if (m[1] == 'u') | ||||
| 				return `ethabi::Token::Uint({ let mut r = [0u8; 32]; ${n <= 64 ? "util::U256::from(" + name + " as u64)" : name}.to_big_endian(&mut r); r })`; | ||||
| 			else if (n <= 32) | ||||
| 				return `ethabi::Token::Int(pad_i32(${name} as i32))`; | ||||
| 			// ERROR - unsupported integer (signed > 32 or unsigned > 256)
 | ||||
| 		} | ||||
| 	} | ||||
| 	if (type == "address") | ||||
| 		return `ethabi::Token::Address(${name}.clone().0)`; | ||||
| 	if (type == "bool") | ||||
| 		return `ethabi::Token::Bool(${name})`; | ||||
| 	if (type == "string") | ||||
| 		return `ethabi::Token::String(${name}.to_owned())`; | ||||
| 	if (type == "bytes") | ||||
| 		return `ethabi::Token::Bytes(${name}.to_owned())`; | ||||
| 
 | ||||
| 	console.log(`Unsupported argument type: ${type} (${name})`); | ||||
| } | ||||
| 
 | ||||
| function tokenType(name, type, _prefs) { | ||||
| 	let prefs = _prefs || {}; | ||||
| 	var m; | ||||
| 	if ((m = type.match(/^bytes(\d+)$/)) != null && m[1] <= 32) | ||||
| 		return `${name}.to_fixed_bytes()`; | ||||
| 	if ((m = type.match(/^(u?)int(\d+)$/)) != null) { | ||||
| 		return `${name}.to_${m[1]}int()`; | ||||
| 	} | ||||
| 	if (type == "address") | ||||
| 		return `${name}.to_address()`; | ||||
| 	if (type == "bool") | ||||
| 		return `${name}.to_bool()`; | ||||
| 	if (type == "string") | ||||
| 		return `${name}.to_string()`; | ||||
| 	if (type == "bytes") | ||||
| 		return `${name}.to_bytes()`; | ||||
| 	if (type == "address[]") | ||||
| 		return `${name}.to_array().and_then(|v| v.into_iter().map(|a| a.to_address()).collect::<Option<Vec<[u8; 20]>>>())`; | ||||
| 
 | ||||
| 	console.log(`Unsupported return type: ${type} (${name})`); | ||||
| } | ||||
| 
 | ||||
| function tokenCoerce(name, type, _prefs) { | ||||
| 	let prefs = _prefs || {}; | ||||
| 	var m; | ||||
| 	if ((m = type.match(/^bytes(\d+)$/)) != null && m[1] <= 32) { | ||||
| 		if (prefs['string']) | ||||
| 			return `String::from_utf8(${name}).unwrap_or_else(String::new)`; | ||||
| 		else | ||||
| 			return `util::H${m[1] * 8}::from_slice(${name}.as_ref())`; | ||||
| 	} | ||||
| 	if ((m = type.match(/^(u?)int(\d+)$/)) != null) { | ||||
| 		var n = [8, 16, 32, 64, 128, 160, 256].filter(i => m[2] <= i)[0]; | ||||
| 		if (n && m[1] == 'u') | ||||
| 			return `util::U${n <= 64 ? 256 : n}::from(${name}.as_ref())` + (n <= 64 ? `.as_u64() as u${n}` : ''); | ||||
| 		// ERROR - unsupported integer (signed or unsigned > 256)
 | ||||
| 	} | ||||
| 	if (type == "address") | ||||
| 		return `util::Address::from(${name})`; | ||||
| 	if (type == "bool") | ||||
| 		return `${name}`; | ||||
| 	if (type == "string") | ||||
| 		return `${name}`; | ||||
| 	if (type == "bytes") | ||||
| 		return `${name}`; | ||||
| 	if (type == "address[]") | ||||
| 		return `${name}.into_iter().map(|a| util::Address::from(a)).collect::<Vec<_>>()`; | ||||
| 
 | ||||
| 	console.log(`Unsupported return type: ${type} (${name})`); | ||||
| } | ||||
| 
 | ||||
| function tokenExtract(expr, type, _prefs) { | ||||
| 	return `{ let r = ${expr}; let r = ${tokenType('r', type, _prefs)}.ok_or("Invalid type returned")?; ${tokenCoerce('r', type, _prefs)} }`; | ||||
| } | ||||
| 
 | ||||
| function convertFunction(json, _prefs) { | ||||
| 	let cprefs = _prefs || {}; | ||||
| 	let prefs = (_prefs || {})[json.name] || (_prefs || {})['_'] || {}; | ||||
| 	let snakeName = json.name.toSnake(); | ||||
| 	let params = json.inputs.map((x, i) => (x.name ? x.name.toSnake() : ("_" + (i + 1))) + ": " + mapType(x.name, x.type, prefs[x.name])); | ||||
| 	let returns = json.outputs.length != 1 ? "(" + json.outputs.map(x => mapReturnType(x.name, x.type, prefs[x.name])).join(", ") + ")" : mapReturnType(json.outputs[0].name, json.outputs[0].type, prefs[json.outputs[0].name]); | ||||
| 	return ` | ||||
| 	/// Auto-generated from: \`${JSON.stringify(json)}\`
 | ||||
| 	#[allow(dead_code)] | ||||
| 	pub fn ${snakeName}${cprefs._explicit_do_call ? "<F>" : ""}(&self${cprefs._explicit_do_call ? `, do_call: &F` : ""}${params.length > 0 ? ', ' + params.join(", ") : ''}) -> Result<${returns}, String> | ||||
| 		${cprefs._explicit_do_call ? `where F: Fn(util::Address, Vec<u8>) -> Result<Vec<u8>, String> + Send ${prefs._sync ? "+ Sync " : ""}` : ""} { | ||||
| 		let call = self.contract.function("${json.name}".into()).map_err(Self::as_string)?; | ||||
| 		let data = call.encode_call( | ||||
| 			vec![${json.inputs.map((x, i) => convertToken(x.name ? x.name.toSnake() : ("_" + (i + 1)), x.type, prefs[x.name])).join(', ')}] | ||||
| 		).map_err(Self::as_string)?; | ||||
| 		${json.outputs.length > 0 ? 'let output = ' : ''}call.decode_output((${cprefs._explicit_do_call ? "" : "self."}do_call)(self.address.clone(), data)?).map_err(Self::as_string)?; | ||||
| 		${json.outputs.length > 0 ? 'let mut result = output.into_iter().rev().collect::<Vec<_>>();' : ''} | ||||
| 		Ok((${json.outputs.map((o, i) => tokenExtract('result.pop().ok_or("Invalid return arity")?', o.type, prefs[o.name])).join(', ')})) | ||||
| 	}`;
 | ||||
| } | ||||
| 
 | ||||
| // default preferences:
 | ||||
| let prefs = {"_pub": true, "_": {"_client": {"string": true}, "_platform": {"string": true}}, "_sync": true}; | ||||
| // default contract json ABI
 | ||||
| let jsonabi = [{"constant":true,"inputs":[],"name":"getValidators","outputs":[{"name":"","type":"address[]"}],"payable":false,"type":"function"}]; | ||||
| // default name
 | ||||
| let name = 'Contract'; | ||||
| 
 | ||||
| // parse command line options
 | ||||
| for (let i = 1; i < process.argv.length; ++i) { | ||||
| 	let arg = process.argv[i]; | ||||
| 	if (arg.indexOf("--jsonabi=") == 0) { | ||||
| 		jsonabi = arg.slice(10); | ||||
| 		if (fs.existsSync(jsonabi)) { | ||||
| 			jsonabi = JSON.parse(fs.readFileSync(jsonabi).toString()); | ||||
| 		} | ||||
| 	} else if (arg.indexOf("--explicit-do-call") == 0) { | ||||
| 		prefs._explicit_do_call = true; | ||||
| 	} else if (arg.indexOf("--name=") == 0) { | ||||
| 		name = arg.slice(7); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| let out = makeContractFile(name, jsonabi, prefs); | ||||
| console.log(`${out}`); | ||||
| @ -1,6 +0,0 @@ | ||||
| #!/bin/bash | ||||
| ll | ||||
| ls | ||||
| la | ||||
| echo "list of biniries" | ||||
| exit | ||||
| @ -1,16 +0,0 @@ | ||||
| #!/bin/sh | ||||
| 
 | ||||
| RUSTFMT="rustfmt --write-mode overwrite" | ||||
| 
 | ||||
| $RUSTFMT ./ethash/src/lib.rs | ||||
| $RUSTFMT ./ethcore/src/lib.rs | ||||
| $RUSTFMT ./evmjit/src/lib.rs | ||||
| $RUSTFMT ./json/src/lib.rs | ||||
| $RUSTFMT ./miner/src/lib.rs | ||||
| $RUSTFMT ./parity/main.rs | ||||
| $RUSTFMT ./rpc/src/lib.rs | ||||
| $RUSTFMT ./signer/src/lib.rs | ||||
| $RUSTFMT ./dapps/src/lib.rs | ||||
| $RUSTFMT ./sync/src/lib.rs | ||||
| $RUSTFMT ./util/src/lib.rs | ||||
| 
 | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user