pragma-consistency.js 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. #!/usr/bin/env node
  2. const path = require('path');
  3. const semver = require('semver');
  4. const match = require('micromatch');
  5. const { findAll } = require('solidity-ast/utils');
  6. const { _: artifacts } = require('yargs').argv;
  7. // files to skip
  8. const skipPatterns = ['contracts-exposed/**', 'contracts/mocks/WithInit.sol'];
  9. for (const artifact of artifacts) {
  10. const { output: solcOutput } = require(path.resolve(__dirname, '../..', artifact));
  11. const pragma = {};
  12. // Extract pragma directive for all files
  13. for (const source in solcOutput.contracts) {
  14. if (match.any(source, skipPatterns)) continue;
  15. for (const { literals } of findAll('PragmaDirective', solcOutput.sources[source].ast)) {
  16. // There should only be one.
  17. const [first, ...rest] = literals;
  18. if (first === 'solidity') pragma[source] = rest.join('');
  19. }
  20. }
  21. // Compare the pragma directive of the file, to that of the files it imports
  22. for (const source in solcOutput.contracts) {
  23. if (match.any(source, skipPatterns)) continue;
  24. // minimum version of the compiler that matches source's pragma
  25. const minVersion = semver.minVersion(pragma[source]);
  26. // loop over all imports in source
  27. for (const { absolutePath } of findAll('ImportDirective', solcOutput.sources[source].ast)) {
  28. // So files that only import without declaring anything cause issues, because they don't shop in "pragma"
  29. if (!pragma[absolutePath]) continue;
  30. // Check that the minVersion for source satisfies the requirements of the imported files
  31. if (!semver.satisfies(minVersion, pragma[absolutePath])) {
  32. console.log(
  33. `- ${source} uses ${pragma[source]} but depends on ${absolutePath} that requires ${pragma[absolutePath]}`,
  34. );
  35. process.exitCode = 1;
  36. }
  37. }
  38. }
  39. }
  40. if (!process.exitCode) {
  41. console.log('Pragma directives are consistent.');
  42. }