From 979850578a489622d7c37601ddcba7a3640d628a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Go=C5=82=C4=99biowski-Owczarek?= Date: Wed, 18 Nov 2020 00:01:31 +0100 Subject: [PATCH] Build: Add a jQuery Mobile setup script This scripts allow to create a builder instance from scratch without relying on the `post_receive` hook to be installed before proper releases are available. Closes gh-12 --- .jshintignore | 1 + README.md | 44 ++++++++--- package-lock.json | 6 ++ package.json | 1 + scripts/setup-mobile.js | 161 ++++++++++++++++++++++++++++++++++++++++ server.js | 1 + 6 files changed, 203 insertions(+), 11 deletions(-) create mode 100644 .jshintignore create mode 100755 scripts/setup-mobile.js diff --git a/.jshintignore b/.jshintignore new file mode 100644 index 0000000..b744996 --- /dev/null +++ b/.jshintignore @@ -0,0 +1 @@ +scripts diff --git a/README.md b/README.md index ed9934a..e9b4060 100644 --- a/README.md +++ b/README.md @@ -42,26 +42,48 @@ URL arguments are: ### Setup an instance for your project +Perform all the following operations in the `node-amd-builder` main folder. + 1. Clone a bare repo of your project: -``` -mkdir /repos -cd /repos -git clone --bare git://github.com/yourname/yourproject.git -``` + ``` + mkdir repos + cd repos + git clone --bare git://github.com/yourname/yourproject.git + ``` 1. Now create the staging directory: -``` -mkdir /staging -``` + ``` + mkdir -p staging + ``` + 1. Install the dependencies with ```npm install``` 1. Start the service: -``` -node server.js -r /repos -s /staging -``` + ``` + node server.js -r "$(pwd)/repos" -s "$(pwd)/staging" + ``` 1. Add a post_receive hook to the your GitHub repo pointing at ```http://instance:3000/post_receive``` +### Setup an instance for jQuery Migrate + +Perform all the following operations in the `node-amd-builder` main folder. Make sure you use Node.js v14.14.0 or higher. + +1. Install the dependencies with `npm install` + +1. Invoke: + ``` + scripts/setup-mobile.js + ``` + +1. Start the service: + ``` + node server.js -r "$(pwd)/repos" -s "$(pwd)/staging" + ``` + Invoke just `node server.js --help` to see other available options. + +1. ~~Add a post_receive hook to the your GitHub repo pointing at `http://instance:3000/post_receive`~~ (only needed if you don't checkout tags manually as described above) + ## Author * Ghislain Seguin - [@gseguin](http://twitter.com/gseguin) diff --git a/package-lock.json b/package-lock.json index 1fd2a2e..126de74 100644 --- a/package-lock.json +++ b/package-lock.json @@ -120,6 +120,12 @@ "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", "dev": true }, + "adm-zip": { + "version": "0.4.16", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", + "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==", + "dev": true + }, "agent-base": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.1.1.tgz", diff --git a/package.json b/package.json index 1aa2956..4bf2592 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "modern-syslog": "1.2.0" }, "devDependencies": { + "adm-zip": "0.4.16", "grunt": "1.3.0", "grunt-cli": "1.3.2", "grunt-contrib-jshint": "2.1.0", diff --git a/scripts/setup-mobile.js b/scripts/setup-mobile.js new file mode 100755 index 0000000..1b83d6c --- /dev/null +++ b/scripts/setup-mobile.js @@ -0,0 +1,161 @@ +#!/usr/bin/env node + +'use strict'; + +const [ major, minor ] = process.version + .replace(/^v/, '') + .split('.') + .map( part => Number( part ) ); + +if ( major < 14 || major === 14 && minor < 14 ) { + console.error( "Node.js v14.14.0 or higher is required" ); + process.exitCode = 1; + return; +} + +const mobileVersions = [ + "1.5.0-rc1", + "1.5.0-alpha.1", + "1.4.5", + "1.4.4", + "1.4.3", + "1.3.2", + "1.2.1", + "1.1.2", +]; + +const fs = require( "fs" ).promises; +const { existsSync, createWriteStream } = require( "fs" ); +const path = require( "path" ); +const { spawn } = require( "child_process" ); +const https = require( "https" ); +const AdmZip = require( "adm-zip" ); + +const rootPath = path.resolve( __dirname, ".." ); + +const download = async ( url, dest ) => new Promise( ( resolve, reject ) => { + const file = createWriteStream( dest ); + + const request = https.get( url, ( response ) => { + if ( response.statusCode === 301 || response.statusCode === 302 ) { + resolve( download( response.headers.location, dest ) ); + } + + if ( response.statusCode !== 200 ) { + reject( new Error( `Response status was ${ response.statusCode }` ) ); + return; + } + + response.pipe( file ); + } ); + + file.on( "finish", () => { + resolve(); + } ); + + // check for request error too + request.on( "error", async ( err ) => { + await fs.unlink( dest ); + reject( err ); + } ); + + file.on( "error", async ( err ) => { // Handle errors + await fs.unlink( dest ); + reject( err ); + } ); +} ); + +const downloadVersion = async version => { + console.log( `Setting up jQuery Mobile ${ version }` ); + + const parentFolderPath = `${ rootPath }/staging/jquery/${ version }`; + const finalFolderPath = `${ parentFolderPath }/jquery-mobile`; + const zipPath = `${ parentFolderPath }/jquery-mobile-${ version }.zip`; + + if ( existsSync( finalFolderPath ) ) { + console.log( `Version ${ version } already downloaded, skipping.` ); + return; + } + + await fs.mkdir( parentFolderPath, { + recursive: true, + } ); + + await download( + `https://github.com/jquery/jquery-mobile/archive/${ version }.zip`, + zipPath + ); + + const zip = new AdmZip( zipPath ); + + // The zip file contains a single folder named `jquery-mobile-${ version }`. + // Extract it first to the parent path & rename to just "jquery-mobile". + zip.extractAllTo( parentFolderPath, /* overwrite */ true ); + await fs.rename( + `${ parentFolderPath }/jquery-mobile-${ version }`, + finalFolderPath + ); + + await fs.unlink( zipPath ); +}; + +const setupRepos = async () => new Promise( async ( resolve, reject ) => { + console.log( " *** Set up the `repos` folder *** " ); + + const jQueryMobileRepoParentPath = `${ rootPath }/repos/jquery`; + const jQueryMobileRepoPath = `${ jQueryMobileRepoParentPath }/jquery-mobile.git`; + + if ( existsSync( jQueryMobileRepoPath ) ) { + console.log( `jQuery Mobile repo already cloned, removing...` ); + await fs.rm( jQueryMobileRepoPath, { + recursive: true + } ); + console.log( `jQuery Mobile folder removed.` ); + } + + await fs.mkdir( jQueryMobileRepoParentPath, { + recursive: true, + } ); + + console.log( "Cloning the jQuery Mobile repository..." ); + const gitProcess = spawn( + "git clone --bare https://github.com/jquery/jquery-mobile.git", + { + shell: true, + cwd: jQueryMobileRepoParentPath, + pipe: 'inherit', + } + ); + + gitProcess.on( "close", code => { + if ( code === 0 ) { + console.log( "Cloning finished successfully." ); + resolve(); + } else { + process.exitCode = code; + const message = `\`git clone\` child process exited with code ${ code }`; + console.error( message ); + reject( new Error( message ) ); + } + } ); +} ); + +const setupStaging = async () => { + console.log( " *** Set up the `staging` folder *** " ); + + for ( const version of mobileVersions ) { + await downloadVersion( version ); + } +}; + +const main = async () => { + await setupRepos(); + await setupStaging(); +} ; + +main(); + +process.on( "unhandledRejection", ( reason ) => { + process.exitCode = 1; + throw reason; +} ) diff --git a/server.js b/server.js index 8c50ef5..1d272d5 100644 --- a/server.js +++ b/server.js @@ -33,6 +33,7 @@ var argv = require( 'yargs' ) alias: "port", default: 3000 }) + .describe( 'console', 'Pass to print logging messages to the console instead of syslog' ) .usage( 'Usage: $0 -r -s [-p ]' ) .argv;