├── .gitignore ├── .gitattributes ├── generators ├── app │ ├── templates │ │ ├── gdt │ │ │ ├── src │ │ │ │ ├── static │ │ │ │ │ └── .gitkeep │ │ │ │ ├── themes │ │ │ │ │ └── .gitkeep │ │ │ │ ├── libraries │ │ │ │ │ └── .gitkeep │ │ │ │ ├── modules │ │ │ │ │ └── .gitkeep │ │ │ │ ├── profiles │ │ │ │ │ └── .gitkeep │ │ │ │ └── sites │ │ │ │ │ └── default │ │ │ │ │ └── .gitkeep │ │ │ ├── Gruntfile.js │ │ │ ├── composer.json │ │ │ ├── package.json │ │ │ ├── .eslintignore │ │ │ ├── Gruntconfig.json │ │ │ ├── test │ │ │ │ └── behat.yml │ │ │ ├── .eslintrc │ │ │ └── phpmd.xml │ │ ├── drupal │ │ │ ├── make-smtp.ejs │ │ │ ├── openatrium │ │ │ │ ├── 7.x │ │ │ │ │ └── bin │ │ │ │ │ │ ├── get-atrium-dev.sh │ │ │ │ │ │ └── grunt │ │ │ │ │ │ └── atrium.js │ │ │ │ ├── project-specific.make.yml │ │ │ │ ├── project-main.make.yml │ │ │ │ └── project-dev.make.yml │ │ │ ├── drupal │ │ │ │ ├── project.make.yml │ │ │ │ ├── 8.x │ │ │ │ │ ├── Gruntconfig.json │ │ │ │ │ ├── test │ │ │ │ │ │ └── features │ │ │ │ │ │ │ └── example.feature │ │ │ │ │ └── composer.json │ │ │ │ └── 7.x │ │ │ │ │ └── test │ │ │ │ │ └── features │ │ │ │ │ ├── bootstrap │ │ │ │ │ └── FeatureContext.php │ │ │ │ │ └── example.feature │ │ │ ├── project-distro.make.yml │ │ │ ├── make-cache.ejs │ │ │ └── octane │ │ │ │ └── 8.x │ │ │ │ └── Gruntconfig.json │ │ ├── project │ │ │ ├── editorconfig │ │ │ └── gitignore │ │ └── README.md │ └── index.js └── lib │ ├── distros │ ├── index.js │ ├── drupal.js │ ├── openatrium.js │ └── octane.js │ ├── util.js │ ├── prompts.js │ └── drupalProjectVersion.js ├── .yo-rc.json ├── .travis.yml ├── .editorconfig ├── .jshintrc ├── docker-compose.yml ├── package.json ├── test ├── generator.int.atrium.test.js ├── distro.unit.test.js ├── generator.int.octane.test.js ├── generator.int.test.js └── drupal-org-api.test.js ├── LICENSE-MIT ├── CHANGELOG.md ├── README.md └── npm-shrinkwrap.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /generators/app/templates/gdt/src/static/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /generators/app/templates/gdt/src/themes/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.yo-rc.json: -------------------------------------------------------------------------------- 1 | { 2 | "generator-generator": {} 3 | } -------------------------------------------------------------------------------- /generators/app/templates/gdt/src/libraries/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /generators/app/templates/gdt/src/modules/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /generators/app/templates/gdt/src/profiles/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /generators/app/templates/gdt/src/sites/default/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /generators/app/templates/drupal/make-smtp.ejs: -------------------------------------------------------------------------------- 1 | # Provides SMTP mail transport support. 2 | <%= smtp %>: 3 | version: "<%= smtpVersion %>" 4 | -------------------------------------------------------------------------------- /generators/lib/distros/index.js: -------------------------------------------------------------------------------- 1 | var requireDirectory = require('require-directory'); 2 | module.exports = requireDirectory(module, {recurse: false}); 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: 4 | - '7' 5 | - '6' 6 | - '5' 7 | - '4' 8 | install: 9 | - npm install -g grunt-cli mocha 10 | - ls -lRa 11 | script: 12 | - npm install 13 | - npm test 14 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /generators/app/templates/project/editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /generators/app/templates/drupal/openatrium/7.x/bin/get-atrium-dev.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | ## 3 | # Get Atrium Dev! 4 | # 5 | # Retrieve or update a local snapshot of Atrium to the latest development copy. 6 | ## 7 | 8 | cd $1 9 | rm -Rf openatrium 10 | git clone --branch 7.x-2.x http://git.drupal.org/project/openatrium.git 11 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node": true, 3 | "esnext": true, 4 | "bitwise": true, 5 | "camelcase": true, 6 | "curly": true, 7 | "eqeqeq": true, 8 | "immed": true, 9 | "indent": 2, 10 | "latedef": true, 11 | "newcap": true, 12 | "noarg": true, 13 | "quotmark": "single", 14 | "undef": true, 15 | "unused": true, 16 | "strict": true 17 | } 18 | -------------------------------------------------------------------------------- /generators/app/templates/gdt/Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | 3 | // Load all plugins and tasks defined by the grunt-drupal-tasks package. 4 | require('grunt-drupal-tasks')(grunt); 5 | 6 | // If bin/grunt exists, load task files. 7 | if (grunt.file.exists(__dirname + '/bin/grunt')) { 8 | grunt.loadTasks(__dirname + '/bin/grunt'); 9 | } 10 | 11 | }; 12 | -------------------------------------------------------------------------------- /generators/app/templates/project/gitignore: -------------------------------------------------------------------------------- 1 | # Files produced by bad patch & diff runs 2 | *~*~ 3 | *.rej 4 | *.diff 5 | *.orig 6 | interdiff*.txt 7 | 8 | # Local caches. 9 | .sass-cache 10 | 11 | # IDE artifacts 12 | *~ 13 | \#*\# 14 | *.swp 15 | .DS* 16 | .project 17 | .idea 18 | 19 | # Upstream dependencies. 20 | vendor 21 | node_modules 22 | .bundle 23 | 24 | # Build output 25 | /build 26 | 27 | # Site Content 28 | /src/sites/*/files 29 | -------------------------------------------------------------------------------- /generators/app/templates/drupal/drupal/project.make.yml: -------------------------------------------------------------------------------- 1 | api: 2 2 | core: <%= coreCompatibility %> 3 | 4 | defaults: 5 | projects: 6 | subdir: contrib 7 | type: module 8 | 9 | projects: 10 | 11 | # Drupal Core 12 | drupal: 13 | version: "<%= drupalDistroRelease %>" 14 | 15 | # Project-specific Dependencies 16 | 17 | <% if (cache) { %><%- include ../make-cache -%><% } %> 18 | <% if (smtp) { %><%- include ../make-smtp -%><% } %> 19 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2.1' 2 | 3 | services: 4 | 5 | cli: 6 | extends: 7 | service: yo 8 | working_dir: /usr/local/lib/node_modules/generator-gadget 9 | entrypoint: ["/usr/bin/env"] 10 | command: "bash" 11 | 12 | yo: 13 | image: outrigger/yeoman 14 | network_mode: "bridge" 15 | volumes: 16 | - ${YO_PROJECT_DIRECTORY:-~/Projects/newproject}:/generated 17 | - .:/usr/local/lib/node_modules/generator-gadget 18 | -------------------------------------------------------------------------------- /generators/app/templates/drupal/openatrium/project-specific.make.yml: -------------------------------------------------------------------------------- 1 | api: 2 2 | core: <%= coreCompatibility %> 3 | 4 | ## 5 | # Project-specific Dependencies. 6 | # 7 | # The projects below are additional to the Atrium-based Drupal system to meet 8 | # site-specific functional, infrastructural, and development requirements. 9 | ## 10 | 11 | defaults: 12 | projects: 13 | subdir: contrib 14 | type: module 15 | 16 | projects: 17 | <% if (cache) { %><%- include ../make-cache -%><% } %> 18 | <% if (smtp) { %><%- include ../make-smtp -%><% } %> 19 | -------------------------------------------------------------------------------- /generators/app/templates/drupal/project-distro.make.yml: -------------------------------------------------------------------------------- 1 | api: 2 2 | core: <%= coreCompatibility %> 3 | 4 | defaults: 5 | projects: 6 | subdir: contrib 7 | type: module 8 | 9 | # Drupal Core 10 | includes: 11 | - drupal-org-core.make 12 | 13 | # Open Atrium 14 | projects: 15 | <%= drupalDistroName %>: 16 | type: profile 17 | version: "<%= drupalDistroRelease %>" 18 | subdir: "" 19 | 20 | # Project-specific Dependencies 21 | 22 | <% if (cache) { %><%- include make-cache -%><% } %> 23 | <% if (smtp) { %><%- include make-smtp -%><% } %> 24 | -------------------------------------------------------------------------------- /generators/app/templates/gdt/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "client/project", 3 | "description": "{Project} drupal codebase for {client}.", 4 | "require-dev": { 5 | "behat/mink-zombie-driver": "~1.2", 6 | "drupal/drupal-extension": "~3.0", 7 | "drupal/coder": "^8.2", 8 | "drush/drush": "8.x", 9 | "phpmd/phpmd": "~2.1" 10 | }, 11 | "require": { 12 | "roave/security-advisories": "dev-master" 13 | }, 14 | "config": { 15 | "preferred-install": "dist", 16 | "sort-packages": true 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /generators/app/templates/gdt/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "grunt-drupal-tasks-example", 3 | "description": "Example package.json for a Drupal project built with grunt-drupal-tasks.", 4 | "version": "0.1.0", 5 | "engines": { 6 | "node": ">=0.12.0", 7 | "npm": "2.x" 8 | }, 9 | "private": true, 10 | "scripts": { 11 | "start": "grunt --timer", 12 | "stop": "grunt clean:default", 13 | "test": "grunt validate && grunt test" 14 | }, 15 | "dependencies": { 16 | "grunt": "^1.0.0", 17 | "grunt-drupal-tasks": "^1.0", 18 | "zombie": "^2.5.1" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /generators/app/templates/gdt/.eslintignore: -------------------------------------------------------------------------------- 1 | ## 2 | # This file instructs eslint to skip certain directories in it's analysis. 3 | # 4 | # It is not needed by grunt-drupal-tasks but is intended to make direct use 5 | # of eslint more effective. 6 | # 7 | # @see http://eslint.org/docs/user-guide/configuring.html 8 | ## 9 | 10 | # node_modules ignored by default 11 | 12 | # Ignore composer and bundler managed dependencies 13 | vendor/**/* 14 | 15 | # Ignore generated files and upstream dependencies via Drush Make 16 | build/**/* 17 | 18 | # Ignore JS in the Drupal files directory such as aggregations. 19 | src/sites/**/files/**/*.js 20 | -------------------------------------------------------------------------------- /generators/app/templates/drupal/openatrium/project-main.make.yml: -------------------------------------------------------------------------------- 1 | api: 2 2 | core: <%= coreCompatibility %> 3 | 4 | ## 5 | # Build the entire Drupal codebase from an official Atrium release. 6 | ## 7 | 8 | defaults: 9 | projects: 10 | subdir: contrib 11 | type: module 12 | 13 | includes: 14 | ## Drupal Core 15 | - drupal-org-core.make 16 | 17 | ## Project-specific Dependencies 18 | - <%= projectName %>.make.yml 19 | 20 | projects: 21 | # Base Distribution - [Open Atrium](https://www.drupal.org/project/openatrium) 22 | openatrium: 23 | type: profile 24 | version: "<%= drupalDistroRelease %>" 25 | subdir: '' 26 | -------------------------------------------------------------------------------- /generators/app/templates/drupal/make-cache.ejs: -------------------------------------------------------------------------------- 1 | # Provides cache drivers for <%= cache %>. Module installation not required. 2 | <%= cache %>: 3 | version: "<%= cacheVersion %>" 4 | 5 | <% if (cache == 'redis') { -%> 6 | 7 | ## 8 | # Predis 9 | # - https://github.com/nrk/predis is a userland Redis client for PHP 10 | # - PhpRedis (https://github.com/phpredis/phpredis) is a PHP extension with 11 | # slightly higher performance and should be used if possible. 12 | ## 13 | libraries: 14 | predis: 15 | download: 16 | type: "get" 17 | url: "https://github.com/nrk/predis/archive/v1.0.3.zip" 18 | directory_name: "predis" 19 | type: "library" 20 | <% } -%> 21 | -------------------------------------------------------------------------------- /generators/app/templates/gdt/Gruntconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "srcPaths": { 3 | "make": "src/project.make.yml", 4 | "drupal": "src" 5 | }, 6 | "domain": "project.vm", 7 | "packages": { 8 | "srcFiles": ["!sites/*/files/**", "!xmlrpc.php", "!modules/php/*"], 9 | "projFiles": ["README*", "bin/**"] 10 | }, 11 | "phpcs": { 12 | "path": "vendor/bin/phpcs" 13 | }, 14 | "phpmd": { 15 | "path": "vendor/bin/phpmd" 16 | }, 17 | "drush": { 18 | "cmd": "vendor/bin/drush" 19 | }, 20 | "behat": { 21 | "flags": "--tags ~@wip" 22 | }, 23 | "eslint": true, 24 | "scripts": { 25 | "update": "<%= config.drush.cmd %> <%= config.alias %> updatedb -yv" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /generators/app/templates/gdt/test/behat.yml: -------------------------------------------------------------------------------- 1 | default: 2 | suites: 3 | default: 4 | contexts: 5 | - FeatureContext 6 | - Drupal\DrupalExtension\Context\DrupalContext 7 | - Drupal\DrupalExtension\Context\MinkContext 8 | extensions: 9 | Behat\MinkExtension: 10 | goutte: ~ 11 | selenium2: ~ 12 | zombie: ~ 13 | javascript_session: 'zombie' 14 | Drupal\DrupalExtension: 15 | blackbox: ~ 16 | drush: 17 | alias: '<%= projectName %>' 18 | drupal: 19 | drupal_root: './build/html' 20 | api_driver: 'drupal' 21 | 22 | ci: 23 | formatter: 24 | name: junit 25 | parameters: 26 | output_path: behat_junit 27 | -------------------------------------------------------------------------------- /generators/app/templates/gdt/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true 4 | }, 5 | "globals": { 6 | "Drupal": true, 7 | "jQuery": true, 8 | "tinyMCE": true 9 | }, 10 | "rules": { 11 | "eqeqeq": [2, "smart"], 12 | "guard-for-in": 2, 13 | "no-undef": 2, 14 | //"no-unused-vars": [2, {"vars": "local", "args": "none"}], 15 | "no-unused-vars": 0, 16 | "strict": 0, 17 | "new-cap": 0, 18 | "quotes": 0, 19 | "camelcase": 0, 20 | "no-underscore-dangle": 0, 21 | "no-new": 0, 22 | "no-alert": 0, 23 | "no-use-before-define": 0, 24 | "consistent-return": 0, 25 | "no-constant-condition": 0, 26 | "comma-dangle" : 2, 27 | "no-catch-shadow" : 2 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /generators/app/templates/drupal/drupal/8.x/Gruntconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "srcPaths": { 3 | "drupal": "src" 4 | }, 5 | "domain": "project.vm", 6 | "packages": { 7 | "srcFiles": ["!sites/*/files/**", "!xmlrpc.php", "!modules/php/*"], 8 | "projFiles": ["README*", "bin/**", "hooks/**", "src/*.make", "vendor/**", "composer.*"], 9 | "dest": { 10 | "docroot": "build/html", 11 | "devResources": "" 12 | } 13 | }, 14 | "phpcs": { 15 | "path": "vendor/bin/phpcs" 16 | }, 17 | "phpmd": { 18 | "path": "vendor/bin/phpmd" 19 | }, 20 | "drush": { 21 | "cmd": "vendor/bin/drush" 22 | }, 23 | "behat": { 24 | "flags": "--tags ~@wip" 25 | }, 26 | "eslint": true, 27 | "scripts": { 28 | "update": "<%= config.drush.cmd %> <%= config.alias %> updatedb -yv" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /generators/app/templates/drupal/octane/8.x/Gruntconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "srcPaths": { 3 | "drupal": "src" 4 | }, 5 | "domain": "project.vm", 6 | "packages": { 7 | "srcFiles": ["!sites/*/files/**", "!xmlrpc.php", "!modules/php/*"], 8 | "projFiles": ["README*", "bin/**", "hooks/**", "src/*.make", "vendor/**", "composer.*"], 9 | "dest": { 10 | "docroot": "build/html", 11 | "devResources": "" 12 | } 13 | }, 14 | "phpcs": { 15 | "path": "vendor/bin/phpcs" 16 | }, 17 | "phpmd": { 18 | "path": "vendor/bin/phpmd" 19 | }, 20 | "drush": { 21 | "cmd": "vendor/bin/drush" 22 | }, 23 | "behat": { 24 | "flags": "--tags ~@wip" 25 | }, 26 | "eslint": true, 27 | "scripts": { 28 | "update": "<%= config.drush.cmd %> <%= config.alias %> features-revert-all -yv" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /generators/app/templates/gdt/phpmd.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | Ruleset for PHPMD analysis of Drupal projects. Excludes coding issues 10 | handled better by PHPCS and rules which have too many false positives 11 | in a typical Drupal codebase. 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /generators/app/templates/drupal/drupal/7.x/test/features/bootstrap/FeatureContext.php: -------------------------------------------------------------------------------- 1 | =0.12.0" 13 | }, 14 | "scripts": { 15 | "test": "mocha --timeout=7500" 16 | }, 17 | "files": [ 18 | "generators" 19 | ], 20 | "keywords": [ 21 | "build", 22 | "drupal", 23 | "grunt", 24 | "yeoman-generator" 25 | ], 26 | "dependencies": { 27 | "chalk": "^1.1.3", 28 | "lodash": "^4.17.4", 29 | "merge": "^1.2.0", 30 | "request": "^2.79.0", 31 | "require-directory": "^2.1.1", 32 | "xml2js": "^0.4.17", 33 | "yeoman-generator": "^1.1.1", 34 | "yosay": "^2.0.0" 35 | }, 36 | "devDependencies": { 37 | "longjohn": "^0.2.12", 38 | "mocha": "^4.0.0", 39 | "yeoman-assert": "^3.0.0", 40 | "yeoman-test": "^1.6.0" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /test/generator.int.atrium.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var assert = require('yeoman-assert'); 4 | var os = require('os'); 5 | var path = require('path'); 6 | var test = require('yeoman-test'); 7 | 8 | describe('gadget:app for Atrium', function() { 9 | 10 | before(function (done) { 11 | var testDir = path.join(os.tmpdir(), './temp-test-atrium'); 12 | console.log(testDir); 13 | test.run(path.join(__dirname, '../generators/app')) 14 | .inDir(testDir) 15 | .withOptions({ 16 | 'skip-install': true, 17 | projectName: 'oa', 18 | projectDescription: 'test atrium project', 19 | drupalDistro: 'openatrium', 20 | drupalDistroVersion: '7.x' 21 | }) 22 | .on('end', done); 23 | }); 24 | 25 | it('creates files', function() { 26 | assert.file([ 27 | 'README.md', 28 | // Distribution-specific makefile. 29 | 'src/project.make.yml', 30 | // gtd scaffolding dotfiles are copying. 31 | 'src/modules/.gitkeep', 32 | // General-purpose behat.yml is not overridden. 33 | 'test/behat.yml', 34 | ]); 35 | }); 36 | }); 37 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Phase2 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /generators/lib/util.js: -------------------------------------------------------------------------------- 1 | var _ = require('lodash'); 2 | var spawn = require('yeoman-generator/lib/actions/spawn-command'); 3 | 4 | module.exports.labelMaker = function(str) { 5 | return _.words(str).map(function(word) { 6 | return _.capitalize(word); 7 | }).join(' '); 8 | }; 9 | 10 | module.exports.tokens = function(options) { 11 | return { 12 | title: module.exports.labelMaker(options.projectName), 13 | description: options.projectDescription, 14 | distroDescription: options.drupalDistro.description 15 | }; 16 | }; 17 | 18 | module.exports.npmVersion = function(name, relativeRepoUrl, useMaster) { 19 | if (useMaster) { 20 | return 'git+https:' + relativeRepoUrl + '#master'; 21 | } 22 | else { 23 | var version = spawn.spawnCommandSync( 24 | 'npm', 25 | ['show', name, 'version'], 26 | {stdio: 'pipe'} 27 | ).stdout.toString('utf8'); 28 | return '~' + _.trim(version); 29 | } 30 | } 31 | 32 | module.exports.fsExistsSync = function(path) { 33 | var fs = require('fs'); 34 | 35 | if (fs.existsSync) { 36 | return fs.existsSync(path); 37 | } 38 | else { 39 | try { 40 | fs.accessSync(path); 41 | return true; 42 | } 43 | catch(ex) { 44 | return false; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /generators/app/templates/drupal/openatrium/project-dev.make.yml: -------------------------------------------------------------------------------- 1 | api: 2 2 | core: <%= coreCompatibility %> 3 | 4 | ## 5 | # Build the entire Atmos Drupal codebase in "development mode". 6 | # 7 | # This uses the latest developments of the main Atrium distribution including 8 | # the latest versions of all core Atrium modules checked out as Git repositories. 9 | ## 10 | 11 | defaults: 12 | projects: 13 | subdir: contrib 14 | type: module 15 | 16 | ## Drupal Core 17 | 18 | # Drupal core makefile might be customized per project. When using the dev snapshot 19 | # it is critical to check routinely for changes to the core makefile in case it 20 | # needs update. This is not done automatically. 21 | 22 | includes: 23 | - drupal-org-core.make 24 | 25 | ## Open Atrium 26 | 27 | # Unlike the stable release, the Atrium installation profile's development 28 | # snapshot is downloaded via a custom build process that pulls down Atrium 29 | # before Drush Make begins, then moved Atrium into place after it concludes. 30 | # 31 | # The copy of Atrium so retrieved is cached in build/cache and it's development 32 | # makefile is leveraged to build out contrib dependencies via the modified grunt 33 | # drushmake process. 34 | 35 | ## Project-specific Dependencies 36 | 37 | includes: <%= projectName %>.make.yml 38 | -------------------------------------------------------------------------------- /generators/app/templates/README.md: -------------------------------------------------------------------------------- 1 | # <%= title %> 2 | 3 | > <%= description %> 4 | 5 | 6 | 7 | <%= distroDescription %> 8 | 9 | ## Requirements 10 | 11 | * [Node.js](https://nodejs.com) v4.3.x via a [package manager](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager) or [standalone installer](http://nodejs.org/download/) 12 | * [Grunt](https://gruntjs.org) (`npm install -g grunt-cli`) 13 | * PHP 5.4 14 | * [Composer](https://getcomposer.org/download) (e.g. `brew install composer`) 15 | 16 | ## About This Repository 17 | 18 | This codebase is maintained in a minimal working repository containing custom code 19 | and manifests of upstream dependencies. [Grunt-Drupal-Tasks](https://github.com/phase2/grunt-drupal-tasks) 20 | (a Node.js tool based on the popular Grunt task-runner) is used for development 21 | and operational management of the application code. A build process downloads and assembles all dependencies for deployment into the webserver. 22 | 23 | ## Installation 24 | 25 | * **`npm install`:** Retrieve build system dependencies. 26 | * **`grunt`:** Validate and assemble functional Drupal codebase. 27 | 28 | ## Get Oriented 29 | 30 | * To learn about available commands run `grunt help`. 31 | -------------------------------------------------------------------------------- /generators/app/templates/drupal/drupal/7.x/test/features/example.feature: -------------------------------------------------------------------------------- 1 | 2 | Feature: Behat tests for a clean install of the Drupal 7 standard profile. These 3 | tests are meant both to verify the Drupal install as well as Behat test features 4 | (like API access and JavaScript handling). 5 | 6 | Scenario: Ensure the Login link is available for anonymous users. 7 | Given I am an anonymous user 8 | When I am on the homepage 9 | Then I should see an "input#edit-name" element 10 | And I should see an "input#edit-pass" element 11 | 12 | @api 13 | Scenario: Ensure as a logged in user, I can log out. 14 | Given I am logged in as a user with the "authenticated user" role 15 | When I click "Log out" 16 | Then I should be on the homepage 17 | And I should see "User login" 18 | 19 | @api @javascript 20 | Scenario: Ensure the Reports page is loaded into an overlay when the Reports 21 | menu item is clicked. 22 | Given I am logged in as a user with the "administrator" role 23 | When I am on the homepage 24 | And I click "Reports" 25 | Then I should be on "#overlay=admin/reports" 26 | 27 | @wip 28 | Scenario: This is a broken test scenario, which should be excluded with the 29 | example Gruntconfig.json due to the wip tag. 30 | Given I am logged in as a user with the "xyz" role 31 | When I am on the xyz page 32 | And I click "Xyz" 33 | Then I should be on "abc" 34 | -------------------------------------------------------------------------------- /test/distro.unit.test.js: -------------------------------------------------------------------------------- 1 | var _ = require('lodash'); 2 | var assert = require('yeoman-assert'); 3 | var distros = require('../generators/lib/distros'); 4 | 5 | describe('Distribution Plugins', function() { 6 | for(var id in distros) { 7 | // This structure copies the value into the test to ensure the same value 8 | // is not reused for multiple test runs. 9 | testPluginConformance(id, distros[id]); 10 | } 11 | }); 12 | 13 | function testPluginConformance(id, distro) { 14 | describe('have an ' + id + ' implementation', function() { 15 | it('should have a complete definition', function(done) { 16 | assert(distro.id); 17 | assert(distro.option); 18 | assert(distro.option.name); 19 | assert(distro.option.value); 20 | assert(distro.versions); 21 | assert(distro.versions.length > 0); 22 | assert(distro.versionDefault); 23 | assert(distro.releaseVersion); 24 | assert(distro.drushMakeFile); 25 | assert(distro.loadComposer); 26 | done(); 27 | }); 28 | 29 | it('should require the filename and distro ID be identical', function(done) { 30 | assert.equal(distro.id, id); 31 | done(); 32 | }); 33 | 34 | it('should have a versionDefault in the versions list', function(done) { 35 | var versions = _.map(distro.versions, 'value'); 36 | assert(versions.indexOf(distro.versionDefault) !== -1); 37 | done(); 38 | }); 39 | }); 40 | } 41 | -------------------------------------------------------------------------------- /generators/app/templates/drupal/drupal/8.x/test/features/example.feature: -------------------------------------------------------------------------------- 1 | 2 | Feature: Behat tests for a clean install of the Drupal 8 standard profile. These 3 | tests are meant both to verify the Drupal install as well as Behat test features 4 | (like API access and JavaScript handling). 5 | 6 | Scenario: Ensure the Login link is available for anonymous users. 7 | Given I am an anonymous user 8 | When I am on the homepage 9 | And I click "Log in" 10 | Then I should see an "input#edit-name" element 11 | And I should see an "input#edit-pass" element 12 | 13 | @api 14 | Scenario: Ensure as a logged in user, I can log out. 15 | Given I am logged in as a user with the "authenticated user" role 16 | When I click "Log out" 17 | Then I should be on the homepage 18 | And I should see "Log in" 19 | 20 | @api @javascript 21 | Scenario: Ensure the Reports page is loaded into an overlay when the Reports 22 | menu item is clicked. 23 | Given I am logged in as a user with the "administrator" role 24 | And I am on the homepage 25 | And I click "My account" 26 | And I click "Edit" 27 | When I fill in "pass[pass1]" with "123" 28 | Then I should see "Password strength" in the ".form-item-pass-pass1" element 29 | 30 | @wip 31 | Scenario: This is a broken test scenario, which should be excluded with the 32 | example Gruntconfig.json due to the wip tag. 33 | Given I am logged in as a user with the "xyz" role 34 | When I am on the xyz page 35 | And I click "Xyz" 36 | Then I should be on "abc" 37 | -------------------------------------------------------------------------------- /test/generator.int.octane.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var assert = require('yeoman-assert'); 4 | var fs = require('fs'); 5 | var os = require('os'); 6 | var path = require('path'); 7 | var test = require('yeoman-test'); 8 | var _ = require('lodash'); 9 | 10 | describe('gadget:app for Octane', function() { 11 | 12 | before(function (done) { 13 | var testDir = path.join(os.tmpdir(), './temp-test-octane'); 14 | console.log(testDir); 15 | test.run(path.join(__dirname, '../generators/app')) 16 | .inDir(testDir) 17 | .withOptions({ 18 | 'skip-install': true, 19 | projectName: 'octane', 20 | projectDescription: 'test octane project', 21 | drupalDistro: 'octane', 22 | drupalDistroVersion: '8.x' 23 | }) 24 | .on('end', done); 25 | }); 26 | 27 | it('creates files', function() { 28 | assert.file([ 29 | 'README.md', 30 | // Distribution-specific makefile. 31 | 'composer.json', 32 | // gtd scaffolding dotfiles are copying. 33 | 'src/modules/.gitkeep', 34 | // General-purpose behat.yml is not overridden. 35 | 'test/behat.yml', 36 | ]); 37 | }); 38 | 39 | describe('composer.json', function() { 40 | it('has a valid composer.json', function() { 41 | assert.jsonFileContent('composer.json', { 42 | 'name': 'organization/octane', 43 | }); 44 | }); 45 | 46 | it('does not specify a core version', function() { 47 | var json = JSON.parse(fs.readFileSync('composer.json', 'utf8')); 48 | assert.ok(!json.require['drupal/core']); 49 | }); 50 | 51 | it('does include merged dependencies from the Octane composer.json', function() { 52 | var json = JSON.parse(fs.readFileSync('composer.json', 'utf8')); 53 | assert.ok(json.require['acquia/lightning']); 54 | assert.ok(json['require-dev']['se/selenium-server-standalone']); 55 | }); 56 | }); 57 | 58 | }); 59 | -------------------------------------------------------------------------------- /generators/lib/distros/drupal.js: -------------------------------------------------------------------------------- 1 | var gadget = require('../util'); 2 | var drupalOrgApi = require('../drupalProjectVersion'); 3 | 4 | function init() { 5 | var module = { 6 | id: 'drupal', 7 | profile: 'standard' 8 | }; 9 | 10 | module.option = { 11 | name: 'Drupal', 12 | value: module.id 13 | }; 14 | 15 | module.versions = [ 16 | {name: 'Drupal 8', value: '8.x'}, 17 | {name: 'Drupal 7', value: '7.x'} 18 | ]; 19 | 20 | module.versionDefault = '8.x'; 21 | 22 | module.description = 'This project is built directly on Drupal Core, it is not leveraging other distributions. For more information visit the [Drupal Project homepage](http://drupal.org/project/drupal).'; 23 | 24 | module.releaseVersion = function(majorVersion, done, cb) { 25 | drupalOrgApi.latestReleaseStable(module.id, majorVersion, done, cb); 26 | }; 27 | 28 | module.loadComposer = function(yo, options) { 29 | var file = yo.templatePath('drupal/' + module.id + '/' + options.drupalDistroVersion + '/composer.json'); 30 | if (gadget.fsExistsSync(file)) { 31 | return yo.fs.readJSON(file); 32 | } 33 | return yo.fs.readJSON(yo.templatePath('gdt/composer.json')); 34 | } 35 | 36 | module.drushMakeFile = function(yo, options, done) { 37 | var tokens = { 38 | drupalDistroRelease: options.drupalDistroRelease, 39 | coreCompatibility: options.drupalDistroVersion, 40 | cache: false, 41 | smtp: false 42 | }; 43 | 44 | if (options['cacheVersion']) { 45 | tokens.cache = options['cacheInternal']; 46 | tokens.cacheVersion = options['cacheVersion']; 47 | } 48 | 49 | if (options['smtpVersion']) { 50 | tokens.smtp = 'smtp'; 51 | tokens.smtpVersion = options['smtpVersion']; 52 | } 53 | 54 | yo.fs.copyTpl( 55 | yo.templatePath('drupal/drupal/project.make.yml'), 56 | yo.destinationPath('src/project.make.yml'), 57 | tokens 58 | ); 59 | 60 | done(); 61 | }; 62 | 63 | return module; 64 | } 65 | 66 | module.exports = init(); 67 | -------------------------------------------------------------------------------- /generators/app/templates/drupal/drupal/8.x/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "client/project", 3 | "description": "{Project} Drupal codebase for {client}.", 4 | "repositories": [ 5 | { 6 | "type": "composer", 7 | "url": "https://packages.drupal.org/8" 8 | } 9 | ], 10 | "require": { 11 | "composer/installers": "^1.2", 12 | "cweagans/composer-patches": "^1.6", 13 | "drupal-composer/drupal-scaffold": "^2.2", 14 | "drupal/core": "~8.5", 15 | "roave/security-advisories": "dev-master" 16 | }, 17 | "require-dev": { 18 | "behat/mink": "~1.7", 19 | "behat/mink-zombie-driver": "~1.2", 20 | "behat/mink-goutte-driver": "~1.2", 21 | "drupal/drupal-extension": "~3.0", 22 | "drupal/coder": "^8.2.12", 23 | "drupal/console": "^1.0.2", 24 | "drush/drush": "^9", 25 | "jcalderonzumba/gastonjs": "^1.0.2", 26 | "jcalderonzumba/mink-phantomjs-driver": "^0.3.1", 27 | "mikey179/vfsstream": "^1.2", 28 | "phpmd/phpmd": "^2.6", 29 | "phpunit/phpunit": "^4.8.35 || ^6.1", 30 | "phpspec/prophecy": "^1.4", 31 | "symfony/css-selector": "^3.4.0", 32 | "symfony/phpunit-bridge": "^3.4.3", 33 | "symfony/debug": "^3.4.0" 34 | }, 35 | "conflict": { 36 | "drupal/drupal": "*" 37 | }, 38 | "minimum-stability": "dev", 39 | "prefer-stable": true, 40 | "config": { 41 | "preferred-install": "dist", 42 | "sort-packages": true 43 | }, 44 | "scripts": { 45 | "drupal-scaffold": "DrupalComposer\\DrupalScaffold\\Plugin::scaffold" 46 | }, 47 | "extra": { 48 | "installer-paths": { 49 | "build/html/core": ["type:drupal-core"], 50 | "build/html/modules/contrib/{$name}": ["type:drupal-module"], 51 | "build/html/profiles/contrib/{$name}": ["type:drupal-profile"], 52 | "build/html/themes/contrib/{$name}": ["type:drupal-theme"], 53 | "build/drush/contrib/{$name}": ["type:drupal-drush"] 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /generators/lib/prompts.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | /** 3 | * General-purpose questions that a parent-generator may want to leverage. 4 | */ 5 | 6 | var chalk = require('chalk'); 7 | var _ = require('lodash'); 8 | 9 | var distros = require('./distros'); 10 | var labelMaker = require('./util').labelMaker; 11 | 12 | var prompts = [ 13 | { 14 | type: 'input', 15 | name: 'projectName', 16 | message: 'Machine-name of your project?', 17 | // Name of the parent directory. 18 | default: _.last(process.cwd().split('/')), 19 | validate: function (input) { 20 | if (input.search(' ') !== -1) return 'No spaces allowed.'; 21 | if (/[A-Z]/.test(input)) return 'Lower-case characters only.'; 22 | return true; 23 | } 24 | }, 25 | { 26 | type: 'input', 27 | name: 'projectDescription', 28 | message: 'One-line project description?', 29 | validate: function(input) { 30 | if (input.search('"') !== -1) return 'No quotes allowed.'; 31 | return true; 32 | }, 33 | default: function(answers) { 34 | return labelMaker(answers['projectName']) + ' Drupal codebase.'; 35 | } 36 | }, 37 | 38 | { 39 | type: 'list', 40 | name: 'drupalDistro', 41 | message: 'Which ' + chalk.red('Drupal distribution') + ' would you like to use?', 42 | default: 'drupal', 43 | filter: function(answer) { 44 | return distros[answer]; 45 | }, 46 | choices: function(answers) { 47 | var opts = []; 48 | for (var i in distros) { 49 | opts.push(distros[i].option); 50 | } 51 | 52 | return opts; 53 | } 54 | }, 55 | { 56 | type: 'list', 57 | name: 'drupalDistroVersion', 58 | message: function(answers) { 59 | return 'Which version of ' 60 | + chalk.red(answers['drupalDistro'].option.name) 61 | + ' would you like to use?'; 62 | }, 63 | default: function(answers) { 64 | return answers['drupalDistro'].versionDefault; 65 | }, 66 | choices: function(answers) { 67 | return answers['drupalDistro'].versions; 68 | } 69 | } 70 | ]; 71 | 72 | module.exports = prompts; 73 | -------------------------------------------------------------------------------- /generators/app/templates/drupal/openatrium/7.x/bin/grunt/atrium.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | 3 | grunt.loadNpmTasks('grunt-contrib-symlink'); 4 | grunt.loadNpmTasks('grunt-shell'); 5 | 6 | // Make Atrium libraries available from sites/all/libraries. 7 | // Many modules do not properly respect the declaration of the contrib Libraries API. 8 | grunt.config(['symlink', 'oa-libraries'], { 9 | expand: true, 10 | cwd: '<%= config.buildPaths.html %>/profiles/openatrium/libraries', 11 | src: ['*'], 12 | dest: '<%= config.buildPaths.html %>/sites/all/libraries' 13 | }); 14 | 15 | // Retrieve a development snapshot of Atrium. 16 | if (grunt.option('dev')) { 17 | grunt.config(['shell', 'get-atrium-dev'], { 18 | command: 'bash bin/get-atrium-dev.sh <%= config.buildPaths.build %>/temp/profiles' 19 | }); 20 | } 21 | 22 | // Rewire the scaffold task based on tailored Atrium commands. 23 | grunt.task.renameTask('scaffold', 'scaffold-pre-atrium'); 24 | grunt.registerTask('scaffold', ['scaffold-pre-atrium', 'symlink:oa-libraries']); 25 | 26 | // Rewire the main build task based on Atrium development builds. 27 | if (grunt.option('dev')) { 28 | var make_args = grunt.config.get('drush.make.args'); 29 | make_args.push('--working-copy'); 30 | make_args.push('--no-gitinfofile'); 31 | make_args.push('--no-cache'); 32 | 33 | // grunt-drupal-tasks does not provide a clean facilitate to override the 34 | // Gruntconfig makefile. 35 | make_args[1] = 'src/project-dev.make.yml'; 36 | grunt.config.set('drush.make.args', make_args); 37 | 38 | // Define the make-atrium job by duplicating the standard make configuration. 39 | grunt.config.set('drush.make-atrium', grunt.config('drush.make')); 40 | var make_args = grunt.config.get('drush.make-atrium.args'); 41 | make_args[1] = '<%= config.buildPaths.build %>/temp/profiles/openatrium/scripts/oa-drush-dev.make'; 42 | make_args.push('--no-core'); 43 | make_args.push('--contrib-destination=profiles/openatrium'); 44 | grunt.config.set('drush.make-atrium.args', make_args); 45 | 46 | grunt.registerTask('drushmake', 'Prepare the build directory and run "drush make"', function() { 47 | grunt.task.run([ 48 | 'mkdir:init', 49 | 'clean:temp', 50 | 'drush:make', 51 | // Retrieve Atrium 2.x and place in transitional codebase. 52 | 'shell:get-atrium-dev', 53 | // Ensure Atrium's dependencies are placed in the openatrium profile directory tree. 54 | 'drush:make-atrium', 55 | 'clean:default', 56 | require('grunt-drupal-tasks/lib/util').canRsync() ? 'rsync:tempbuild' : 'copy:tempbuild', 57 | 'clean:temp' 58 | ]); 59 | }); 60 | 61 | } 62 | }; 63 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG 2 | 3 | ## v1.2.0 [2017/10/05] 4 | 5 | * Improved context for HTTP errors when requesting remote project metadata. 6 | * Default configuration of grunt update now swiched from drush features-revert-all to drush updatedb. 7 | * Project/Machine Name now required to be entered as lower-case. 8 | * Drupal 8 composer install defaults `preferred-install: 'dist'` 9 | * Drupal 7 composer install defaults `preferred-install: 'dist'` and `sorted-packages: true` 10 | 11 | ### Technical Plumbing 12 | 13 | * Upgrade mocha to v4 14 | 15 | ## v1.1.0 [2017/06/02] 16 | 17 | * Update Drupal 8 composer.json to drupal-project versions. 18 | * Add a default value to the project description prompt. 19 | * Change the composer.json project name to include 'organization/' prefix for strict format compliance. 20 | 21 | ### Technical Plumbing 22 | 23 | * Added Greenkeeper to help manage dependency updates. 24 | * Updated to yeoman-generator 1.x with various related refactorings. 25 | * Add Docker integration for development. 26 | * Add Longjohn as a dev dependency to fix asynchronous debugging, such as learning anything about templating errors. 27 | * Overhauled Drupal Update Feed integration, it is now almost a full-fledged API client. 28 | * Light reorganization to reduce race conditions. 29 | 30 | ## v1.0.0 [2017/02/18] 31 | 32 | * Generated composer.json updates 33 | * Drupal Console from v0.11 to v1.0.0-rc16 34 | * Remove duplicate phpunit entry 35 | 36 | ## v1.0.0-rc1 [2017/01/12] 37 | 38 | * Drupal 8 projects now use Composer as their sole dependency manager. Drush Make is only used for Drupal 7/Atrium projects. 39 | * Add a project distribution option for [Octane](https://github.com/phase2/octane). 40 | * Added the merge library as a generator dependency so Octane projects receive a composer.json which combines the gadget template with the current Octane stable release manifest. 41 | * Update Drupal 8 dev dependencies to match Drupal Core. (Note that they are not computed dynamically at generator-time, unlike the distribution version.) 42 | * Drop support for Node v0.12. Begin support for Node 6 and Node 7. 43 | * Adjust default behat.yml configuration to work more cleanly out-of-box for CI. 44 | * Fixed switch deprecated eslint no-comment-dangle configuration option to comment-dangle. 45 | 46 | ## v0.5.0 [2016/07/01] 47 | 48 | - Added hidden support for SMTP module added to makefile. 49 | - Offline mode via `--offline` 50 | - Drupal 8 composer.json updates: Drush 8.x, Coder 8.2.x especially. 51 | - Switch to make.yml format for Drush Makefiles 52 | - Stability improvements 53 | 54 | ## v0.4.0 [2016/03/02] 55 | 56 | - Added support for cache options (including database, Memcache, Redis). 57 | - Added support for distributions with multiple make files (especially Atrium). 58 | - Added README.md for generated projects. 59 | - Dropped support for Node.js v0.10. Node.js v0.12.x or later is required. 60 | - Improved Travis CI tests with runs with Node.js 5.x, 4.x, and 0.12.x. 61 | - Improved documentation. 62 | -------------------------------------------------------------------------------- /generators/lib/distros/openatrium.js: -------------------------------------------------------------------------------- 1 | var request = require('request'); 2 | var gadget = require('../util'); 3 | var drupalOrgApi = require('../drupalProjectVersion'); 4 | 5 | function init() { 6 | var module = { 7 | id: 'openatrium', 8 | profile: 'openatrium' 9 | }; 10 | 11 | module.option = { 12 | name: 'Open Atrium', 13 | value: module.id 14 | }; 15 | 16 | module.versions = [ 17 | {name: 'OpenAtrium 2', value: '7.x'}, 18 | ]; 19 | 20 | module.versionDefault = '7.x'; 21 | 22 | module.description = 'This project is built on [' + module.option.name + '](http://openatrium.com) for more information visit the [Atrium Project Homepage](https://drupal.org/project/openatrium).'; 23 | 24 | module.releaseVersion = function(majorVersion, done, cb) { 25 | drupalOrgApi.latestReleaseStable(module.id, majorVersion, done, cb); 26 | }; 27 | 28 | module.loadComposer = function(yo, options) { 29 | var file = yo.templatePath('drupal/' + module.id + '/' + options.drupalDistroVersion + '/composer.json'); 30 | if (gadget.fsExistsSync(file)) { 31 | return yo.fs.readJSON(file); 32 | } 33 | return yo.fs.readJSON(yo.templatePath('gdt/composer.json')); 34 | } 35 | 36 | module.drushMakeFile = function(yo, options, done) { 37 | var v = options.drupalDistroRelease; 38 | var releaseVersion = v.slice(v.indexOf('-') + 1); 39 | 40 | var tokens = { 41 | drupalDistroName: module.id, 42 | drupalDistroRelease: releaseVersion, 43 | coreCompatibility: options.drupalDistroVersion, 44 | projectName: options.projectName, 45 | cache: false, 46 | smtp: false 47 | }; 48 | 49 | if (options['cacheVersion']) { 50 | tokens.cache = options['cacheInternal']; 51 | tokens.cacheVersion = options['cacheVersion']; 52 | } 53 | 54 | if (options['smtpVersion']) { 55 | tokens.smtp = 'smtp'; 56 | tokens.smtpVersion = options['smtpVersion']; 57 | } 58 | 59 | yo.fs.copyTpl( 60 | yo.templatePath('drupal/' + options.drupalDistro.id + '/project-main.make.yml'), 61 | yo.destinationPath('src/project.make.yml'), 62 | tokens 63 | ); 64 | 65 | yo.fs.copyTpl( 66 | yo.templatePath('drupal/' + options.drupalDistro.id + '/project-dev.make.yml'), 67 | yo.destinationPath('src/project-dev.make.yml'), 68 | tokens 69 | ); 70 | 71 | yo.fs.copyTpl( 72 | yo.templatePath('drupal/' + options.drupalDistro.id + '/project-specific.make.yml'), 73 | yo.destinationPath('src/' + options.projectName + '.make.yml'), 74 | tokens 75 | ); 76 | 77 | // The Core Makefile is managed by Atrium and varies by release. 78 | var url = 'http://cgit.drupalcode.org/' + options.drupalDistro.id 79 | + '/plain/drupal-org-core.make?id=' + options.drupalDistroRelease; 80 | request(url, 81 | function (error, response, body) { 82 | if (!error && response.statusCode == 200 && body.length) { 83 | yo.fs.write(yo.destinationPath('src/drupal-org-core.make'), body); 84 | } 85 | done(); 86 | } 87 | ) 88 | }; 89 | 90 | return module; 91 | } 92 | 93 | module.exports = init(); 94 | -------------------------------------------------------------------------------- /test/generator.int.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var assert = require('yeoman-assert'); 4 | var fs = require('fs'); 5 | var os = require('os'); 6 | var path = require('path'); 7 | var test = require('yeoman-test'); 8 | var _ = require('lodash'); 9 | 10 | describe('gadget:app for Drupal 8', function () { 11 | describe('online', function () { 12 | before(function (done) { 13 | var testDir = path.join(os.tmpdir(), './temp-test-standard'); 14 | console.log(testDir); 15 | test.run(path.join(__dirname, '../generators/app')) 16 | .inDir(testDir) 17 | .withOptions({ 18 | 'skip-install': true, 19 | projectName: 'drupal8', 20 | projectDescription: 'test drupal8 project', 21 | drupalDistro: 'drupal', 22 | drupalDistroVersion: '8.x', 23 | }) 24 | .on('end', done); 25 | }); 26 | 27 | it('creates files', function() { 28 | assert.file([ 29 | 'README.md', 30 | 'composer.json', 31 | // gtd scaffolding dotfiles are copying. 32 | 'src/modules/.gitkeep', 33 | // General-purpose behat.yml is not overridden. 34 | 'test/behat.yml', 35 | // Behat example tests are present. 36 | 'test/features/example.feature', 37 | ]); 38 | }); 39 | 40 | describe('composer.json', function() { 41 | it('has a valid composer.json', function() { 42 | assert.jsonFileContent('composer.json', { 43 | 'name': 'organization/drupal8', 44 | }); 45 | }); 46 | 47 | it('specifies a real drupal/core version', function() { 48 | var json = JSON.parse(fs.readFileSync('composer.json', 'utf8')); 49 | assert.ok(json.require['drupal/core']); 50 | }); 51 | }); 52 | }); 53 | 54 | describe('offline', function () { 55 | before(function (done) { 56 | var testDir = path.join(os.tmpdir(), './temp-test-standard'); 57 | console.log(testDir); 58 | test.run(path.join(__dirname, '../generators/app')) 59 | .inDir(testDir) 60 | .withOptions({ 61 | 'skip-install': true, 62 | projectName: 'drupal8', 63 | projectDescription: 'test drupal8 project', 64 | drupalDistro: 'drupal', 65 | drupalDistroVersion: '8.x', 66 | offline: true 67 | }) 68 | .on('end', done); 69 | }); 70 | 71 | it('creates files', function() { 72 | assert.file([ 73 | 'README.md', 74 | 'composer.json', 75 | // gtd scaffolding dotfiles are copying. 76 | 'src/modules/.gitkeep', 77 | // General-purpose behat.yml is not overridden. 78 | 'test/behat.yml', 79 | // Behat example tests are present. 80 | 'test/features/example.feature', 81 | ]); 82 | }); 83 | 84 | describe('composer.json', function() { 85 | it('has a valid composer.json', function() { 86 | assert.jsonFileContent('composer.json', { 87 | 'name': 'organization/drupal8', 88 | }); 89 | }); 90 | 91 | it('specifies a real drupal/core version', function() { 92 | var json = JSON.parse(fs.readFileSync('composer.json', 'utf8')); 93 | assert.ok(json.require['drupal/core']); 94 | }); 95 | }); 96 | 97 | }); 98 | 99 | }); 100 | -------------------------------------------------------------------------------- /test/drupal-org-api.test.js: -------------------------------------------------------------------------------- 1 | var _ = require('lodash'); 2 | var assert = require('yeoman-assert'); 3 | var drupal = require('../generators/lib/drupalProjectVersion'); 4 | 5 | describe('Drupal.org API Client', function() { 6 | describe('latestRelease', function() { 7 | it ('should retrieve the latest Drupal 8 core release', function(done) { 8 | drupal.latestRelease('drupal', '8.x', done, function(err, result, done) { 9 | assert.ok(!err && result, 'Retrieved a result for Drupal 8 release.'); 10 | if (err) { 11 | console.error(err); 12 | } 13 | done(); 14 | }); 15 | }) 16 | 17 | it ('should retrieve the latest Drupal 7 core release', function(done) { 18 | drupal.latestRelease('drupal', '7.x', done, function(err, result, done) { 19 | assert.ok(!err && result, 'Retrieved a result for Drupal 7 release.'); 20 | if (err) { 21 | console.error(err); 22 | } 23 | done(); 24 | }); 25 | }); 26 | }); 27 | 28 | describe('latestReleaseStable', function() { 29 | it ('should retrieve the latest Drupal 8 core release', function(done) { 30 | drupal.latestReleaseStable('drupal', '8.x', done, function(err, result, done) { 31 | assert.ok(!err && result, 'Retrieved a result for Drupal 8 release.'); 32 | if (err) { 33 | console.error(err); 34 | } 35 | done(); 36 | }); 37 | }) 38 | 39 | it ('should retrieve the latest Drupal 7 core release', function(done) { 40 | drupal.latestReleaseStable('drupal', '7.x', done, function(err, result, done) { 41 | assert.ok(!err && result, 'Retrieved a result for Drupal 7 release.'); 42 | if (err) { 43 | console.error(err); 44 | } 45 | done(); 46 | }); 47 | }); 48 | }); 49 | 50 | describe('isCached', function() { 51 | it ('should retrieve follow-up requests from the cache.', function() { 52 | assert.ok(drupal.isCached('drupal', '8.x'), 'Previously retrieved drupal 8.x data.'); 53 | }); 54 | }); 55 | 56 | describe('numericCoreVersion', function() { 57 | it ('should convert a version number to the core version digits', function() { 58 | assert.equal(8, drupal.numericCoreVersion('8.2.6'), '8.2.6 returns 8'); 59 | }); 60 | it ('should convert a major version to the core version digits', function() { 61 | assert.equal(8, drupal.numericCoreVersion('8.x'), '8.x returns 8'); 62 | }); 63 | }); 64 | 65 | describe('toMinorRange', function() { 66 | it ('should convert a version number to a minor range', function() { 67 | assert.equal('^8.2', drupal.toMinorRange('8.2.6'), '8.2.6 becomes ^8.2'); 68 | }); 69 | it ('should return Major.X as a viable minor range.', function() { 70 | assert.equal('8.x', drupal.toMinorRange('8.x'), '8.x becomes 8.x'); 71 | }); 72 | }); 73 | 74 | describe('toDrupalMajorVersion', function() { 75 | it ('should leave a properly formatted version alone.', function() { 76 | assert.equal('8.x', drupal.toDrupalMajorVersion('8.x'), 'A major version such as 8.x should be left alone.'); 77 | }); 78 | it ('should convert a semantic version to a Drupal major version.', function() { 79 | assert.equal('8.x', drupal.toDrupalMajorVersion('8.2.6'), '8.2.6 should be converted to 8.x'); 80 | }); 81 | it ('should ignore the presence of a pre-release suffix.', function() { 82 | assert.equal('8.x', drupal.toDrupalMajorVersion('8.3.0-beta2'), '8.3.0-beta2 should be converted to 8.x'); 83 | }); 84 | it ('should convert a semver patch level range to Drupal major version..', function() { 85 | assert.equal('8.x', drupal.toDrupalMajorVersion('8.2.x'), '8.2.x should be converted to 8.x'); 86 | }); 87 | }); 88 | 89 | 90 | }); 91 | -------------------------------------------------------------------------------- /generators/lib/distros/octane.js: -------------------------------------------------------------------------------- 1 | var request = require('request'); 2 | var merge = require('merge'); 3 | var gadget = require('../util'); 4 | 5 | function init() { 6 | var module = { 7 | id: 'octane', 8 | // Generated project will be based on Lightning, not Octane directly. 9 | // Octane only used as template for build files. 10 | profile: 'lightning' 11 | }; 12 | 13 | module.option = { 14 | name: 'Octane/Lightning', 15 | value: module.id 16 | }; 17 | 18 | module.versions = [ 19 | {name: 'Octane 8.x', value: '8.x'} 20 | ]; 21 | 22 | module.versionDefault = '8.x'; 23 | 24 | module.description = 'This project is built on [' + module.option.name + '] distribution.'; 25 | 26 | module.releaseVersion = function(majorVersion, done, cb) { 27 | cb(null, '8.x', done); 28 | }; 29 | 30 | module.drushMakeFile = function(yo, options, done) { 31 | // Using all composer. No Drush make files. 32 | done(); 33 | }; 34 | 35 | module.loadComposer = function(yo, options) { 36 | var composer = {}; 37 | var file = yo.templatePath('drupal/drupal/' + options.drupalDistroRelease + '/composer.json'); 38 | if (gadget.fsExistsSync(file)) { 39 | composer = yo.fs.readJSON(file); 40 | // Octane gets it's version of Drupal Core from Lightning. 41 | // The composer.json template is pulled from the Drupal distro, which does 42 | // use a drupal/core version. To ensure some core processing logic does 43 | // not execute for Octane we remove this entry as the one key difference. 44 | delete composer.require['drupal/core']; 45 | } 46 | return composer; 47 | } 48 | 49 | module.modifyComposer = function(options, localComposer, isNewProject, done, cb) { 50 | // We fetch the current composer.json from Drupal.org for the distro. 51 | // Then we merge the "require", "require-dev", patches" sections with either 52 | // the existing project composer.json, or the Drupal base template. 53 | if (options.offline) { 54 | cb(null, localComposer, done); 55 | } 56 | else { 57 | // Lastest Octane distro code living on drupal.org 58 | var url = 'http://cgit.drupalcode.org/' + module.id 59 | + '/plain/composer.json'; 60 | 61 | request(url, 62 | function (error, response, body) { 63 | if (!error && response.statusCode == 200 && body.length) { 64 | var remoteComposer = JSON.parse(body); 65 | // Read the default Drupal composer.json template. 66 | if (isNewProject) { 67 | // drupal.org composer determines source for drupal modules. 68 | // @todo if the remoteComposer starts having changes to composer 69 | // repositories this will need to be changed to update existing 70 | // composer.json. 71 | localComposer.repositories = remoteComposer.repositories; 72 | } 73 | 74 | // Merge in requirements from drupal.org composer. 75 | localComposer.require = merge.recursive(true, localComposer.require, remoteComposer.require); 76 | localComposer.extra['enable-patching'] = remoteComposer.extra['enable-patching']; 77 | // Merge in patches from drupal.org composer. 78 | localComposer.extra['patches'] = merge.recursive(true, localComposer.extra['patches'], remoteComposer.extra['patches'], true); 79 | // Merge in require-dev from drupal.org composer. 80 | localComposer['require-dev'] = merge.recursive(true, localComposer['require-dev'], remoteComposer['require-dev']); 81 | 82 | cb(null, localComposer, done); 83 | } 84 | else if (error) { 85 | cb(error, null, done); 86 | } 87 | else { 88 | done(); 89 | } 90 | } 91 | ); 92 | } 93 | }; 94 | 95 | return module; 96 | } 97 | 98 | module.exports = init(); 99 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Gadget: A Generator for New Drupal Projects 2 | 3 | > [Yeoman](http://yeoman.io) generator to scaffold a [Drupal](https://www.drupal.org) project for use with [grunt-drupal-tasks](https://github.com/phase2/grunt-drupal-tasks). 4 | 5 | [![Travis CI status](https://travis-ci.org/phase2/generator-gadget.png?branch=master)](https://travis-ci.org/phase2/generator-gadget) 6 | [![npm version](https://badge.fury.io/js/generator-gadget.svg)](https://www.npmjs.com/package/generator-gadget) 7 | [![Dependency Status](https://david-dm.org/phase2/generator-gadget.svg)](https://david-dm.org/phase2/generator-gadget) 8 | [![Greenkeeper badge](https://badges.greenkeeper.io/phase2/generator-gadget.svg)](https://greenkeeper.io/) 9 | 10 | ## Features 11 | 12 | Gadget will set up a Drupal project with the site skeleton and tools to build your project and configure your build 13 | system with the Grunt Drupal Tasks kit. 14 | 15 | * Automatically uses the latest version of Grunt Drupal Tasks. 16 | * Select from Drupal 7, Drupal 8, Atrium 2, or Octane. The latest published release of the selected option will be used. 17 | * For Drupal 8, creates a `composer.json` file that requires the latest stable Drupal, Drupal Console, and Drush. 18 | * For Drupal 7, creates a Drush Makefile so your grunt build process is ready to assemble a working codebase immediately! 19 | * Provides numerous configuration files for Git, IDE's, and other tools for Drupal best practices out-of-the-box. 20 | * The entire Grunt Drupal Tasks features list is ready to go, including Behat Testing, Static Analysis, and Continuous-Integration readiness. 21 | 22 | ## Requirements 23 | 24 | * Install _Node.js v4 or better_ either using a 25 | [package manager](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager) 26 | like apt-get, brew, or yum or a [standalone installer](http://nodejs.org/download/) 27 | 28 | * Once _Node.js_ is installed, use _npm_ to install the generator. If you have 29 | not used a Yeoman generator before install the [`yo`](https://www.npmjs.com/package/yo) package as well. 30 | [Grunt Drupal Tasks](https://github.com/phase2/grunt-drupal-tasks) requires the [grunt task runner](https://www.npmjs.com/package/grunt-cli) as well. 31 | 32 | ``` 33 | npm install -g generator-gadget grunt-cli yo 34 | ``` 35 | 36 | Grunt Drupal Tasks leverages a number of additional tools from outside the Node ecosystem, such as [PHP](http://php.net) and 37 | [Composer](https://getcomposer.org/download/). See Grunt-Drupal-Tasks for details. 38 | 39 | ## Usage 40 | 41 | To set up a new Drupal project with Grunt Drupal Tasks using Gadget, run the following in a new directory: 42 | 43 | ``` 44 | yo gadget 45 | ``` 46 | 47 | ## Options 48 | 49 | * `--offline`: Will make a best effort to complete generator run, though some generated values 50 | may be non-applicable, such as Drupal Core version of "0". 51 | * `--use-master`: Will make a point of leveraging the master version of Grunt Drupal Tasks. 52 | * `--skip-install`: Will skip running `npm install` at the end of the generation process. 53 | * `--skip-readme`: Will not generate a README.md. (Useful when you've already hand-crafted the perfect project introduction!) 54 | * `--skipWelcome`: Skip opening welcome message. 55 | * `--skipGoodbye`: Skip closing messages. 56 | 57 | ## Additional Resources 58 | 59 | * For information on using Grunt Drupal Tasks after installing with Gadget, see the [Grunt Drupal Tasks documentation](https://phase2.github.io/grunt-drupal-tasks). 60 | * Interested in the Frontend? Check out our sibling project, [Generator Patter Lab Starter](https://github.com/phase2/generator-pattern-lab-starter) to get a theme ready to go with options for Pattern Lab, icon fonts, SASS, visual regression testing, and more. 61 | 62 | ## Docker-based Development 63 | 64 | Install the dependencies: 65 | 66 | ``` 67 | docker-compose run --rm cli npm install 68 | ``` 69 | 70 | Then run the generator: 71 | 72 | ``` 73 | docker-compose run --rm yo gadget 74 | ``` 75 | -------------------------------------------------------------------------------- /generators/lib/drupalProjectVersion.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Retrieve Drupal project release data. 5 | * 6 | * @todo extract to a library. 7 | * @todo switch to promises. 8 | */ 9 | 10 | var request = require('request'); 11 | var xml2js = require('xml2js'); 12 | var _ = require('lodash'); 13 | 14 | function init() { 15 | var module = {}; 16 | 17 | /** 18 | * Project Release Data Cache 19 | * 20 | * Cache the data associated with any given major version of a project for the 21 | * extent of a single generator run. We cache it already parsed to an object. 22 | */ 23 | var cache = {}; 24 | 25 | function loadReleaseData(project, majorVersion, done, cb) { 26 | // Just in case we have a semver string instead of the expected Drupal 27 | // update system style major version "8.x", perform a cleanup. 28 | majorVersion = toDrupalMajorVersion(majorVersion); 29 | 30 | var cid = project + majorVersion; 31 | if (cache[cid]) { 32 | return cb(null, cache[cid], done); 33 | } 34 | 35 | var releaseUri = 'https://updates.drupal.org/release-history/'; 36 | request(releaseUri + project + '/' + majorVersion, function(error, response, body) { 37 | if (!error && response.statusCode == 200 && body.length) { 38 | xml2js.parseString(body, function (err, result) { 39 | if (!err && result && result.project) { 40 | cache[cid] = result.project; 41 | return cb(null, result.project, done); 42 | } 43 | else { 44 | return cb('Could not parse latest version of ' + project + '. Received:\n', result, done); 45 | } 46 | }); 47 | } 48 | else { 49 | var msg = 'Could not retrieve latest version of ' + project + ' for Drush makefile.\n'; 50 | if (error.code == 'ETIMEDOUT') { 51 | msg += 'Failure was caused by a network timeout. If testing Gadget, try running with --offline.\n'; 52 | } 53 | return cb(msg, null, done); 54 | } 55 | }); 56 | } 57 | 58 | function latestRelease(project, majorVersion, done, cb) { 59 | loadReleaseData(project, majorVersion, done, function(err, result, done) { 60 | if (!err && result.releases 61 | && result.releases[0] 62 | && result.releases[0].release 63 | && result.releases[0].release[0] 64 | && result.releases[0].release[0].version 65 | ) { 66 | return cb(null, result.releases[0].release[0].version[0], done); 67 | } 68 | else { 69 | err = 'No version data found. This may be a an error in communication with updates.drupal.org.'; 70 | } 71 | if (err) { 72 | return cb(err, null, done); 73 | } 74 | }); 75 | } 76 | 77 | function latestReleaseStable(project, majorVersion, done, cb) { 78 | loadReleaseData(project, majorVersion, done, function(err, result, done) { 79 | if (!err && result.releases 80 | && result.releases[0] 81 | && result.releases[0].release 82 | ) { 83 | var release = _.find(result.releases[0].release, function(release) { 84 | return !release.version_extra; 85 | }) 86 | return cb(null, release.version[0], done); 87 | } 88 | else { 89 | err = 'No version data found. This may be a an error in communication with updates.drupal.org.'; 90 | } 91 | 92 | if (err) { 93 | return cb(err, null, done); 94 | } 95 | }); 96 | } 97 | 98 | // Generate the numeric core version from a more typical Drupal version number. 99 | function numericCoreVersion(version) { 100 | return version.slice(0, version.indexOf('.')); 101 | } 102 | 103 | /** 104 | * Convert a semantic version to a minor range. 105 | * 106 | * In composer.json entries for Drupal core or other major projects, we often 107 | * want to designate the version similar to '^8.2'. This code converts version 108 | * strings that may have a pre-release suffix to such a range. 109 | * 110 | * Furthermore, there are some edge cases wherein we may want to take a version 111 | * that is already a minor range, such as 8.x, and use it as is. 112 | */ 113 | function toMinorRange(version) { 114 | var regex = /^\d+\.\d+/; 115 | var range = version.match(regex); 116 | if (range) { 117 | return '^' + range[0]; 118 | } 119 | else { 120 | var regex = /^\d+\.x/; 121 | var range = version.match(regex); 122 | if (range) { 123 | return range[0]; 124 | } 125 | } 126 | 127 | return version; 128 | } 129 | 130 | /** 131 | * The Drupal update system uses a pre-semver approach of version numbering. 132 | * 133 | * Major versions must be in the form of "8.x", as opposed to other semver 134 | * ranges or version numbers. 135 | */ 136 | function toDrupalMajorVersion(version) { 137 | var regex = /^(\d+)\.\d+\.[x\d+]/; 138 | var match = version.match(regex) 139 | if (match) { 140 | return match[1] + '.x'; 141 | } 142 | 143 | return version; 144 | } 145 | 146 | /** 147 | * Determine if we have successfully cached the release data. 148 | */ 149 | function isCached(project, majorVersion) { 150 | var cid = project+majorVersion; 151 | return cache[cid] && cache[cid].short_name[0] == project && cache[cid].api_version[0] == majorVersion; 152 | } 153 | 154 | module.latestRelease = latestRelease; 155 | module.latestReleaseStable = latestReleaseStable; 156 | module.numericCoreVersion = numericCoreVersion; 157 | module.toMinorRange = toMinorRange; 158 | module.toDrupalMajorVersion = toDrupalMajorVersion; 159 | // This function facilitates testing & troubleshooting. 160 | module.isCached = isCached; 161 | 162 | 163 | return module; 164 | } 165 | 166 | module.exports = init(); 167 | -------------------------------------------------------------------------------- /generators/app/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var Generator = require('yeoman-generator'); 4 | var chalk = require('chalk'); 5 | var yosay = require('yosay'); 6 | var path = require('path'); 7 | var _ = require('lodash'); 8 | 9 | var gadget = require('../lib/util'); 10 | var drupalOrgApi = require('../lib/drupalProjectVersion'); 11 | 12 | var options = {}; 13 | 14 | module.exports = Generator.extend({ 15 | initializing: function () { 16 | this.pkg = require('../../package.json'); 17 | 18 | if (!this.options.skipWelcome) { 19 | this.log(yosay( 20 | 'Welcome to ' + chalk.red.bold('Gadget ' + this.pkg.version) 21 | + ', the gnarly generator for Grunt Drupal Tasks!' 22 | )); 23 | } 24 | }, 25 | 26 | prompting: function () { 27 | var self = this; 28 | 29 | if (this.options.hasOwnProperty('drupalDistro') && typeof self.options.drupalDistro === 'string') { 30 | var distros = require('../lib/distros'); 31 | self.options.drupalDistro = distros[self.options.drupalDistro]; 32 | } 33 | 34 | if (this.options.hasOwnProperty('drupal-distro') && typeof self.options['drupal-distro'] === 'string') { 35 | var distros = require('../lib/distros'); 36 | self.options['drupalDistro'] = distros[self.options['drupal-distro']]; 37 | } 38 | 39 | var prompts = require('../lib/prompts'); 40 | prompts = _.filter(prompts, function (item) { 41 | return _.isUndefined(self.options[item.name]); 42 | }); 43 | 44 | if (!self.options['cacheInternal']) { 45 | self.options.cacheInternal = 'database'; 46 | } 47 | // The generator uses a separate options object, let's make sure it is not 48 | // dependent on prompt processing. 49 | options = self.options; 50 | 51 | return this.prompt(prompts).then(function (props) { 52 | options = _.assign(props, self.options); 53 | this.log("\nOk, I'm going to start assembling this project..."); 54 | }.bind(self)); 55 | }, 56 | 57 | configuring: { 58 | // Determine the latest stable release for the requested Drupal core version. 59 | getDistroRelease: function () { 60 | if (options['offline']) { 61 | options.drupalDistroRelease = '0.0.0'; 62 | } 63 | else { 64 | // Find the latest stable release for the Drupal distro version. 65 | var done = this.async(); 66 | options.drupalDistro.releaseVersion(options.drupalDistroVersion, done, function(err, version, done) { 67 | if (err) { 68 | this.env.error('Could not retrieve distribution project info: ' + err); 69 | return done(err); 70 | } 71 | options.drupalDistroRelease = version; 72 | done(); 73 | }.bind(this)); 74 | } 75 | }, 76 | 77 | cacheVersion: function() { 78 | if (options.cacheInternal != 'database') { 79 | if (options['offline']) { 80 | options.cacheVersion = 0; 81 | } 82 | else { 83 | var done = this.async(); 84 | // the other options for cache are redis and memcache, which happen 85 | // to be the names of the contrib modules that integrate with them. 86 | drupalOrgApi.latestRelease(options.cacheInternal, options.drupalDistroVersion, done, 87 | function(err, version, done) { 88 | if (err) { 89 | this.env.error('Could not retrieve project info for selected cache system: ' + err); 90 | return done(err); 91 | } 92 | options.cacheVersion = version.substr(4); 93 | done(); 94 | }.bind(this) 95 | ); 96 | } 97 | } 98 | }, 99 | 100 | smtpVersion: function() { 101 | if (options.mail == 'mailhog') { 102 | if (options['offline']) { 103 | options.smtpVersion = 0; 104 | } 105 | else { 106 | var done = this.async(); 107 | drupalOrgApi.latestRelease('smtp', options.drupalDistroVersion, done, 108 | function(err, version, done) { 109 | if (err) { 110 | this.env.error('Could not retrieve project info for selected mail system: ' + err); 111 | return done(err); 112 | } 113 | options.smtpVersion = version.substr(4); 114 | 115 | done(); 116 | }.bind(this) 117 | ); 118 | } 119 | } 120 | }, 121 | 122 | gdtBase: function() { 123 | // Load any existing composer.json now before it is overridden by template. 124 | this.composerOrig = this.fs.readJSON('composer.json'); 125 | this.fs.copy( 126 | path.resolve(this.templatePath('gdt'), '**', '*'), 127 | this.destinationRoot(), 128 | { 129 | globOptions: { dot: true } 130 | } 131 | ); 132 | this.fs.copyTpl( 133 | path.resolve(this.templatePath('gdt'), 'test', 'behat.yml'), 134 | path.resolve(this.destinationRoot(), 'test', 'behat.yml'), 135 | options 136 | ); 137 | }, 138 | 139 | // This has been moved up from writing because the details of some of these 140 | // files may need to be loaded as part of configuring other write operations, 141 | // and the parallelization model for generator composition requires 142 | // dependencies to be handled in an earlier priority context. 143 | distroAdditions: function () { 144 | var srcFiles = path.resolve( 145 | this.templatePath('drupal'), 146 | options.drupalDistro.id, 147 | options.drupalDistroVersion 148 | ); 149 | 150 | if (gadget.fsExistsSync(srcFiles)) { 151 | this.fs.copy( 152 | path.resolve(srcFiles), 153 | this.destinationRoot(), 154 | { 155 | globOptions: { dot: true } 156 | } 157 | ); 158 | } 159 | 160 | this.composer = options.drupalDistro.loadComposer(this, options); 161 | }, 162 | 163 | // While there are write operations in this, other write operations may need 164 | // to examine the composer.json to determine their own configuration. 165 | prepareComposerJson: function () { 166 | var isNewProject = (this.composerOrig == undefined); 167 | if (!isNewProject) { 168 | // Use original composer file if project already generated. 169 | this.composer = this.composerOrig; 170 | } 171 | 172 | this.composer.name = 'organization/' + options.projectName; 173 | this.composer.description = options.projectDescription; 174 | // Allow distros to modify the composer.json. 175 | if (typeof options.drupalDistro.modifyComposer == 'function') { 176 | var done = this.async(); 177 | options.drupalDistro.modifyComposer(options, this.composer, isNewProject, done, function(err, result, done) { 178 | if (!err && result) { 179 | this.composer = result; 180 | } 181 | else { 182 | this.log.warning("Could not retrieve Octane's composer.json: " + err); 183 | return done(err); 184 | } 185 | done(); 186 | }.bind(this)); 187 | } 188 | } 189 | }, 190 | 191 | writing: { 192 | projectResources: function () { 193 | this.fs.copy( 194 | this.templatePath('project/gitignore'), 195 | this.destinationPath('.gitignore') 196 | ); 197 | this.fs.copy( 198 | this.templatePath('project/editorconfig'), 199 | this.destinationPath('.editorconfig') 200 | ); 201 | }, 202 | 203 | packageJson: function () { 204 | var pkg = this.fs.readJSON('package.json'); 205 | 206 | // Inject grunt-drupal-tasks into the dependency list. 207 | pkg.dependencies['grunt-drupal-tasks'] = gadget.npmVersion( 208 | 'grunt-drupal-tasks', 209 | '//github.com/phase2/grunt-drupal-tasks.git', 210 | this.options['use-master'] || this.options['offline'] 211 | ); 212 | 213 | pkg.name = options.projectName; 214 | pkg.description = options.projectDescription; 215 | 216 | if (!pkg['scripts']) { 217 | pkg.scripts = {}; 218 | } 219 | if (!pkg.scripts['postinstall'] && options['themePath']) { 220 | pkg.scripts['postinstall'] = 'cd ' + path.join(options.themePath, options.themeName) + ' && npm install'; 221 | } 222 | 223 | this.fs.writeJSON('package.json', pkg); 224 | }, 225 | 226 | gruntConfig: function () { 227 | var gcfg = this.fs.readJSON('Gruntconfig.json'); 228 | 229 | if (!gcfg) { 230 | //TODO: throw error 231 | } 232 | 233 | // Process theme options and insert into Gruntconfig.json. 234 | if (options.themeName && options.themePath) { 235 | var themeOpts = { 236 | path: path.join(options.themePath, options.themeName) 237 | }; 238 | 239 | if (options.themeType === 'compass') { 240 | themeOpts.compass = true; 241 | } 242 | else if (options.themeType === 'grunt' && options.themeGruntTask) { 243 | themeOpts.grunt = true; 244 | themeOpts.gruntTask = options.themeGruntTask; 245 | } 246 | 247 | if (options.themeScripts) { 248 | themeOpts.scripts = options.themeScripts; 249 | } 250 | 251 | if (!gcfg.hasOwnProperty('themes')) { 252 | gcfg.themes = {}; 253 | } 254 | gcfg.themes[options.themeName] = themeOpts; 255 | } 256 | 257 | gcfg.project = { 'profile': options.drupalDistro.profile }; 258 | gcfg.generated = { name: this.pkg.name, version: this.pkg.version }; 259 | 260 | this.fs.writeJSON('Gruntconfig.json', gcfg); 261 | }, 262 | 263 | readme: function () { 264 | if (!options['skip-readme']) { 265 | this.fs.copyTpl( 266 | this.templatePath('README.md'), 267 | this.destinationPath('README.md'), 268 | // Extracted to facilitate parallel README generation by a parent. 269 | gadget.tokens(options) 270 | ); 271 | } 272 | }, 273 | 274 | composerJson: function() { 275 | this.fs.writeJSON('composer.json', this.composer); 276 | }, 277 | 278 | drushMakefile: function () { 279 | // Make files only for 7.x and less. 280 | var coreVersion = drupalOrgApi.numericCoreVersion(options.drupalDistroVersion); 281 | if (coreVersion < 8) { 282 | this.log('Setting up Drush makefile to install Drupal Distribution ' 283 | + options.drupalDistro.option.name + ' version ' 284 | + chalk.red(options.drupalDistroRelease) + '.\n'); 285 | var done = this.async(); 286 | options.drupalDistro.drushMakeFile(this, options, done); 287 | } 288 | } 289 | }, 290 | 291 | install: function () { 292 | if (!options['skip-install'] && !options['offline']) { 293 | this.npmInstall(); 294 | } 295 | }, 296 | 297 | end: function () { 298 | if (!options['skipGoodbye']) { 299 | this.log('\nGadget has ' + chalk.red('finished') 300 | + ' setting up the Drupal project scaffold with Grunt Drupal Tasks!\n'); 301 | this.log('Run `' + chalk.red('grunt') 302 | + '` to start the first build of this project.\n'); 303 | } 304 | } 305 | }); 306 | -------------------------------------------------------------------------------- /npm-shrinkwrap.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "generator-gadget", 3 | "version": "1.0.1-pre", 4 | "dependencies": { 5 | "ajv": { 6 | "version": "4.11.8", 7 | "from": "ajv@>=4.9.1 <5.0.0", 8 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz" 9 | }, 10 | "ansi-escapes": { 11 | "version": "1.4.0", 12 | "from": "ansi-escapes@>=1.1.0 <2.0.0", 13 | "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz" 14 | }, 15 | "ansi-regex": { 16 | "version": "2.1.1", 17 | "from": "ansi-regex@>=2.0.0 <3.0.0", 18 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz" 19 | }, 20 | "ansi-styles": { 21 | "version": "2.2.1", 22 | "from": "ansi-styles@>=2.2.1 <3.0.0", 23 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz" 24 | }, 25 | "array-differ": { 26 | "version": "1.0.0", 27 | "from": "array-differ@>=1.0.0 <2.0.0", 28 | "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz" 29 | }, 30 | "array-union": { 31 | "version": "1.0.2", 32 | "from": "array-union@>=1.0.1 <2.0.0", 33 | "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz" 34 | }, 35 | "array-uniq": { 36 | "version": "1.0.3", 37 | "from": "array-uniq@>=1.0.1 <2.0.0", 38 | "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz" 39 | }, 40 | "arrify": { 41 | "version": "1.0.1", 42 | "from": "arrify@>=1.0.0 <2.0.0", 43 | "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz" 44 | }, 45 | "asn1": { 46 | "version": "0.2.3", 47 | "from": "asn1@>=0.2.3 <0.3.0", 48 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz" 49 | }, 50 | "assert-plus": { 51 | "version": "0.2.0", 52 | "from": "assert-plus@>=0.2.0 <0.3.0", 53 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz" 54 | }, 55 | "async": { 56 | "version": "2.4.1", 57 | "from": "async@>=2.0.0 <3.0.0", 58 | "resolved": "https://registry.npmjs.org/async/-/async-2.4.1.tgz" 59 | }, 60 | "asynckit": { 61 | "version": "0.4.0", 62 | "from": "asynckit@>=0.4.0 <0.5.0", 63 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" 64 | }, 65 | "aws-sign2": { 66 | "version": "0.6.0", 67 | "from": "aws-sign2@>=0.6.0 <0.7.0", 68 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz" 69 | }, 70 | "aws4": { 71 | "version": "1.6.0", 72 | "from": "aws4@>=1.2.1 <2.0.0", 73 | "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz" 74 | }, 75 | "balanced-match": { 76 | "version": "0.4.2", 77 | "from": "balanced-match@>=0.4.1 <0.5.0", 78 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz" 79 | }, 80 | "bcrypt-pbkdf": { 81 | "version": "1.0.1", 82 | "from": "bcrypt-pbkdf@>=1.0.0 <2.0.0", 83 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", 84 | "optional": true 85 | }, 86 | "binaryextensions": { 87 | "version": "2.0.0", 88 | "from": "binaryextensions@>=1.0.0 <2.0.0||>=2.0.0 <3.0.0", 89 | "resolved": "https://registry.npmjs.org/binaryextensions/-/binaryextensions-2.0.0.tgz" 90 | }, 91 | "boom": { 92 | "version": "2.10.1", 93 | "from": "boom@>=2.0.0 <3.0.0", 94 | "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz" 95 | }, 96 | "brace-expansion": { 97 | "version": "1.1.7", 98 | "from": "brace-expansion@>=1.1.7 <2.0.0", 99 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.7.tgz" 100 | }, 101 | "buffer-shims": { 102 | "version": "1.0.0", 103 | "from": "buffer-shims@>=1.0.0 <1.1.0", 104 | "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz" 105 | }, 106 | "builtin-modules": { 107 | "version": "1.1.1", 108 | "from": "builtin-modules@>=1.0.0 <2.0.0", 109 | "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz" 110 | }, 111 | "capture-stack-trace": { 112 | "version": "1.0.0", 113 | "from": "capture-stack-trace@>=1.0.0 <2.0.0", 114 | "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz" 115 | }, 116 | "caseless": { 117 | "version": "0.12.0", 118 | "from": "caseless@>=0.12.0 <0.13.0", 119 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz" 120 | }, 121 | "chalk": { 122 | "version": "1.1.3", 123 | "from": "chalk@>=1.1.3 <2.0.0", 124 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz" 125 | }, 126 | "class-extend": { 127 | "version": "0.1.2", 128 | "from": "class-extend@>=0.1.0 <0.2.0", 129 | "resolved": "https://registry.npmjs.org/class-extend/-/class-extend-0.1.2.tgz" 130 | }, 131 | "cli-boxes": { 132 | "version": "1.0.0", 133 | "from": "cli-boxes@>=1.0.0 <2.0.0", 134 | "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz" 135 | }, 136 | "cli-cursor": { 137 | "version": "1.0.2", 138 | "from": "cli-cursor@>=1.0.1 <2.0.0", 139 | "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz" 140 | }, 141 | "cli-table": { 142 | "version": "0.3.1", 143 | "from": "cli-table@>=0.3.1 <0.4.0", 144 | "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.1.tgz" 145 | }, 146 | "cli-width": { 147 | "version": "2.1.0", 148 | "from": "cli-width@>=2.0.0 <3.0.0", 149 | "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.1.0.tgz" 150 | }, 151 | "clone": { 152 | "version": "1.0.2", 153 | "from": "clone@>=1.0.0 <2.0.0", 154 | "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz" 155 | }, 156 | "clone-buffer": { 157 | "version": "1.0.0", 158 | "from": "clone-buffer@>=1.0.0 <2.0.0", 159 | "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz" 160 | }, 161 | "clone-stats": { 162 | "version": "1.0.0", 163 | "from": "clone-stats@>=1.0.0 <2.0.0", 164 | "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz" 165 | }, 166 | "cloneable-readable": { 167 | "version": "1.0.0", 168 | "from": "cloneable-readable@>=1.0.0 <2.0.0", 169 | "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.0.0.tgz" 170 | }, 171 | "co": { 172 | "version": "4.6.0", 173 | "from": "co@>=4.6.0 <5.0.0", 174 | "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz" 175 | }, 176 | "code-point-at": { 177 | "version": "1.1.0", 178 | "from": "code-point-at@>=1.0.0 <2.0.0", 179 | "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz" 180 | }, 181 | "color-convert": { 182 | "version": "1.9.0", 183 | "from": "color-convert@>=1.0.0 <2.0.0", 184 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz" 185 | }, 186 | "color-name": { 187 | "version": "1.1.2", 188 | "from": "color-name@>=1.1.1 <2.0.0", 189 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.2.tgz" 190 | }, 191 | "colors": { 192 | "version": "1.0.3", 193 | "from": "colors@1.0.3", 194 | "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz" 195 | }, 196 | "combined-stream": { 197 | "version": "1.0.5", 198 | "from": "combined-stream@>=1.0.5 <1.1.0", 199 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz" 200 | }, 201 | "commondir": { 202 | "version": "1.0.1", 203 | "from": "commondir@>=1.0.1 <2.0.0", 204 | "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz" 205 | }, 206 | "concat-map": { 207 | "version": "0.0.1", 208 | "from": "concat-map@0.0.1", 209 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" 210 | }, 211 | "concat-stream": { 212 | "version": "1.6.0", 213 | "from": "concat-stream@>=1.4.7 <2.0.0", 214 | "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz" 215 | }, 216 | "core-util-is": { 217 | "version": "1.0.2", 218 | "from": "core-util-is@>=1.0.0 <1.1.0", 219 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" 220 | }, 221 | "create-error-class": { 222 | "version": "3.0.2", 223 | "from": "create-error-class@>=3.0.0 <4.0.0", 224 | "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz" 225 | }, 226 | "cross-spawn": { 227 | "version": "5.1.0", 228 | "from": "cross-spawn@>=5.0.1 <6.0.0", 229 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz" 230 | }, 231 | "cryptiles": { 232 | "version": "2.0.5", 233 | "from": "cryptiles@>=2.0.0 <3.0.0", 234 | "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz" 235 | }, 236 | "dargs": { 237 | "version": "5.1.0", 238 | "from": "dargs@>=5.1.0 <6.0.0", 239 | "resolved": "https://registry.npmjs.org/dargs/-/dargs-5.1.0.tgz" 240 | }, 241 | "dashdash": { 242 | "version": "1.14.1", 243 | "from": "dashdash@>=1.12.0 <2.0.0", 244 | "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", 245 | "dependencies": { 246 | "assert-plus": { 247 | "version": "1.0.0", 248 | "from": "assert-plus@>=1.0.0 <2.0.0", 249 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" 250 | } 251 | } 252 | }, 253 | "dateformat": { 254 | "version": "2.0.0", 255 | "from": "dateformat@>=2.0.0 <3.0.0", 256 | "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.0.0.tgz" 257 | }, 258 | "debug": { 259 | "version": "2.6.8", 260 | "from": "debug@>=2.1.0 <3.0.0", 261 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz" 262 | }, 263 | "deep-extend": { 264 | "version": "0.4.2", 265 | "from": "deep-extend@>=0.4.0 <0.5.0", 266 | "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz" 267 | }, 268 | "delayed-stream": { 269 | "version": "1.0.0", 270 | "from": "delayed-stream@>=1.0.0 <1.1.0", 271 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" 272 | }, 273 | "detect-conflict": { 274 | "version": "1.0.1", 275 | "from": "detect-conflict@>=1.0.0 <2.0.0", 276 | "resolved": "https://registry.npmjs.org/detect-conflict/-/detect-conflict-1.0.1.tgz" 277 | }, 278 | "diff": { 279 | "version": "2.2.3", 280 | "from": "diff@>=2.1.2 <3.0.0", 281 | "resolved": "https://registry.npmjs.org/diff/-/diff-2.2.3.tgz" 282 | }, 283 | "duplexer3": { 284 | "version": "0.1.4", 285 | "from": "duplexer3@>=0.1.4 <0.2.0", 286 | "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz" 287 | }, 288 | "ecc-jsbn": { 289 | "version": "0.1.1", 290 | "from": "ecc-jsbn@>=0.1.1 <0.2.0", 291 | "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", 292 | "optional": true 293 | }, 294 | "editions": { 295 | "version": "1.3.3", 296 | "from": "editions@>=1.1.1 <2.0.0", 297 | "resolved": "https://registry.npmjs.org/editions/-/editions-1.3.3.tgz" 298 | }, 299 | "ejs": { 300 | "version": "2.5.6", 301 | "from": "ejs@>=2.3.1 <3.0.0", 302 | "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.5.6.tgz" 303 | }, 304 | "error": { 305 | "version": "7.0.2", 306 | "from": "error@>=7.0.2 <8.0.0", 307 | "resolved": "https://registry.npmjs.org/error/-/error-7.0.2.tgz" 308 | }, 309 | "error-ex": { 310 | "version": "1.3.1", 311 | "from": "error-ex@>=1.2.0 <2.0.0", 312 | "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz" 313 | }, 314 | "escape-string-regexp": { 315 | "version": "1.0.5", 316 | "from": "escape-string-regexp@>=1.0.2 <2.0.0", 317 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" 318 | }, 319 | "exit-hook": { 320 | "version": "1.1.1", 321 | "from": "exit-hook@>=1.0.0 <2.0.0", 322 | "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz" 323 | }, 324 | "extend": { 325 | "version": "3.0.1", 326 | "from": "extend@>=3.0.0 <3.1.0", 327 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz" 328 | }, 329 | "external-editor": { 330 | "version": "1.1.1", 331 | "from": "external-editor@>=1.1.0 <2.0.0", 332 | "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-1.1.1.tgz" 333 | }, 334 | "extsprintf": { 335 | "version": "1.0.2", 336 | "from": "extsprintf@1.0.2", 337 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz" 338 | }, 339 | "figures": { 340 | "version": "1.7.0", 341 | "from": "figures@>=1.3.5 <2.0.0", 342 | "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", 343 | "dependencies": { 344 | "object-assign": { 345 | "version": "4.1.1", 346 | "from": "object-assign@>=4.1.0 <5.0.0", 347 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" 348 | } 349 | } 350 | }, 351 | "find-up": { 352 | "version": "2.1.0", 353 | "from": "find-up@>=2.1.0 <3.0.0", 354 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz" 355 | }, 356 | "first-chunk-stream": { 357 | "version": "2.0.0", 358 | "from": "first-chunk-stream@>=2.0.0 <3.0.0", 359 | "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-2.0.0.tgz" 360 | }, 361 | "forever-agent": { 362 | "version": "0.6.1", 363 | "from": "forever-agent@>=0.6.1 <0.7.0", 364 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz" 365 | }, 366 | "form-data": { 367 | "version": "2.1.4", 368 | "from": "form-data@>=2.1.1 <2.2.0", 369 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz" 370 | }, 371 | "fs.realpath": { 372 | "version": "1.0.0", 373 | "from": "fs.realpath@>=1.0.0 <2.0.0", 374 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" 375 | }, 376 | "get-stdin": { 377 | "version": "4.0.1", 378 | "from": "get-stdin@>=4.0.1 <5.0.0", 379 | "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz" 380 | }, 381 | "get-stream": { 382 | "version": "3.0.0", 383 | "from": "get-stream@>=3.0.0 <4.0.0", 384 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz" 385 | }, 386 | "getpass": { 387 | "version": "0.1.7", 388 | "from": "getpass@>=0.1.1 <0.2.0", 389 | "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", 390 | "dependencies": { 391 | "assert-plus": { 392 | "version": "1.0.0", 393 | "from": "assert-plus@>=1.0.0 <2.0.0", 394 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" 395 | } 396 | } 397 | }, 398 | "gh-got": { 399 | "version": "5.0.0", 400 | "from": "gh-got@>=5.0.0 <6.0.0", 401 | "resolved": "https://registry.npmjs.org/gh-got/-/gh-got-5.0.0.tgz" 402 | }, 403 | "github-username": { 404 | "version": "3.0.0", 405 | "from": "github-username@>=3.0.0 <4.0.0", 406 | "resolved": "https://registry.npmjs.org/github-username/-/github-username-3.0.0.tgz" 407 | }, 408 | "glob": { 409 | "version": "7.1.2", 410 | "from": "glob@>=7.0.3 <8.0.0", 411 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz" 412 | }, 413 | "globby": { 414 | "version": "6.1.0", 415 | "from": "globby@>=6.1.0 <7.0.0", 416 | "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", 417 | "dependencies": { 418 | "object-assign": { 419 | "version": "4.1.1", 420 | "from": "object-assign@>=4.0.1 <5.0.0", 421 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" 422 | } 423 | } 424 | }, 425 | "got": { 426 | "version": "6.7.1", 427 | "from": "got@>=6.2.0 <7.0.0", 428 | "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz" 429 | }, 430 | "graceful-fs": { 431 | "version": "4.1.11", 432 | "from": "graceful-fs@>=4.1.2 <5.0.0", 433 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz" 434 | }, 435 | "grouped-queue": { 436 | "version": "0.3.3", 437 | "from": "grouped-queue@>=0.3.0 <0.4.0", 438 | "resolved": "https://registry.npmjs.org/grouped-queue/-/grouped-queue-0.3.3.tgz" 439 | }, 440 | "har-schema": { 441 | "version": "1.0.5", 442 | "from": "har-schema@>=1.0.5 <2.0.0", 443 | "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz" 444 | }, 445 | "har-validator": { 446 | "version": "4.2.1", 447 | "from": "har-validator@>=4.2.1 <4.3.0", 448 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz" 449 | }, 450 | "has-ansi": { 451 | "version": "2.0.0", 452 | "from": "has-ansi@>=2.0.0 <3.0.0", 453 | "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz" 454 | }, 455 | "hawk": { 456 | "version": "3.1.3", 457 | "from": "hawk@>=3.1.3 <3.2.0", 458 | "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz" 459 | }, 460 | "hoek": { 461 | "version": "2.16.3", 462 | "from": "hoek@>=2.0.0 <3.0.0", 463 | "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz" 464 | }, 465 | "hosted-git-info": { 466 | "version": "2.4.2", 467 | "from": "hosted-git-info@>=2.1.4 <3.0.0", 468 | "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.4.2.tgz" 469 | }, 470 | "http-signature": { 471 | "version": "1.1.1", 472 | "from": "http-signature@>=1.1.0 <1.2.0", 473 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz" 474 | }, 475 | "inflight": { 476 | "version": "1.0.6", 477 | "from": "inflight@>=1.0.4 <2.0.0", 478 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" 479 | }, 480 | "inherits": { 481 | "version": "2.0.3", 482 | "from": "inherits@>=2.0.0 <3.0.0", 483 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" 484 | }, 485 | "inquirer": { 486 | "version": "1.2.3", 487 | "from": "inquirer@>=1.0.2 <2.0.0", 488 | "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-1.2.3.tgz" 489 | }, 490 | "interpret": { 491 | "version": "1.0.3", 492 | "from": "interpret@>=1.0.0 <2.0.0", 493 | "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.0.3.tgz" 494 | }, 495 | "is-arrayish": { 496 | "version": "0.2.1", 497 | "from": "is-arrayish@>=0.2.1 <0.3.0", 498 | "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz" 499 | }, 500 | "is-builtin-module": { 501 | "version": "1.0.0", 502 | "from": "is-builtin-module@>=1.0.0 <2.0.0", 503 | "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz" 504 | }, 505 | "is-fullwidth-code-point": { 506 | "version": "1.0.0", 507 | "from": "is-fullwidth-code-point@>=1.0.0 <2.0.0", 508 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz" 509 | }, 510 | "is-plain-obj": { 511 | "version": "1.1.0", 512 | "from": "is-plain-obj@>=1.1.0 <2.0.0", 513 | "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz" 514 | }, 515 | "is-promise": { 516 | "version": "2.1.0", 517 | "from": "is-promise@>=2.1.0 <3.0.0", 518 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz" 519 | }, 520 | "is-redirect": { 521 | "version": "1.0.0", 522 | "from": "is-redirect@>=1.0.0 <2.0.0", 523 | "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz" 524 | }, 525 | "is-retry-allowed": { 526 | "version": "1.1.0", 527 | "from": "is-retry-allowed@>=1.0.0 <2.0.0", 528 | "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz" 529 | }, 530 | "is-stream": { 531 | "version": "1.1.0", 532 | "from": "is-stream@>=1.0.0 <2.0.0", 533 | "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz" 534 | }, 535 | "is-typedarray": { 536 | "version": "1.0.0", 537 | "from": "is-typedarray@>=1.0.0 <1.1.0", 538 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz" 539 | }, 540 | "is-utf8": { 541 | "version": "0.2.1", 542 | "from": "is-utf8@>=0.2.0 <0.3.0", 543 | "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz" 544 | }, 545 | "isarray": { 546 | "version": "1.0.0", 547 | "from": "isarray@>=1.0.0 <1.1.0", 548 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" 549 | }, 550 | "isexe": { 551 | "version": "2.0.0", 552 | "from": "isexe@>=2.0.0 <3.0.0", 553 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" 554 | }, 555 | "isstream": { 556 | "version": "0.1.2", 557 | "from": "isstream@>=0.1.2 <0.2.0", 558 | "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz" 559 | }, 560 | "istextorbinary": { 561 | "version": "2.1.0", 562 | "from": "istextorbinary@>=2.1.0 <3.0.0", 563 | "resolved": "https://registry.npmjs.org/istextorbinary/-/istextorbinary-2.1.0.tgz" 564 | }, 565 | "jodid25519": { 566 | "version": "1.0.2", 567 | "from": "jodid25519@>=1.0.0 <2.0.0", 568 | "resolved": "https://registry.npmjs.org/jodid25519/-/jodid25519-1.0.2.tgz", 569 | "optional": true 570 | }, 571 | "jsbn": { 572 | "version": "0.1.1", 573 | "from": "jsbn@>=0.1.0 <0.2.0", 574 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", 575 | "optional": true 576 | }, 577 | "json-schema": { 578 | "version": "0.2.3", 579 | "from": "json-schema@0.2.3", 580 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz" 581 | }, 582 | "json-stable-stringify": { 583 | "version": "1.0.1", 584 | "from": "json-stable-stringify@>=1.0.1 <2.0.0", 585 | "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz" 586 | }, 587 | "json-stringify-safe": { 588 | "version": "5.0.1", 589 | "from": "json-stringify-safe@>=5.0.1 <5.1.0", 590 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" 591 | }, 592 | "jsonify": { 593 | "version": "0.0.0", 594 | "from": "jsonify@>=0.0.0 <0.1.0", 595 | "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz" 596 | }, 597 | "jsprim": { 598 | "version": "1.4.0", 599 | "from": "jsprim@>=1.2.2 <2.0.0", 600 | "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.0.tgz", 601 | "dependencies": { 602 | "assert-plus": { 603 | "version": "1.0.0", 604 | "from": "assert-plus@1.0.0", 605 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" 606 | } 607 | } 608 | }, 609 | "load-json-file": { 610 | "version": "2.0.0", 611 | "from": "load-json-file@>=2.0.0 <3.0.0", 612 | "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz" 613 | }, 614 | "locate-path": { 615 | "version": "2.0.0", 616 | "from": "locate-path@>=2.0.0 <3.0.0", 617 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz" 618 | }, 619 | "lodash": { 620 | "version": "4.17.4", 621 | "from": "lodash@>=4.17.4 <5.0.0", 622 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz" 623 | }, 624 | "log-symbols": { 625 | "version": "1.0.2", 626 | "from": "log-symbols@>=1.0.1 <2.0.0", 627 | "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz" 628 | }, 629 | "lowercase-keys": { 630 | "version": "1.0.0", 631 | "from": "lowercase-keys@>=1.0.0 <2.0.0", 632 | "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz" 633 | }, 634 | "lru-cache": { 635 | "version": "4.0.2", 636 | "from": "lru-cache@>=4.0.1 <5.0.0", 637 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.2.tgz" 638 | }, 639 | "mem-fs": { 640 | "version": "1.1.3", 641 | "from": "mem-fs@>=1.1.0 <2.0.0", 642 | "resolved": "https://registry.npmjs.org/mem-fs/-/mem-fs-1.1.3.tgz", 643 | "dependencies": { 644 | "clone-stats": { 645 | "version": "0.0.1", 646 | "from": "clone-stats@>=0.0.1 <0.0.2", 647 | "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz" 648 | }, 649 | "replace-ext": { 650 | "version": "0.0.1", 651 | "from": "replace-ext@0.0.1", 652 | "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz" 653 | }, 654 | "vinyl": { 655 | "version": "1.2.0", 656 | "from": "vinyl@>=1.1.0 <2.0.0", 657 | "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz" 658 | } 659 | } 660 | }, 661 | "mem-fs-editor": { 662 | "version": "3.0.2", 663 | "from": "mem-fs-editor@>=3.0.0 <4.0.0", 664 | "resolved": "https://registry.npmjs.org/mem-fs-editor/-/mem-fs-editor-3.0.2.tgz" 665 | }, 666 | "merge": { 667 | "version": "1.2.0", 668 | "from": "merge@>=1.2.0 <2.0.0", 669 | "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.0.tgz" 670 | }, 671 | "mime-db": { 672 | "version": "1.27.0", 673 | "from": "mime-db@>=1.27.0 <1.28.0", 674 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.27.0.tgz" 675 | }, 676 | "mime-types": { 677 | "version": "2.1.15", 678 | "from": "mime-types@>=2.1.7 <2.2.0", 679 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.15.tgz" 680 | }, 681 | "minimatch": { 682 | "version": "3.0.4", 683 | "from": "minimatch@>=3.0.4 <4.0.0", 684 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz" 685 | }, 686 | "minimist": { 687 | "version": "1.2.0", 688 | "from": "minimist@>=1.2.0 <2.0.0", 689 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz" 690 | }, 691 | "mkdirp": { 692 | "version": "0.5.1", 693 | "from": "mkdirp@>=0.5.0 <0.6.0", 694 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 695 | "dependencies": { 696 | "minimist": { 697 | "version": "0.0.8", 698 | "from": "minimist@0.0.8", 699 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz" 700 | } 701 | } 702 | }, 703 | "ms": { 704 | "version": "2.0.0", 705 | "from": "ms@2.0.0", 706 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" 707 | }, 708 | "multimatch": { 709 | "version": "2.1.0", 710 | "from": "multimatch@>=2.0.0 <3.0.0", 711 | "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz" 712 | }, 713 | "mute-stream": { 714 | "version": "0.0.6", 715 | "from": "mute-stream@0.0.6", 716 | "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.6.tgz" 717 | }, 718 | "normalize-package-data": { 719 | "version": "2.3.8", 720 | "from": "normalize-package-data@>=2.3.2 <3.0.0", 721 | "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.3.8.tgz" 722 | }, 723 | "number-is-nan": { 724 | "version": "1.0.1", 725 | "from": "number-is-nan@>=1.0.0 <2.0.0", 726 | "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz" 727 | }, 728 | "oauth-sign": { 729 | "version": "0.8.2", 730 | "from": "oauth-sign@>=0.8.1 <0.9.0", 731 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz" 732 | }, 733 | "object-assign": { 734 | "version": "2.1.1", 735 | "from": "object-assign@>=2.0.0 <3.0.0", 736 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz" 737 | }, 738 | "once": { 739 | "version": "1.4.0", 740 | "from": "once@>=1.3.0 <2.0.0", 741 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz" 742 | }, 743 | "onetime": { 744 | "version": "1.1.0", 745 | "from": "onetime@>=1.0.0 <2.0.0", 746 | "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz" 747 | }, 748 | "os-homedir": { 749 | "version": "1.0.2", 750 | "from": "os-homedir@>=1.0.0 <2.0.0", 751 | "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz" 752 | }, 753 | "os-shim": { 754 | "version": "0.1.3", 755 | "from": "os-shim@>=0.1.2 <0.2.0", 756 | "resolved": "https://registry.npmjs.org/os-shim/-/os-shim-0.1.3.tgz" 757 | }, 758 | "os-tmpdir": { 759 | "version": "1.0.2", 760 | "from": "os-tmpdir@>=1.0.1 <1.1.0", 761 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz" 762 | }, 763 | "p-limit": { 764 | "version": "1.1.0", 765 | "from": "p-limit@>=1.1.0 <2.0.0", 766 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz" 767 | }, 768 | "p-locate": { 769 | "version": "2.0.0", 770 | "from": "p-locate@>=2.0.0 <3.0.0", 771 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz" 772 | }, 773 | "pad-component": { 774 | "version": "0.0.1", 775 | "from": "pad-component@0.0.1", 776 | "resolved": "https://registry.npmjs.org/pad-component/-/pad-component-0.0.1.tgz" 777 | }, 778 | "parse-json": { 779 | "version": "2.2.0", 780 | "from": "parse-json@>=2.2.0 <3.0.0", 781 | "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz" 782 | }, 783 | "path-exists": { 784 | "version": "3.0.0", 785 | "from": "path-exists@>=3.0.0 <4.0.0", 786 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz" 787 | }, 788 | "path-is-absolute": { 789 | "version": "1.0.1", 790 | "from": "path-is-absolute@>=1.0.0 <2.0.0", 791 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" 792 | }, 793 | "path-parse": { 794 | "version": "1.0.5", 795 | "from": "path-parse@>=1.0.5 <2.0.0", 796 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz" 797 | }, 798 | "path-type": { 799 | "version": "2.0.0", 800 | "from": "path-type@>=2.0.0 <3.0.0", 801 | "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz" 802 | }, 803 | "performance-now": { 804 | "version": "0.2.0", 805 | "from": "performance-now@>=0.2.0 <0.3.0", 806 | "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz" 807 | }, 808 | "pify": { 809 | "version": "2.3.0", 810 | "from": "pify@>=2.0.0 <3.0.0", 811 | "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz" 812 | }, 813 | "pinkie": { 814 | "version": "2.0.4", 815 | "from": "pinkie@>=2.0.0 <3.0.0", 816 | "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz" 817 | }, 818 | "pinkie-promise": { 819 | "version": "2.0.1", 820 | "from": "pinkie-promise@>=2.0.0 <3.0.0", 821 | "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz" 822 | }, 823 | "prepend-http": { 824 | "version": "1.0.4", 825 | "from": "prepend-http@>=1.0.1 <2.0.0", 826 | "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz" 827 | }, 828 | "pretty-bytes": { 829 | "version": "4.0.2", 830 | "from": "pretty-bytes@>=4.0.2 <5.0.0", 831 | "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-4.0.2.tgz" 832 | }, 833 | "process-nextick-args": { 834 | "version": "1.0.7", 835 | "from": "process-nextick-args@>=1.0.6 <1.1.0", 836 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz" 837 | }, 838 | "pseudomap": { 839 | "version": "1.0.2", 840 | "from": "pseudomap@>=1.0.1 <2.0.0", 841 | "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz" 842 | }, 843 | "punycode": { 844 | "version": "1.4.1", 845 | "from": "punycode@>=1.4.1 <2.0.0", 846 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz" 847 | }, 848 | "qs": { 849 | "version": "6.4.0", 850 | "from": "qs@>=6.4.0 <6.5.0", 851 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz" 852 | }, 853 | "read-chunk": { 854 | "version": "2.0.0", 855 | "from": "read-chunk@>=2.0.0 <3.0.0", 856 | "resolved": "https://registry.npmjs.org/read-chunk/-/read-chunk-2.0.0.tgz" 857 | }, 858 | "read-pkg": { 859 | "version": "2.0.0", 860 | "from": "read-pkg@>=2.0.0 <3.0.0", 861 | "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz" 862 | }, 863 | "read-pkg-up": { 864 | "version": "2.0.0", 865 | "from": "read-pkg-up@>=2.0.0 <3.0.0", 866 | "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz" 867 | }, 868 | "readable-stream": { 869 | "version": "2.2.9", 870 | "from": "readable-stream@>=2.1.5 <3.0.0", 871 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz" 872 | }, 873 | "rechoir": { 874 | "version": "0.6.2", 875 | "from": "rechoir@>=0.6.2 <0.7.0", 876 | "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz" 877 | }, 878 | "remove-trailing-separator": { 879 | "version": "1.0.1", 880 | "from": "remove-trailing-separator@>=1.0.1 <2.0.0", 881 | "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.0.1.tgz" 882 | }, 883 | "replace-ext": { 884 | "version": "1.0.0", 885 | "from": "replace-ext@>=1.0.0 <2.0.0", 886 | "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz" 887 | }, 888 | "request": { 889 | "version": "2.81.0", 890 | "from": "request@>=2.79.0 <3.0.0", 891 | "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz" 892 | }, 893 | "require-directory": { 894 | "version": "2.1.1", 895 | "from": "require-directory@>=2.1.1 <3.0.0", 896 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" 897 | }, 898 | "resolve": { 899 | "version": "1.3.3", 900 | "from": "resolve@>=1.1.6 <2.0.0", 901 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.3.3.tgz" 902 | }, 903 | "restore-cursor": { 904 | "version": "1.0.1", 905 | "from": "restore-cursor@>=1.0.1 <2.0.0", 906 | "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz" 907 | }, 908 | "rimraf": { 909 | "version": "2.6.1", 910 | "from": "rimraf@>=2.2.0 <3.0.0", 911 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz" 912 | }, 913 | "run-async": { 914 | "version": "2.3.0", 915 | "from": "run-async@>=2.0.0 <3.0.0", 916 | "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz" 917 | }, 918 | "rx": { 919 | "version": "4.1.0", 920 | "from": "rx@>=4.1.0 <5.0.0", 921 | "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz" 922 | }, 923 | "safe-buffer": { 924 | "version": "5.0.1", 925 | "from": "safe-buffer@>=5.0.1 <6.0.0", 926 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.0.1.tgz" 927 | }, 928 | "sax": { 929 | "version": "1.2.2", 930 | "from": "sax@>=0.6.0", 931 | "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.2.tgz" 932 | }, 933 | "semver": { 934 | "version": "5.3.0", 935 | "from": "semver@>=2.0.0 <3.0.0||>=3.0.0 <4.0.0||>=4.0.0 <5.0.0||>=5.0.0 <6.0.0", 936 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz" 937 | }, 938 | "shebang-command": { 939 | "version": "1.2.0", 940 | "from": "shebang-command@>=1.2.0 <2.0.0", 941 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz" 942 | }, 943 | "shebang-regex": { 944 | "version": "1.0.0", 945 | "from": "shebang-regex@>=1.0.0 <2.0.0", 946 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz" 947 | }, 948 | "shelljs": { 949 | "version": "0.7.7", 950 | "from": "shelljs@>=0.7.0 <0.8.0", 951 | "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.7.tgz" 952 | }, 953 | "sntp": { 954 | "version": "1.0.9", 955 | "from": "sntp@>=1.0.0 <2.0.0", 956 | "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz" 957 | }, 958 | "spawn-sync": { 959 | "version": "1.0.15", 960 | "from": "spawn-sync@>=1.0.15 <2.0.0", 961 | "resolved": "https://registry.npmjs.org/spawn-sync/-/spawn-sync-1.0.15.tgz" 962 | }, 963 | "spdx-correct": { 964 | "version": "1.0.2", 965 | "from": "spdx-correct@>=1.0.0 <1.1.0", 966 | "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz" 967 | }, 968 | "spdx-expression-parse": { 969 | "version": "1.0.4", 970 | "from": "spdx-expression-parse@>=1.0.0 <1.1.0", 971 | "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz" 972 | }, 973 | "spdx-license-ids": { 974 | "version": "1.2.2", 975 | "from": "spdx-license-ids@>=1.0.2 <2.0.0", 976 | "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz" 977 | }, 978 | "sshpk": { 979 | "version": "1.13.0", 980 | "from": "sshpk@>=1.7.0 <2.0.0", 981 | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.0.tgz", 982 | "dependencies": { 983 | "assert-plus": { 984 | "version": "1.0.0", 985 | "from": "assert-plus@>=1.0.0 <2.0.0", 986 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" 987 | } 988 | } 989 | }, 990 | "string_decoder": { 991 | "version": "1.0.1", 992 | "from": "string_decoder@>=1.0.0 <1.1.0", 993 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.1.tgz" 994 | }, 995 | "string-template": { 996 | "version": "0.2.1", 997 | "from": "string-template@>=0.2.1 <0.3.0", 998 | "resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz" 999 | }, 1000 | "string-width": { 1001 | "version": "1.0.2", 1002 | "from": "string-width@>=1.0.1 <2.0.0", 1003 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz" 1004 | }, 1005 | "stringstream": { 1006 | "version": "0.0.5", 1007 | "from": "stringstream@>=0.0.4 <0.1.0", 1008 | "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz" 1009 | }, 1010 | "strip-ansi": { 1011 | "version": "3.0.1", 1012 | "from": "strip-ansi@>=3.0.0 <4.0.0", 1013 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz" 1014 | }, 1015 | "strip-bom": { 1016 | "version": "3.0.0", 1017 | "from": "strip-bom@>=3.0.0 <4.0.0", 1018 | "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" 1019 | }, 1020 | "strip-bom-stream": { 1021 | "version": "2.0.0", 1022 | "from": "strip-bom-stream@>=2.0.0 <3.0.0", 1023 | "resolved": "https://registry.npmjs.org/strip-bom-stream/-/strip-bom-stream-2.0.0.tgz", 1024 | "dependencies": { 1025 | "strip-bom": { 1026 | "version": "2.0.0", 1027 | "from": "strip-bom@>=2.0.0 <3.0.0", 1028 | "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz" 1029 | } 1030 | } 1031 | }, 1032 | "supports-color": { 1033 | "version": "2.0.0", 1034 | "from": "supports-color@>=2.0.0 <3.0.0", 1035 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz" 1036 | }, 1037 | "taketalk": { 1038 | "version": "1.0.0", 1039 | "from": "taketalk@>=1.0.0 <2.0.0", 1040 | "resolved": "https://registry.npmjs.org/taketalk/-/taketalk-1.0.0.tgz" 1041 | }, 1042 | "text-table": { 1043 | "version": "0.2.0", 1044 | "from": "text-table@>=0.2.0 <0.3.0", 1045 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" 1046 | }, 1047 | "textextensions": { 1048 | "version": "2.1.0", 1049 | "from": "textextensions@>=1.0.0 <2.0.0||>=2.0.0 <3.0.0", 1050 | "resolved": "https://registry.npmjs.org/textextensions/-/textextensions-2.1.0.tgz" 1051 | }, 1052 | "through": { 1053 | "version": "2.3.8", 1054 | "from": "through@>=2.3.6 <3.0.0", 1055 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz" 1056 | }, 1057 | "through2": { 1058 | "version": "2.0.3", 1059 | "from": "through2@>=2.0.0 <3.0.0", 1060 | "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz" 1061 | }, 1062 | "timed-out": { 1063 | "version": "4.0.1", 1064 | "from": "timed-out@>=4.0.0 <5.0.0", 1065 | "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz" 1066 | }, 1067 | "tmp": { 1068 | "version": "0.0.29", 1069 | "from": "tmp@>=0.0.29 <0.0.30", 1070 | "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.29.tgz" 1071 | }, 1072 | "tough-cookie": { 1073 | "version": "2.3.2", 1074 | "from": "tough-cookie@>=2.3.0 <2.4.0", 1075 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz" 1076 | }, 1077 | "tunnel-agent": { 1078 | "version": "0.6.0", 1079 | "from": "tunnel-agent@>=0.6.0 <0.7.0", 1080 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz" 1081 | }, 1082 | "tweetnacl": { 1083 | "version": "0.14.5", 1084 | "from": "tweetnacl@>=0.14.0 <0.15.0", 1085 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", 1086 | "optional": true 1087 | }, 1088 | "typedarray": { 1089 | "version": "0.0.6", 1090 | "from": "typedarray@>=0.0.6 <0.0.7", 1091 | "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz" 1092 | }, 1093 | "untildify": { 1094 | "version": "2.1.0", 1095 | "from": "untildify@>=2.0.0 <3.0.0", 1096 | "resolved": "https://registry.npmjs.org/untildify/-/untildify-2.1.0.tgz" 1097 | }, 1098 | "unzip-response": { 1099 | "version": "2.0.1", 1100 | "from": "unzip-response@>=2.0.1 <3.0.0", 1101 | "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz" 1102 | }, 1103 | "url-parse-lax": { 1104 | "version": "1.0.0", 1105 | "from": "url-parse-lax@>=1.0.0 <2.0.0", 1106 | "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz" 1107 | }, 1108 | "user-home": { 1109 | "version": "2.0.0", 1110 | "from": "user-home@>=2.0.0 <3.0.0", 1111 | "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz" 1112 | }, 1113 | "util-deprecate": { 1114 | "version": "1.0.2", 1115 | "from": "util-deprecate@>=1.0.1 <1.1.0", 1116 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" 1117 | }, 1118 | "uuid": { 1119 | "version": "3.0.1", 1120 | "from": "uuid@>=3.0.0 <4.0.0", 1121 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.0.1.tgz" 1122 | }, 1123 | "validate-npm-package-license": { 1124 | "version": "3.0.1", 1125 | "from": "validate-npm-package-license@>=3.0.1 <4.0.0", 1126 | "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz" 1127 | }, 1128 | "verror": { 1129 | "version": "1.3.6", 1130 | "from": "verror@1.3.6", 1131 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz" 1132 | }, 1133 | "vinyl": { 1134 | "version": "2.0.2", 1135 | "from": "vinyl@>=2.0.1 <3.0.0", 1136 | "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.0.2.tgz" 1137 | }, 1138 | "vinyl-file": { 1139 | "version": "2.0.0", 1140 | "from": "vinyl-file@>=2.0.0 <3.0.0", 1141 | "resolved": "https://registry.npmjs.org/vinyl-file/-/vinyl-file-2.0.0.tgz", 1142 | "dependencies": { 1143 | "clone-stats": { 1144 | "version": "0.0.1", 1145 | "from": "clone-stats@>=0.0.1 <0.0.2", 1146 | "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz" 1147 | }, 1148 | "replace-ext": { 1149 | "version": "0.0.1", 1150 | "from": "replace-ext@0.0.1", 1151 | "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz" 1152 | }, 1153 | "strip-bom": { 1154 | "version": "2.0.0", 1155 | "from": "strip-bom@>=2.0.0 <3.0.0", 1156 | "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz" 1157 | }, 1158 | "vinyl": { 1159 | "version": "1.2.0", 1160 | "from": "vinyl@>=1.1.0 <2.0.0", 1161 | "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz" 1162 | } 1163 | } 1164 | }, 1165 | "which": { 1166 | "version": "1.2.14", 1167 | "from": "which@>=1.2.9 <2.0.0", 1168 | "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz" 1169 | }, 1170 | "wrap-ansi": { 1171 | "version": "2.1.0", 1172 | "from": "wrap-ansi@>=2.0.0 <3.0.0", 1173 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz" 1174 | }, 1175 | "wrappy": { 1176 | "version": "1.0.2", 1177 | "from": "wrappy@>=1.0.0 <2.0.0", 1178 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" 1179 | }, 1180 | "xml2js": { 1181 | "version": "0.4.17", 1182 | "from": "xml2js@>=0.4.17 <0.5.0", 1183 | "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.17.tgz" 1184 | }, 1185 | "xmlbuilder": { 1186 | "version": "4.2.1", 1187 | "from": "xmlbuilder@>=4.1.0 <5.0.0", 1188 | "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-4.2.1.tgz" 1189 | }, 1190 | "xtend": { 1191 | "version": "4.0.1", 1192 | "from": "xtend@>=4.0.0 <4.1.0", 1193 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz" 1194 | }, 1195 | "yallist": { 1196 | "version": "2.1.2", 1197 | "from": "yallist@>=2.0.0 <3.0.0", 1198 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz" 1199 | }, 1200 | "yeoman-environment": { 1201 | "version": "1.6.6", 1202 | "from": "yeoman-environment@>=1.1.0 <2.0.0", 1203 | "resolved": "https://registry.npmjs.org/yeoman-environment/-/yeoman-environment-1.6.6.tgz", 1204 | "dependencies": { 1205 | "glob": { 1206 | "version": "6.0.4", 1207 | "from": "glob@>=6.0.1 <7.0.0", 1208 | "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz" 1209 | }, 1210 | "globby": { 1211 | "version": "4.1.0", 1212 | "from": "globby@>=4.0.0 <5.0.0", 1213 | "resolved": "https://registry.npmjs.org/globby/-/globby-4.1.0.tgz" 1214 | }, 1215 | "object-assign": { 1216 | "version": "4.1.1", 1217 | "from": "object-assign@>=4.0.1 <5.0.0", 1218 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" 1219 | } 1220 | } 1221 | }, 1222 | "yeoman-generator": { 1223 | "version": "1.1.1", 1224 | "from": "yeoman-generator@>=1.1.1 <2.0.0", 1225 | "resolved": "https://registry.npmjs.org/yeoman-generator/-/yeoman-generator-1.1.1.tgz" 1226 | }, 1227 | "yosay": { 1228 | "version": "2.0.0", 1229 | "from": "yosay@>=2.0.0 <3.0.0", 1230 | "resolved": "https://registry.npmjs.org/yosay/-/yosay-2.0.0.tgz", 1231 | "dependencies": { 1232 | "ansi-styles": { 1233 | "version": "3.0.0", 1234 | "from": "ansi-styles@>=3.0.0 <4.0.0", 1235 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.0.0.tgz" 1236 | }, 1237 | "is-fullwidth-code-point": { 1238 | "version": "2.0.0", 1239 | "from": "is-fullwidth-code-point@>=2.0.0 <3.0.0", 1240 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz" 1241 | }, 1242 | "string-width": { 1243 | "version": "2.0.0", 1244 | "from": "string-width@>=2.0.0 <3.0.0", 1245 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.0.0.tgz" 1246 | } 1247 | } 1248 | } 1249 | } 1250 | } 1251 | --------------------------------------------------------------------------------