run-server.js
1 require('colors'); 2 3 const fs = require('fs'); 4 const path = require('path'); 5 const express = require('express'); 6 7 const app = express(); 8 const port = process.env.PORT || 3456; 9 10 // Load the metadata for the local build of Atom 11 const buildPath = path.resolve(__dirname, '..', '..', 'out'); 12 const packageJsonPath = path.join(buildPath, 'app', 'package.json'); 13 if (!fs.existsSync(buildPath) || !fs.existsSync(packageJsonPath)) { 14 console.log( 15 `This script requires a full Atom build with release packages for the current platform in the following path:\n ${buildPath}\n` 16 ); 17 if (process.platform === 'darwin') { 18 console.log( 19 `Run this command before trying again:\n script/build --compress-artifacts --test-sign\n\n` 20 ); 21 } else if (process.platform === 'win32') { 22 console.log( 23 `Run this command before trying again:\n script/build --create-windows-installer\n\n` 24 ); 25 } 26 process.exit(1); 27 } 28 29 const appMetadata = require(packageJsonPath); 30 const versionMatch = appMetadata.version.match(/-(beta|nightly)\d+$/); 31 const releaseChannel = versionMatch ? versionMatch[1] : 'stable'; 32 33 console.log( 34 `Serving ${ 35 appMetadata.productName 36 } release assets (channel = ${releaseChannel})\n`.green 37 ); 38 39 function getMacZip(req, res) { 40 console.log(`Received request for atom-mac.zip, sending it`); 41 res.sendFile(path.join(buildPath, 'atom-mac.zip')); 42 } 43 44 function getMacUpdates(req, res) { 45 if (req.query.version !== appMetadata.version) { 46 const updateInfo = { 47 name: appMetadata.version, 48 pub_date: new Date().toISOString(), 49 url: `http://localhost:${port}/mac/atom-mac.zip`, 50 notes: '<p>No Details</p>' 51 }; 52 53 console.log( 54 `Received request for macOS updates (version = ${ 55 req.query.version 56 }), sending\n`, 57 updateInfo 58 ); 59 res.json(updateInfo); 60 } else { 61 console.log( 62 `Received request for macOS updates, sending 204 as Atom is up to date (version = ${ 63 req.query.version 64 })` 65 ); 66 res.sendStatus(204); 67 } 68 } 69 70 function getReleasesFile(fileName) { 71 return function(req, res) { 72 console.log( 73 `Received request for ${fileName}, version: ${req.query.version}` 74 ); 75 if (req.query.version) { 76 const versionMatch = (req.query.version || '').match( 77 /-(beta|nightly)\d+$/ 78 ); 79 const versionChannel = (versionMatch && versionMatch[1]) || 'stable'; 80 if (releaseChannel !== versionChannel) { 81 console.log( 82 `Atom requested an update for version ${ 83 req.query.version 84 } but the current release channel is ${releaseChannel}` 85 ); 86 res.sendStatus(404); 87 return; 88 } 89 } 90 91 res.sendFile(path.join(buildPath, fileName)); 92 }; 93 } 94 95 function getNupkgFile(is64bit) { 96 return function(req, res) { 97 let nupkgFile = req.params.nupkg; 98 if (is64bit) { 99 const nupkgMatch = nupkgFile.match(/atom-(.+)-(delta|full)\.nupkg/); 100 if (nupkgMatch) { 101 nupkgFile = `atom-x64-${nupkgMatch[1]}-${nupkgMatch[2]}.nupkg`; 102 } 103 } 104 105 console.log( 106 `Received request for ${req.params.nupkg}, sending ${nupkgFile}` 107 ); 108 res.sendFile(path.join(buildPath, nupkgFile)); 109 }; 110 } 111 112 if (process.platform === 'darwin') { 113 app.get('/mac/atom-mac.zip', getMacZip); 114 app.get('/api/updates', getMacUpdates); 115 } else if (process.platform === 'win32') { 116 app.get('/api/updates/RELEASES', getReleasesFile('RELEASES')); 117 app.get('/api/updates/:nupkg', getNupkgFile()); 118 app.get('/api/updates-x64/RELEASES', getReleasesFile('RELEASES-x64')); 119 app.get('/api/updates-x64/:nupkg', getNupkgFile(true)); 120 } else { 121 console.log( 122 `The current platform '${ 123 process.platform 124 }' doesn't support Squirrel updates, exiting.`.red 125 ); 126 process.exit(1); 127 } 128 129 app.listen(port, () => { 130 console.log( 131 `Run Atom with ATOM_UPDATE_URL_PREFIX="http://localhost:${port}" set to test updates!\n` 132 .yellow 133 ); 134 });