async function configDrive (url, {forkOf, tags} = {forkOf: undefined, tags: undefined}) {
  var release = await lock('filesystem:drives')
  try {
    var key = await hyper.drives.fromURLToKey(url, true)
    var driveCfg = drives.find(d => d.key === key)
    if (!driveCfg) {
      let drive = await hyper.drives.getOrLoadDrive(url)
      let manifest = await drive.pda.readManifest().catch(_ => ({}))

      driveCfg = /** @type DriveConfig */({key})
      if (tags && Array.isArray(tags) && tags.every(t => typeof t === 'string')) {
        driveCfg.tags = tags.filter(Boolean)
      }
      if (forkOf && typeof forkOf === 'object') {
        driveCfg.forkOf = forkOf
      }

      if (!drive.writable) {
        // announce the drive
        drive.session.drive.configureNetwork({
          announce: true,
          lookup: true
        })
      }

      // for forks, we need to ensure:
      // 1. the drives.json forkOf.key is the same as index.json forkOf value
      // 2. there's a local forkOf.label
      // 3. the parent is saved
      if (manifest.forkOf && typeof manifest.forkOf === 'string') {
        if (!driveCfg.forkOf) driveCfg.forkOf = {key: undefined, label: undefined}
        driveCfg.forkOf.key = await hyper.drives.fromURLToKey(manifest.forkOf, true)
        if (!driveCfg.forkOf.label) {
          let message = 'Choose a label to save this fork under (e.g. "dev" or "bobs-changes")'
          let promptRes = await modals.create(BrowserWindow.getFocusedWindow().webContents, 'prompt', {message}).catch(e => false)
          if (!promptRes || !promptRes.value) return
          driveCfg.forkOf.label = promptRes.value
        }

        let parentDriveCfg = drives.find(d => d.key === driveCfg.forkOf.key)
        if (!parentDriveCfg) {
          drives.push({key: driveCfg.forkOf.key})
        }
      }

      drives.push(driveCfg)
    } else {
      if (typeof tags !== 'undefined') {
        if (tags && Array.isArray(tags) && tags.every(t => typeof t === 'string')) {
          driveCfg.tags = tags.filter(Boolean)
        } else {
          delete driveCfg.tags
        }
      }
      if (typeof forkOf !== 'undefined') {
        if (forkOf && typeof forkOf === 'object') {
          driveCfg.forkOf = forkOf
        } else {
          delete driveCfg.forkOf
        }
      }
    }
    await rootDrive.pda.writeFile('/drives.json', JSON.stringify({drives}, null, 2))
  } finally {
    release()
  }
}
@param {string} url
@param {Object} [opts]
@param {Object} [opts.forkOf]
@param {string[]} [opts.tags]
@returns {Promise<void>}