Skip to content
This repository has been archived by the owner on Jul 16, 2021. It is now read-only.

Commit

Permalink
Merge branch 'master' of https://github.com/stojanovic/scottyjs
Browse files Browse the repository at this point in the history
# Conflicts:
#	package.json
  • Loading branch information
simalexan committed Aug 28, 2017
2 parents f86d6c3 + 9f04124 commit 5ef4b88
Show file tree
Hide file tree
Showing 17 changed files with 1,671 additions and 480 deletions.
5 changes: 5 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
language: node_js
node_js:
- 4.3.2
- 6.11.2
- 8.4.0
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ Deploy static websites or folders to AWS S3 with a single command
<br/>
</hr>

[![Build Status](https://travis-ci.org/stojanovic/scottyjs.svg?branch=master)](https://travis-ci.org/stojanovic/scottyjs)
[![npm](https://img.shields.io/npm/v/scottyjs.svg?maxAge=2592000?style=plastic)](https://www.npmjs.com/package/scottyjs)
[![npm](https://img.shields.io/npm/dt/scottyjs.svg?maxAge=2592000?style=plastic)](https://www.npmjs.com/package/scottyjs)
[![npm](https://img.shields.io/npm/l/scottyjs.svg?maxAge=2592000?style=plastic)](https://github.com/stojanovic/scottyjs/blob/master/LICENSE)
[![Join the chat at https://gitter.im/scottyjs/scotty](https://badges.gitter.im/scottyjs/scotty.svg)](https://gitter.im/scottyjs/scotty?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)

## Install

Scotty.js is available on NPM. Install it as a global dependency to be able to use `scotty` command anywhere:
Expand All @@ -19,7 +25,7 @@ npm install scottyjs --global

> Beam me up, Scotty
![](intro.gif)
![](scotty-intro.gif)

To deploy a static folder to AWS S3 run:

Expand All @@ -45,14 +51,15 @@ beam-me-up {options}
- _--region_ or _-r_ - AWS region where the files will be uploaded, default: saved region if exists or a list to choose one if it is not saved yet
- _--force_ or _-f_ - Update the bucket without asking (default: false, forced region can be overridden with _-r_)
- _--update_ or _-u_ - Update existing bucket (default: false)
- _--delete_ or _-d_ - Delete existing bucket (default: false)

### Examples

#### _Create React App_ application

Full tutorial: http://medium.com/@slobodan/single-command-deployment-for-single-page-apps-29941d62ef97

To deploy [CRA](https://github.com/facebookincubator/create-react-app) apps simply run `npm build` in your project root folder to create build version.
To deploy [CRA](https://github.com/facebookincubator/create-react-app) apps simply run `npm run build` in your project root folder to create build version.

Then deploy build version using following command:

Expand Down
15 changes: 9 additions & 6 deletions bin/scotty.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ const AWS_REGIONS = [
'ap-southeast-1',
'ap-southeast-2',
'ap-northeast-1',
'sa-east-1'
'sa-east-1',
'cn-north-1'
]

function showHelp() {
Expand All @@ -49,8 +50,9 @@ function showHelp() {
${colors.magenta('--source')} ${colors.cyan('or')} ${colors.magenta('-s')} Source of the folder that will be uploaded ${colors.cyan('| default: current folder')}
${colors.magenta('--bucket')} ${colors.cyan('or')} ${colors.magenta('-b')} Name of the S3 bucket ${colors.cyan('| default: name of the current folder')}
${colors.magenta('--region')} ${colors.cyan('or')} ${colors.magenta('-r')} AWS region where the files will be uploaded ${colors.cyan('| default: saved region if exists or a list to choose one if it is not saved yet')}
${colors.magenta('--force')} ${colors.cyan('or')} ${colors.magenta('-f')} Update the bucket without asking, region can be overridden with ${colors.magenta('-r')} ${colors.cyan('| default: false')}
${colors.magenta('--force')} ${colors.cyan('or')} ${colors.magenta('-f')} Update the bucket without asking, region can be overridden with ${colors.magenta('-r')} ${colors.cyan('| default: false')}
${colors.magenta('--update')} ${colors.cyan('or')} ${colors.magenta('-u')} Update existing bucket ${colors.cyan('| default: false')}
${colors.magenta('--delete')} ${colors.cyan('or')} ${colors.magenta('-d')} Delete existing bucket ${colors.cyan('| default: false')}
✤ ✤ ✤
Expand All @@ -72,10 +74,11 @@ function readArgs() {
b: 'bucket',
r: 'region',
f: 'force',
u: 'update'
u: 'update',
d: 'delete'
},
string: ['source', 'bucket', 'region'],
boolean: ['quiet', 'website', 'spa', 'force', 'update'],
boolean: ['quiet', 'website', 'spa', 'force', 'update', 'delete'],
default: {
source: process.cwd(),
bucket: path.parse(process.cwd()).name
Expand Down Expand Up @@ -159,9 +162,9 @@ function cmd(console) {
}

function beamUp (args, region, console) {
return scotty(args.source, args.bucket, region, args.website, args.spa, args.update, args.force, args.quiet, console)
return scotty(args.source, args.bucket, region, args.website, args.spa, args.update, args.delete, args.force, args.quiet, console)
.then(endpoint => clipboardy.write(endpoint))
.then(() => process.exit(1))
.then(() => process.exit(0))
.catch(() => process.exit(1))
}

Expand Down
Binary file removed intro.gif
Binary file not shown.
14 changes: 10 additions & 4 deletions lib/create-bucket.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,19 @@ function createBucket(name, region, s3lib) {
if (!name || !region)
return Promise.reject('Bucket name and region are required')

return s3lib.createBucket({
const options = {
Bucket: name,
ACL: 'public-read',
CreateBucketConfiguration: {
ACL: 'public-read'
}

if (region !== 'us-east-1') {
options.CreateBucketConfiguration = {
LocationConstraint: region
}
}).promise()
}

return s3lib.createBucket(options)
.promise()
.then(result => result.Location)
}

Expand Down
22 changes: 22 additions & 0 deletions lib/delete-bucket.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
'use strict'

const AWS = require('aws-sdk')
const s3 = new AWS.S3()
const emptyBucket = require('./empty-bucket')

function deleteBucket(name, s3lib) {
s3lib = s3lib || s3

if (!name)
return Promise.reject('Bucket name is required')

const options = {
Bucket: name
}

return emptyBucket(name)
.then(() => s3lib.deleteBucket(options).promise())
.then(() => name)
}

module.exports = deleteBucket
30 changes: 30 additions & 0 deletions lib/delete-objects.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
'use strict'

const AWS = require('aws-sdk')
const s3 = new AWS.S3()

function deleteObjects(bucketName, keys, s3lib) {
s3lib = s3lib || s3

if (!bucketName || !keys || !Array.isArray(keys))
return Promise.reject('Bucket name or an array of keys are required')

const options = {
Bucket: bucketName,
Delete: {
Objects: [],
Quiet: false
}
}

keys.forEach(key => {
options.Delete.Objects.push({Key: key})
})

if (keys.length < 1)
return Promise.resolve()

return s3lib.deleteObjects(options).promise()
}

module.exports = deleteObjects
27 changes: 27 additions & 0 deletions lib/empty-bucket.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
'use strict'

const AWS = require('aws-sdk')
const s3 = new AWS.S3()
const deleteObjects = require('./delete-objects')

function emptyBucket(name, s3lib) {
s3lib = s3lib || s3

if (!name)
return Promise.reject('Bucket name is required')

const options = {
Bucket: name
}

return s3lib.listObjectsV2(options)
.promise()
.then(result => {
let keys = result.Contents.map(item => item.Key)
return deleteObjects(name, keys, s3lib)
})
.catch(err => {
throw err })
}

module.exports = emptyBucket
6 changes: 4 additions & 2 deletions lib/reuse-bucket.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

const inquirer = require('inquirer')

function reuseBucket(bucket) {
return inquirer.prompt([{
function reuseBucket(bucket, promptLib) {
promptLib = promptLib || inquirer

return promptLib.prompt([{
type: 'list',
name: 'sameBucket',
message: `"${bucket}" bucket already exist, do you want to use it?`,
Expand Down
38 changes: 36 additions & 2 deletions lib/scotty.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const colors = require('colors')
const getFolderSize = require('get-folder-size')

const createBucket = require('./create-bucket')
const deleteBucket = require('./delete-bucket')
const reuseBucket = require('./reuse-bucket')
const upload = require('./upload')
const getFormattedSize = require('./get-formatted-size')
Expand Down Expand Up @@ -40,7 +41,36 @@ function createOrUpdateBucket(bucket, region, update, force, quiet, logger) {
})
}

function scotty(source, bucket, region, website, spa, update, force, quiet, logger) {
function destroyBucket(bucket, quiet, logger) {
if (!bucket)
return Promise.reject('Bucket is required')

if (!quiet)
logger.log(' empty'.magenta, '✤', colors.cyan(`${bucket} bucket`))
return deleteBucket(bucket)
.then(bucket => {
if (!quiet)
logger.log(' delete'.magenta, '✤', colors.cyan(`${bucket} bucket`))

return bucket
})
.then(response => {
if (!quiet) {
logger.log('\nSuccessfully deleted'.magenta, colors.cyan(bucket), '!'.magenta)
}
return response
})
.catch(err => {
if (!quiet)
logger.error('\n 💥 Vaporization failed 💥 \n'.red, colors.red(err && err.message ? err.message : err || ''))
throw err
})
}

function scotty(source, bucket, region, website, spa, update, destroy, force, quiet, logger) {
if (destroy)
return destroyBucket(bucket, quiet, logger)

if (!source || !bucket || !region)
return Promise.reject('Source, bucket and region are required')

Expand Down Expand Up @@ -91,7 +121,11 @@ function scotty(source, bucket, region, website, spa, update, force, quiet, logg
})
.then(response => {
const cdnUrl = response && response.cdn ? response.url : null
const endpoint = website || spa ? `http://${bucket}.s3-website.${region}.amazonaws.com/` : `http://${bucket}.s3.amazonaws.com/`
const endpoint = website || spa ?
( region === 'us-east-1' ?
`http://${bucket}.s3-website-${region}.amazonaws.com/` :
`http://${bucket}.s3-website.${region}.amazonaws.com/` ) :
`http://${bucket}.s3.amazonaws.com/`

if (!quiet) {
logger.log('\nSuccessfully beamed up!'.magenta, colors.cyan(endpoint), '\nThis link should be copied to your clipboard now.'.magenta)
Expand Down
Loading

0 comments on commit 5ef4b88

Please sign in to comment.