init(opts = {}) {
    var _this = this;

    return (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () {
      _this._init(opts);

      _this.workspaceRootFolder = yield _this.findWorkspaceRoot(_this.cwd);
      _this.lockfileFolder = _this.workspaceRootFolder || _this.cwd;

      // using focus in a workspace root is not allowed
      if (_this.focus && (!_this.workspaceRootFolder || _this.cwd === _this.workspaceRootFolder)) {
        throw new (_errors || _load_errors()).MessageError(_this.reporter.lang('workspacesFocusRootCheck'));
      }

      if (_this.focus) {
        const focusedWorkspaceManifest = yield _this.readRootManifest();
        _this.focusedWorkspaceName = focusedWorkspaceManifest.name;
      }

      _this.linkedModules = [];

      let linkedModules;
      try {
        linkedModules = yield (_fs || _load_fs()).readdir(_this.linkFolder);
      } catch (err) {
        if (err.code === 'ENOENT') {
          linkedModules = [];
        } else {
          throw err;
        }
      }

      for (var _iterator = linkedModules, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
        var _ref;

        if (_isArray) {
          if (_i >= _iterator.length) break;
          _ref = _iterator[_i++];
        } else {
          _i = _iterator.next();
          if (_i.done) break;
          _ref = _i.value;
        }

        const dir = _ref;

        const linkedPath = path.join(_this.linkFolder, dir);

        if (dir[0] === '@') {
          // it's a scope, not a package
          const scopedLinked = yield (_fs || _load_fs()).readdir(linkedPath);
          _this.linkedModules.push(...scopedLinked.map(function (scopedDir) {
            return path.join(dir, scopedDir);
          }));
        } else {
          _this.linkedModules.push(dir);
        }
      }

      for (var _iterator2 = Object.keys((_index2 || _load_index2()).registries), _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
        var _ref2;

        if (_isArray2) {
          if (_i2 >= _iterator2.length) break;
          _ref2 = _iterator2[_i2++];
        } else {
          _i2 = _iterator2.next();
          if (_i2.done) break;
          _ref2 = _i2.value;
        }

        const key = _ref2;

        const Registry = (_index2 || _load_index2()).registries[key];

        const extraneousRcFiles = Registry === (_index2 || _load_index2()).registries.yarn ? _this.extraneousYarnrcFiles : [];

        // instantiate registry
        const registry = new Registry(_this.cwd, _this.registries, _this.requestManager, _this.reporter, _this.enableDefaultRc, extraneousRcFiles);
        yield registry.init({
          registry: opts.registry
        });

        _this.registries[key] = registry;
        if (_this.registryFolders.indexOf(registry.folder) === -1) {
          _this.registryFolders.push(registry.folder);
        }
      }

      if (_this.modulesFolder) {
        _this.registryFolders = [_this.modulesFolder];
      }

      _this.networkConcurrency = opts.networkConcurrency || Number(_this.getOption('network-concurrency')) || (_constants || _load_constants()).NETWORK_CONCURRENCY;

      _this.childConcurrency = opts.childConcurrency || Number(_this.getOption('child-concurrency')) || Number(process.env.CHILD_CONCURRENCY) || (_constants || _load_constants()).CHILD_CONCURRENCY;

      _this.networkTimeout = opts.networkTimeout || Number(_this.getOption('network-timeout')) || (_constants || _load_constants()).NETWORK_TIMEOUT;

      const httpProxy = opts.httpProxy || _this.getOption('proxy');
      const httpsProxy = opts.httpsProxy || _this.getOption('https-proxy');
      _this.requestManager.setOptions({
        userAgent: String(_this.getOption('user-agent')),
        httpProxy: httpProxy === false ? false : String(httpProxy || ''),
        httpsProxy: httpsProxy === false ? false : String(httpsProxy || ''),
        strictSSL: Boolean(_this.getOption('strict-ssl')),
        ca: Array.prototype.concat(opts.ca || _this.getOption('ca') || []).map(String),
        cafile: String(opts.cafile || _this.getOption('cafile', true) || ''),
        cert: String(opts.cert || _this.getOption('cert') || ''),
        key: String(opts.key || _this.getOption('key') || ''),
        networkConcurrency: _this.networkConcurrency,
        networkTimeout: _this.networkTimeout
      });

      _this.globalFolder = opts.globalFolder || String(_this.getOption('global-folder', true));
      if (_this.globalFolder === 'undefined') {
        _this.globalFolder = (_constants || _load_constants()).GLOBAL_MODULE_DIRECTORY;
      }

      let cacheRootFolder = opts.cacheFolder || _this.getOption('cache-folder', true);

      if (!cacheRootFolder) {
        let preferredCacheFolders = (_constants || _load_constants()).PREFERRED_MODULE_CACHE_DIRECTORIES;
        const preferredCacheFolder = opts.preferredCacheFolder || _this.getOption('preferred-cache-folder', true);

        if (preferredCacheFolder) {
          preferredCacheFolders = [String(preferredCacheFolder)].concat(preferredCacheFolders);
        }

        const cacheFolderQuery = yield (_fs || _load_fs()).getFirstSuitableFolder(preferredCacheFolders, (_fs || _load_fs()).constants.W_OK | (_fs || _load_fs()).constants.X_OK | (_fs || _load_fs()).constants.R_OK // eslint-disable-line no-bitwise
        );
        for (var _iterator3 = cacheFolderQuery.skipped, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {
          var _ref3;

          if (_isArray3) {
            if (_i3 >= _iterator3.length) break;
            _ref3 = _iterator3[_i3++];
          } else {
            _i3 = _iterator3.next();
            if (_i3.done) break;
            _ref3 = _i3.value;
          }

          const skippedEntry = _ref3;

          _this.reporter.warn(_this.reporter.lang('cacheFolderSkipped', skippedEntry.folder));
        }

        cacheRootFolder = cacheFolderQuery.folder;
        if (cacheRootFolder && cacheFolderQuery.skipped.length > 0) {
          _this.reporter.warn(_this.reporter.lang('cacheFolderSelected', cacheRootFolder));
        }
      }

      if (!cacheRootFolder) {
        throw new (_errors || _load_errors()).MessageError(_this.reporter.lang('cacheFolderMissing'));
      } else {
        _this._cacheRootFolder = String(cacheRootFolder);
      }

      const manifest = yield _this.maybeReadManifest(_this.lockfileFolder);

      const plugnplayByEnv = _this.getOption('plugnplay-override');
      if (plugnplayByEnv != null) {
        _this.plugnplayEnabled = plugnplayByEnv !== 'false' && plugnplayByEnv !== '0';
        _this.plugnplayPersist = false;
      } else if (opts.enablePnp || opts.disablePnp) {
        _this.plugnplayEnabled = !!opts.enablePnp;
        _this.plugnplayPersist = true;
      } else if (manifest && manifest.installConfig && manifest.installConfig.pnp) {
        _this.plugnplayEnabled = !!manifest.installConfig.pnp;
        _this.plugnplayPersist = false;
      } else {
        _this.plugnplayEnabled = false;
        _this.plugnplayPersist = false;
      }

      if (process.platform === 'win32') {
        const cacheRootFolderDrive = path.parse(_this._cacheRootFolder).root.toLowerCase();
        const lockfileFolderDrive = path.parse(_this.lockfileFolder).root.toLowerCase();

        if (cacheRootFolderDrive !== lockfileFolderDrive) {
          if (_this.plugnplayEnabled) {
            _this.reporter.warn(_this.reporter.lang('plugnplayWindowsSupport'));
          }
          _this.plugnplayEnabled = false;
          _this.plugnplayPersist = false;
        }
      }

      _this.plugnplayShebang = String(_this.getOption('plugnplay-shebang') || '') || '/usr/bin/env node';
      _this.plugnplayBlacklist = String(_this.getOption('plugnplay-blacklist') || '') || null;

      _this.ignoreScripts = opts.ignoreScripts || Boolean(_this.getOption('ignore-scripts', false));

      _this.workspacesEnabled = _this.getOption('workspaces-experimental') !== false;
      _this.workspacesNohoistEnabled = _this.getOption('workspaces-nohoist-experimental') !== false;

      _this.offlineCacheFolder = String(_this.getOption('offline-cache-folder') || '') || null;

      _this.pruneOfflineMirror = Boolean(_this.getOption('yarn-offline-mirror-pruning'));
      _this.enableMetaFolder = Boolean(_this.getOption('enable-meta-folder'));
      _this.enableLockfileVersions = Boolean(_this.getOption('yarn-enable-lockfile-versions'));
      _this.linkFileDependencies = Boolean(_this.getOption('yarn-link-file-dependencies'));
      _this.packBuiltPackages = Boolean(_this.getOption('experimental-pack-script-packages-in-mirror'));

      _this.autoAddIntegrity = !(0, (_conversion || _load_conversion()).boolifyWithDefault)(String(_this.getOption('unsafe-disable-integrity-migration')), true);

      //init & create cacheFolder, tempFolder
      _this.cacheFolder = path.join(_this._cacheRootFolder, 'v' + String((_constants || _load_constants()).CACHE_VERSION));
      _this.tempFolder = opts.tempFolder || path.join(_this.cacheFolder, '.tmp');
      yield (_fs || _load_fs()).mkdirp(_this.cacheFolder);
      yield (_fs || _load_fs()).mkdirp(_this.tempFolder);

      if (opts.production !== undefined) {
        _this.production = Boolean(opts.production);
      } else {
        _this.production = Boolean(_this.getOption('production')) || process.env.NODE_ENV === 'production' && process.env.NPM_CONFIG_PRODUCTION !== 'false' && process.env.YARN_PRODUCTION !== 'false';
      }

      if (_this.workspaceRootFolder && !_this.workspacesEnabled) {
        throw new (_errors || _load_errors()).MessageError(_this.reporter.lang('workspacesDisabled'));
      }
    })();
  }
Initialise config. Fetch registry options, find package roots.