🏡 index : quine-global-boneyard/electron-builder.git

#! /usr/bin/env node

import { AppInfo, CancellationToken, Packager, PackagerOptions, PublishManager, PublishOptions, UploadTask, checkBuildRequestOptions } from "app-builder-lib"
import { Publish } from "app-builder-lib/out/core"
import { computeSafeArtifactNameIfNeeded } from "app-builder-lib/out/platformPackager"
import { getConfig } from "app-builder-lib/out/util/config/config"
import { InvalidConfigurationError, archFromString, log, printErrorAndExit } from "builder-util"
import * as chalk from "chalk"
import * as path from "path"
import * as yargs from "yargs"
import { BuildOptions, normalizeOptions } from "./builder"

/** @internal */
export function configurePublishCommand(yargs: yargs.Argv): yargs.Argv {
  // https://github.com/yargs/yargs/issues/760
  // demandOption is required to be set
  return yargs
    .parserConfiguration({
      "camel-case-expansion": false,
    })
    .option("files", {
      alias: "f",
      string: true,
      type: "array",
      requiresArg: true,
      description: "The file(s) to upload to your publisher",
    })
    .option("version", {
      alias: ["v"],
      type: "string",
      description: "The app/build version used when searching for an upload release (used by some Publishers)",
    })
    .option("config", {
      alias: ["c"],
      type: "string",
      description:
        "The path to an electron-builder config. Defaults to `electron-builder.yml` (or `json`, or `json5`, or `js`, or `ts`), see " + chalk.underline("https://goo.gl/YFRJOM"),
    })
    .demandOption("files")
}

export async function publish(args: { files: string[]; version: string | undefined; configurationFilePath: string | undefined }) {
  const uploadTasks = args.files.map(f => {
    return {
      file: path.resolve(f),
      arch: null,
    }
  })
  return publishArtifactsWithOptions(uploadTasks, args.version, args.configurationFilePath)
}

export async function publishArtifactsWithOptions(
  uploadOptions: { file: string; arch: string | null }[],
  buildVersion?: string,
  configurationFilePath?: string,
  publishConfiguration?: Publish
) {
  const projectDir = process.cwd()
  const config = await getConfig(projectDir, configurationFilePath || null, { publish: publishConfiguration, detectUpdateChannel: false })

  const buildOptions: BuildOptions = normalizeOptions({ config })
  checkBuildRequestOptions(buildOptions)

  const uniqueUploads = Array.from(new Set(uploadOptions))
  const tasks: UploadTask[] = uniqueUploads.map(({ file, arch }) => {
    const filename = path.basename(file)
    return { file, arch: arch ? archFromString(arch) : null, safeArtifactName: computeSafeArtifactNameIfNeeded(filename, () => filename) }
  })

  return publishPackageWithTasks(buildOptions, tasks, buildVersion)
}

async function publishPackageWithTasks(
  options: PackagerOptions & PublishOptions,
  uploadTasks: UploadTask[],
  buildVersion?: string,
  cancellationToken: CancellationToken = new CancellationToken(),
  packager: Packager = new Packager(options, cancellationToken)
) {
  await packager.validateConfig()
  const appInfo = new AppInfo(packager, buildVersion)
  const publishManager = new PublishManager(packager, options, cancellationToken)

  const sigIntHandler = () => {
    log.warn("cancelled by SIGINT")
    packager.cancellationToken.cancel()
    publishManager.cancelTasks()
  }
  process.once("SIGINT", sigIntHandler)

  try {
    const publishConfigurations = await publishManager.getGlobalPublishConfigurations()
    if (publishConfigurations == null || publishConfigurations.length === 0) {
      throw new InvalidConfigurationError("unable to find any publish configuration")
    }

    for (const newArtifact of uploadTasks) {
      for (const publishConfiguration of publishConfigurations) {
        await publishManager.scheduleUpload(publishConfiguration, newArtifact, appInfo)
      }
    }

    await publishManager.awaitTasks()
    return uploadTasks
  } catch (error: any) {
    packager.cancellationToken.cancel()
    publishManager.cancelTasks()
    process.removeListener("SIGINT", sigIntHandler)
    log.error({ message: (error.stack || error.message || error).toString() }, "error publishing")
  }
  return null
}

function main() {
  return publish(configurePublishCommand(yargs).argv as any)
}

if (require.main === module) {
  log.warn("please use as subcommand: electron-builder publish")
  main().catch(printErrorAndExit)
}