Skip to content

Instantly share code, notes, and snippets.

@theprojectsomething
Last active May 21, 2017 08:35
Show Gist options
  • Save theprojectsomething/73eccbcda8cc88c5ad11993cc90fca4e to your computer and use it in GitHub Desktop.
Save theprojectsomething/73eccbcda8cc88c5ad11993cc90fca4e to your computer and use it in GitHub Desktop.
launchpack - an npm-powered boilerplate launcher πŸ‘Š

LaunchPack

An npm-powered boilerplate launcher πŸ‘Š
  1. Download this gist
  2. drop the package.json where you develop .. say ~/www
  3. online with npm installed? open a terminal and boom ...
npm run launchpack
  1. follow the prompts to automated heaven

Say What?

LaunchPack is an tiny yet epic tool for kicking off projects quicker than you do, using packages you already defined, so you're never more then moments away from an initial commit.

You'll go from zero to your own personal hero.

LaunchPack uses npm-scripts to download and organise files from wherever, however.

No more installs. Everything. In. One. Tiny. Package.json.

Who's it for?

  • a frontend-fanatic who hones their own HTML, while juggling a JS framework from one boomer with boilerplate SASS from another πŸ”₯πŸ”¨
  • a fullstack god rolling a flavour for each layer (latest WP with your seven favourite plugins and a custom theme thrown in for good measure ... boom it's done) πŸ’£βš‘οΈ
  • AN NPM NINJA ... or ninny, whatever.

Roll your own package

Start by pulling together some resources .. lets mix up the king of front-end kickoffs with a bit of foundation:

{
    "resources": {
        "foundation":       "https://github.com/zurb/foundation-sites/archive/master.zip",
        "html5boilerplate": "https://github.com/h5bp/html5-boilerplate/archive/master.zip"
    }
}

Everything is defined in package.json, where all the regular caveats apply. We've used GH zip files above to save some overhead, but you can safely use .git, plus any server you choose.

Next we pick which of our resources to chew on and where:

{
    "packages": {
        "frontend": [
            {
              "resource":   "html5boilerplate",
              "files":      "*/dist/"
            },
            {
              "resource":   "foundation",
              "files":      "*/dist/js/",
              "output":     "/js/vendor/foundation"
            },
            {
              "resource":   "foundation",
              "files":      "*/dist/css/",
              "output":     "/css/foundation"
            }
        ]
    }
}

And there you go, our resources are set to load in order; so it's a html5bp base sprinkled with some foundation scripts and styles. The files and output help us define what goes where (more on that below).

To test our package just open a terminal and kick things off as you would any package.json:

npm install

Package Particulars

Packages aren't very complex. We're talking a list of named resources, loaded in order of appearance, each with 4 possible properties:

resource*

This one is self explanatory (and required) - it points to the resource url

files

Specifies which files/directories you're interested in from the resource - wildcard (*) and not (!) selectors give it super powers! Leave the property out and you get the lot.

output

Where you want the files to go. Want to place a resource deep down in your structure? Include an output and your files won't ever get a root (note that it's relative to the install directory you are prompted for when you run launchpack)

branch

A bleeding-edge kinda dev? You can change the branch you're checking out with this lovely little tingler. .git only!

Questions? Complaints? Vast improvements?

I would literally make babies with someone who can speak bash. Hit a brother up!

{
"name": "launchpack",
"description": "npm-powered project-template launcher",
"repository": "gist:73eccbcda8cc88c5ad11993cc90fca4e",
"version": "0.1.0",
"license": "MIT",
"author": "Som Meaden <som@theprojectsomething.com> (https://theprojectsomething.com)",
"resources": {
"html5boilerplate": "https://github.com/h5bp/html5-boilerplate/archive/master.zip",
"normalize": "https://github.com/necolas/normalize.css/archive/master.zip",
"foundation": "https://github.com/zurb/foundation-sites/archive/master.zip",
"wordpress": "https://github.com/WordPress/WordPress/archive/master.zip",
"acfplugin": "https://github.com/elliotcondon/acf/archive/master.zip",
"jetpackplugin": "https://github.com/Automattic/jetpack/archive/master.zip",
"underscorestheme": "https://github.com/Automattic/_s/archive/master.zip",
"boilerplate": "https://github.com/theprojectsomething/boilerplate.git"
},
"packages": {
"frontend": [
{
"resource": "html5boilerplate",
"files": "*/dist/"
},
{
"resource": "normalize",
"files": "normalize.css",
"output": "/css"
},
{
"resource": "foundation",
"files": "*/dist/js/",
"output": "/js/vendor/foundation"
},
{
"resource": "foundation",
"files": "*/dist/css/",
"output": "/css/foundation"
}
],
"wordpress": [
{
"resource": "wordpress"
},
{
"resource": "acfplugin",
"output": "/wp-content/plugins/acf"
},
{
"resource": "jetpackplugin",
"output": "/wp-content/plugins/jetpack"
},
{
"resource": "underscorestheme",
"output": "/wp-content/themes/_s"
}
],
"static": [
{
"resource": "boilerplate",
"files": "static/",
"branch": "master"
}
]
},
"*":["<-- WARNING: beyond here be dragons! -->"],
"scripts": {
"*":["<-- HELPERS: big things, little code -->"],
"h": "echo $'\n\\033[1;103;30m '${npm_package_config_h}$' \\033[0m '",
"q:open": "while [[ $answer == '' ]]; do read -p \"$(npm run h --launchpack:h=\"${npm_package_config_q}:\")`echo $'\n> '`\" answer; if [[ $answer == '' ]]; then answer=$(npm run q:yesno --launchpack:q=\"$npm_package_config_qe\" --launchpack:qd=\"$npm_package_config_qd\"); fi; done; echo $answer",
"q:yesno": "read -p \"${npm_package_config_q:=Leave empty?} (y/n): \" -n 1 -r; if [[ $REPLY =~ ^[Yy]$ ]]; then answer=${npm_package_config_qd:=\"y\"}; fi; echo $answer",
"q:yesnoh": "read -p \"$(npm run h --launchpack:h=\"${npm_package_config_q:=Leave empty?} (y/n): \")\" -n 1 -r; if [[ $REPLY =~ ^[Yy]$ ]]; then answer=${npm_package_config_qd:=\"y\"}; fi; echo $answer",
"*":[ "<-- HELPERS -->" ],
"*":[ "<-- PACKAGE: package handlers -->" ],
"package:installer": "selected=$(npm run package:select); package=($(npm run package:options --launchpack:selected=$selected)); dir=$(npm run q:open --launchpack:q=\"Install directory\n\" --launchpack:qe=\"Use current?\" --launchpack:qd=\"$PWD\" -s); if [ $dir == $PWD ]; then echo; fi; cache=$(npm run files:init); echo \"\n... loading\"; for i in ${package[@]}; do npm run resource --launchpack:i=$i --launchpack:dir=$dir; done && if [ -z $cache ]; then npm run files:clean; fi; echo $'\n\"'\"\\033[4m${selected}\\033[0m\"$'\" launched!'",
"package:options": "vars=\"${!npm_package_packages_*}\"; prev=; list=(); for item in $vars; do parts=(${item//_/ }); key=\"${parts[*]:3:1}\"; if [ -n \"$npm_package_config_selected\" ]; then if [ \"$npm_package_config_selected\" != \"$key\" ]; then continue; fi; key=($(IFS=_ ; echo \"${parts[*]:0:5}\")); fi; if [ \"$prev\" != \"$key\" ]; then prev=$key; list+=(\"$key\"); fi; done; echo \"${list[@]}\"",
"package:select": "options=($(npm run package:options));l=${#options[@]};npm run h --launchpack:h=\"Available Packages:\" >&2;PS3=$'Select 1-'${l}$': ';select opt in ${options[@]}; do if [ \"$REPLY\" -lt $(( $l+1 )) ]; then echo $opt; break; fi; done",
"*":[ "<-- PACKAGE -->" ],
"*":[ "<-- RESOURCE: individual resource handlers -->" ],
"resource": "output=$(npm run resource:value --launchpack:i=$npm_package_config_i --launchpack:key=output); files=$(npm run resource:value --launchpack:i=$npm_package_config_i --launchpack:key=files); name=$(npm run resource:value --launchpack:i=$npm_package_config_i); url=$(npm run resource:url --launchpack:i=$name); type=$(npm run resource:type --launchpack:url=$url); npm run ${type}:fetch --launchpack:url=$url --launchpack:name=$name --launchpack:i=$npm_package_config_i && npm run files:move -s --launchpack:files=\"${name}/${files:=*/*}\" --launchpack:dir=${npm_package_config_dir}/${output:=}",
"resource:value": "r=${npm_package_config_i}_${npm_package_config_key:=resource}; echo ${!r};",
"resource:url": "r=npm_package_resources_${npm_package_config_i}; echo ${!r};",
"resource:type": "ext=${npm_package_config_url: -4}; if [ $ext == \".zip\" ]; then echo 'zip'; elif [ $ext == \".git\" ]; then echo 'git'; fi",
"*":[ "<-- RESOURCE -->" ],
"*":[ "<-- FILES: handles moving, caching, removing -->" ],
"files:init": "npm run files:clean --launchpack:q='Load package from cache?'; if [ -d \".launchpack\" ]; then echo 1; fi; mkdir -p .launchpack",
"files:clean": "if [ -d \".launchpack\" ]; then cache=$(npm run q:yesnoh --launchpack:q=\"${npm_package_config_q:=\"Cache loaded package?\"}\"); if [ -z \"$cache\" ]; then rm -rf .launchpack; fi; fi",
"prefiles:move": "mkdir -p $npm_package_config_dir",
"files:move": "shopt -s extglob && cp -pRLn .launchpack/$npm_package_config_files $npm_package_config_dir 2>/dev/null || :",
"*":[ "<-- FILES -->" ],
"*":[ "<-- GIT: clone and checkout -->" ],
"git:fetch": "dir=.launchpack/${npm_package_config_name}; branch=$(npm run resource:value --launchpack:i=$npm_package_config_i --launchpack:key=\"branch\"); if [ ! -d $dir ]; then npm run git:clone --launchpack:branch=$branch --launchpack:url=$npm_package_config_url --launchpack:dir=$dir; fi",
"pregit:clone": "rm -rf $npm_package_config_dir",
"git:clone": "git clone $npm_package_config_url $npm_package_config_dir",
"postgit:clone": "dir=$npm_package_config_dir && if [ -n \"$npm_package_config_branch\" ]; then exists=`git --git-dir $dir/.git --work-tree=$dir show-ref refs/heads/${npm_package_config_branch}`; if [ -n \"$exists\" ]; then branch=$npm_package_config_branch; else npm run h --launchpack:h=\"branch doesn't exist. switching to 'master'\"; fi; fi && git --git-dir $dir/.git --work-tree=$dir checkout -f ${branch:=master} && git --git-dir $dir/.git --work-tree $dir reset --hard && rm -rf $dir/.git",
"*":[ "<-- GIT -->" ],
"*":[ "<-- ZIP: download and decompress -->" ],
"zip:fetch": "dir=.launchpack/${npm_package_config_name}; file=${dir}.zip; if [ ! -f $file ]; then curl -kLo $file $npm_package_config_url && unzip -qd $dir $file; fi",
"*":[ "<-- ZIP -->" ],
"*":["<-- INSTALL: shortcut into launch -->"],
"install": "npm run install:msg -s",
"install:msg": "rm -rf node_modules; npm run h --launchpack:h='Try using \"\\033[4mnpm run '${npm_package_name}'\\033[0m\\033[1;103;30m\" next time!'; npm run launchpack -s",
"*":["<-- INSTALL -->"],
"*":["<-- LAUNCH: kick-off a project -->"],
"launchpack": "npm run package:installer -s",
"*":["<-- LAUNCH -->"]
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment