Browse Source

Add publish-to-npm script

John Kleinschmidt 7 years ago
parent
commit
40e37c68d5
5 changed files with 236 additions and 0 deletions
  1. 10 0
      npm/cli.js
  2. 10 0
      npm/index.js
  3. 65 0
      npm/install.js
  4. 26 0
      npm/package.json
  5. 125 0
      script/publish-to-npm.js

+ 10 - 0
npm/cli.js

@@ -0,0 +1,10 @@
+#!/usr/bin/env node
+
+var electron = require('./')
+
+var proc = require('child_process')
+
+var child = proc.spawn(electron, process.argv.slice(2), {stdio: 'inherit'})
+child.on('close', function (code) {
+  process.exit(code)
+})

+ 10 - 0
npm/index.js

@@ -0,0 +1,10 @@
+var fs = require('fs')
+var path = require('path')
+
+var pathFile = path.join(__dirname, 'path.txt')
+
+if (fs.existsSync(pathFile)) {
+  module.exports = path.join(__dirname, fs.readFileSync(pathFile, 'utf-8'))
+} else {
+  throw new Error('Electron failed to install correctly, please delete node_modules/electron and try installing again')
+}

+ 65 - 0
npm/install.js

@@ -0,0 +1,65 @@
+#!/usr/bin/env node
+
+// maintainer note - x.y.z-ab version in package.json -> x.y.z
+var version = require('./package').version.replace(/-.*/, '')
+
+var fs = require('fs')
+var os = require('os')
+var path = require('path')
+var extract = require('extract-zip')
+var download = require('electron-download')
+
+var installedVersion = null
+try {
+  installedVersion = fs.readFileSync(path.join(__dirname, 'dist', 'version'), 'utf-8').replace(/^v/, '')
+} catch (ignored) {
+  // do nothing
+}
+
+var platformPath = getPlatformPath()
+
+if (installedVersion === version && fs.existsSync(path.join(__dirname, platformPath))) {
+  process.exit(0)
+}
+
+// downloads if not cached
+download({
+  cache: process.env.electron_config_cache,
+  version: version,
+  platform: process.env.npm_config_platform,
+  arch: process.env.npm_config_arch,
+  strictSSL: process.env.npm_config_strict_ssl === 'true',
+  force: process.env.force_no_cache === 'true',
+  quiet: ['info', 'verbose', 'silly', 'http'].indexOf(process.env.npm_config_loglevel) === -1
+}, extractFile)
+
+// unzips and makes path.txt point at the correct executable
+function extractFile (err, zipPath) {
+  if (err) return onerror(err)
+  extract(zipPath, {dir: path.join(__dirname, 'dist')}, function (err) {
+    if (err) return onerror(err)
+    fs.writeFile(path.join(__dirname, 'path.txt'), platformPath, function (err) {
+      if (err) return onerror(err)
+    })
+  })
+}
+
+function onerror (err) {
+  throw err
+}
+
+function getPlatformPath () {
+  var platform = process.env.npm_config_platform || os.platform()
+
+  switch (platform) {
+    case 'darwin':
+      return 'dist/Electron.app/Contents/MacOS/Electron'
+    case 'freebsd':
+    case 'linux':
+      return 'dist/electron'
+    case 'win32':
+      return 'dist/electron.exe'
+    default:
+      throw new Error('Electron builds are not available on platform: ' + platform)
+  }
+}

+ 26 - 0
npm/package.json

@@ -0,0 +1,26 @@
+{
+  "scripts": {
+    "cache-clean": "rm -rf ~/.electron && rm -rf dist",
+    "postinstall": "node install.js",
+    "pretest": "npm run cache-clean",
+    "test": "standard"
+  },
+  "bin": {
+    "electron": "cli.js"
+  },
+  "main": "index.js",
+  "types": "electron.d.ts",
+  "dependencies": {
+    "@types/node": "^7.0.18",
+    "electron-download": "^3.0.1",
+    "extract-zip": "^1.0.3"
+  },
+  "devDependencies": {
+    "home-path": "^0.1.1",
+    "path-exists": "^2.0.0",
+    "standard": "^5.4.1"
+  },
+  "directories": {
+    "test": "test"
+  }
+}

+ 125 - 0
script/publish-to-npm.js

@@ -0,0 +1,125 @@
+const temp = require('temp')
+const fs = require('fs')
+const path = require('path')
+const childProcess = require('child_process')
+const GitHubApi = require('github')
+const request = require('request')
+const assert = require('assert')
+const rootPackageJson = require('../package.json')
+
+const github = new GitHubApi({
+  // debug: true,
+  headers: { 'User-Agent': 'electron-npm-publisher' },
+  followRedirects: false
+})
+
+let tempDir
+temp.track()   // track and cleanup files at exit
+
+const files = [
+  'cli.js',
+  'index.js',
+  'install.js',
+  'package.json',
+  'README.md'
+]
+
+const jsonFields = [
+  'name',
+  'version',
+  'repository',
+  'description',
+  'license',
+  'author',
+  'keywords'
+]
+
+let npmTag = ''
+
+new Promise((resolve, reject) => {
+  temp.mkdir('electron-npm', (err, dirPath) => {
+    if (err) {
+      reject(err)
+    } else {
+      resolve(dirPath)
+    }
+  })
+})
+.then((dirPath) => {
+  tempDir = dirPath
+  // copy files from `/npm` to temp directory
+  files.forEach((name) => {
+    fs.writeFileSync(
+      path.join(tempDir, name),
+      fs.readFileSync(path.join(__dirname, '..', name === 'README.md' ? '' : 'npm', name))
+    )
+  })
+  // copy from root package.json to temp/package.json
+  const packageJson = require(path.join(tempDir, 'package.json'))
+  jsonFields.forEach((fieldName) => {
+    packageJson[fieldName] = rootPackageJson[fieldName]
+  })
+  fs.writeFileSync(
+    path.join(tempDir, 'package.json'),
+    JSON.stringify(packageJson, null, 2)
+  )
+
+  return github.repos.getReleases({
+    owner: 'electron',
+    repo: 'electron'
+  })
+})
+.then((releases) => {
+  // download electron.d.ts from release
+  const release = releases.data.find(
+    (release) => release.tag_name === `v${rootPackageJson.version}`
+  )
+  if (!release) {
+    throw new Error(`cannot find release with tag v${rootPackageJson.version}`)
+  }
+  return release
+})
+.then((release) => {
+  const tsdAsset = release.assets.find((asset) => asset.name === 'electron.d.ts')
+  if (!tsdAsset) {
+    throw new Error(`cannot find electron.d.ts from v${rootPackageJson.version} release assets`)
+  }
+  return new Promise((resolve, reject) => {
+    request.get({
+      url: tsdAsset.url,
+      headers: {
+        'accept': 'application/octet-stream',
+        'user-agent': 'electron-npm-publisher'
+      }
+    }, (err, response, body) => {
+      if (err || response.statusCode !== 200) {
+        reject(err || new Error('Cannot download electron.d.ts'))
+      } else {
+        fs.writeFileSync(path.join(tempDir, 'electron.d.ts'), body)
+        resolve(release)
+      }
+    })
+  })
+})
+.then((release) => {
+  npmTag = release.prerelease ? 'beta' : 'latest'
+})
+.then(() => childProcess.execSync('npm pack', { cwd: tempDir }))
+.then(() => {
+  // test that the package can install electron prebuilt from github release
+  const tarballPath = path.join(tempDir, `${rootPackageJson.name}-${rootPackageJson.version}.tgz`)
+  return new Promise((resolve, reject) => {
+    childProcess.execSync(`npm install ${tarballPath} --force --silent`, {
+      env: Object.assign({}, process.env, { electron_config_cache: tempDir }),
+      cwd: tempDir
+    })
+    const checkVersion = childProcess.execSync(`${path.join(tempDir, 'node_modules', '.bin', 'electron')} -v`)
+    assert.strictEqual(checkVersion.toString().trim(), `v${rootPackageJson.version}`)
+    resolve(tarballPath)
+  })
+})
+.then((tarballPath) => childProcess.execSync(`npm publish ${tarballPath} --tag ${npmTag}`))
+.catch((err) => {
+  console.error(`Error: ${err}`)
+  process.exit(1)
+})