Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
ℹ️ Contributors: Please see the Development section of this README.

https://raw.githubusercontent.com/trufflesuite/truffle/develop/packages/require/require.js

const fs = require("fs");
const path = require("path");
const Module = require("module");
const vm = require("vm");
const originalrequire = require("original-require");
const expect = require("@truffle/expect");
const {
  Web3Shim,
  createInterfaceAdapter
} = require("@truffle/interface-adapter");
const Config = require("@truffle/config");

// options.file: path to file to execute. Must be a module that exports a function.
// options.args: arguments passed to the exported function within file. If a callback
//   is not included in args, exported function is treated as synchronous.
// options.context: Object containing any global variables you'd like set when this
//   function is run.
const Require = {
  file: function(options) {
    let source;
    const file = options.file;
    const config = options.config;

    expect.options(options, ["file"]);

    options = Config.default().with(options);

    source = fs.readFileSync(options.file, { encoding: "utf8" });

    // Modified from here: https://gist.github.com/anatoliychakkaev/1599423
    const m = new Module(file);

    // Provide all the globals listed here: https://nodejs.org/api/globals.html
    const context = {
      __dirname: path.dirname(file),
      __filename: file,
      Buffer,
      clearImmediate,
      clearInterval,
      clearTimeout,
      console,
      exports,
      global,
      process,
      setImmediate,
      setInterval,
      setTimeout,
      config,
      module: m,
      artifacts: options.resolver,
      require: pkgPath => {
        // Ugh. Simulate a full require function for the file.
        pkgPath = pkgPath.trim();

        // If absolute, just require.
        if (path.isAbsolute(pkgPath)) return originalrequire(pkgPath);

        // If relative, it's relative to the file.
        if (pkgPath[0] === ".") {
          return originalrequire(path.join(path.dirname(file), pkgPath));
        } else {
          // Not absolute, not relative, must be a globally or locally installed module.
          // Try local first.
          // Here we have to require from the node_modules directory directly.

          var moduleDir = path.dirname(file);
          while (true) {
            try {
              return originalrequire(
                path.join(moduleDir, "node_modules", pkgPath)
              );
            } catch (e) {}
            var oldModuleDir = moduleDir;
            moduleDir = path.join(moduleDir, "..");
            if (moduleDir === oldModuleDir) break;
          }

          // Try global, and let the error throw.
          return originalrequire(pkgPath);
        }
      }
    };

    // Now add contract names.
    Object.keys(options.context || {}).forEach(key => {
      context[key] = options.context[key];
    });

    const old_cwd = process.cwd();

    process.chdir(path.dirname(file));

    const script = vm.createScript(source, file);
    script.runInNewContext(context);

    process.chdir(old_cwd);

    return m.exports;
  },

  exec: function(options, done) {
    expect.options(options, [
      "contracts_build_directory",
      "file",
      "resolver",
      "provider",
      "network",
      "network_id"
    ]);

    const interfaceAdapter = createInterfaceAdapter({
      provider: options.provider,
      networkType: options.networks[options.network].type
    });
    const web3 = new Web3Shim({
      provider: options.provider,
      networkType: options.networks[options.network].type
    });

    try {
      const fn = this.file({
        file: options.file,
        context: { web3, interfaceAdapter },
        resolver: options.resolver,
        config: options
      });
      fn(done);
    } catch (error) {
      done(error);
    }
  }
};

module.exports = Require;