# App configuration
app:
  subGenerators:  # This is the order that the sub-generators should be executed in. Try not to couple these together
    - confit:buildBrowser
    - confit:paths
    - confit:buildAssets
    - confit:buildCSS
    - confit:buildJS
    - confit:buildHTML
    - confit:entryPoint
    - confit:serverDev
    - confit:serverProd
    - confit:testUnit
    - confit:testSystem
    - confit:testVisualRegression
    - confit:verify
    - confit:documentation
    - confit:release
    - confit:sampleApp
    - confit:zzfinish

  packages:
    - <<: *pkg_npm-run-all
    - <<: *pkg_rimraf
    - <<: *pkg_cross-env

  tasks:
    - name: start
      tasks: ['npm run dev']
      description: Alias for `npm run dev` task
      features:

    - name: dev
      tasks: ['cross-env NODE_ENV=development npm-run-all clean:dev --parallel verify:watch build:dev serve:dev']
      description: Run project in development mode (verify code, create dev build into <%= paths.output.devDir %> folder, serve on **<%= serverDev.protocol + '://' + serverDev.hostname + ':' + serverDev.port %>**, watch for changes and reload the browser automatically)
      features:

    - name: build
      tasks: ['cross-env NODE_ENV=production npm-run-all clean:prod build:prod']
      description: Generate production build into <%= link(paths.output.prodDir) %> folder
      features:

    - name: build:serve
      tasks: ['build', 'serve:prod']
      description: Generate production build and serve on **<%= serverProd.protocol + '://' + serverProd.hostname + ':' + serverProd.port %>**'
      features:

    - name: clean:dev
      tasks: ['rimraf <%= paths.output.devDir %>']
      description:
      features:

    - name: clean:prod
      tasks: ['rimraf <%= paths.output.prodDir %>']
      description:
      features:



# Frameworks are used by multiple generators
frameworks:
  '': # This is not really a framework. It represents the configuration needed when there IS NO framework.
    ES6:
      entryPointFileName: ./<%- resources.sampleApp.demoDir %>app.js
    TypeScript:
      entryPointFileName: ./<%- resources.sampleApp.demoDir %>app.ts
    frameworkPackages: {}
    frameworkTestPackages: {}

  AngularJS 1.x:
    ES6:
      entryPointFileName: ./<%- resources.sampleApp.demoDir %>app.js
    TypeScript:
      entryPointFileName: ./<%- resources.sampleApp.demoDir %>app.ts

    frameworkPackages: &ng1Packages
      packages:
        - <<: *pkg_angular
        - <<: *pkg_@types/angular
        - <<: *pkg_@types/angular-mocks

    frameworkTestPackages: &ng1TestPackages
      testPackages: # Test packages will be used *instead of* the framework packages, in the test harness!
        - <<: *pkg_angular
        - <<: *pkg_angular-mocks

  AngularJS 2.x:
    TypeScript:
      entryPointFileName: ./<%- resources.sampleApp.demoDir %>main.browser.ts
    frameworkPackages: &ng2Packages
      packages:   # All these files end up in the vendors bundle, created by the entryPoint buildTool
        - <<: *pkg_@angular/platform-browser
        - <<: *pkg_@angular/platform-browser-dynamic
        - <<: *pkg_@angular/compiler
        - <<: *pkg_@angular/core
        - <<: *pkg_@angular/common
        - <<: *pkg_rxjs/add/operator/map
        - <<: *pkg_rxjs/add/operator/mergeMap
        - <<: *pkg_core-js/es6/symbol     # Don't include es6/promise as it breaks zone.js
        - <<: *pkg_core-js/es6/object
        - <<: *pkg_core-js/es6/function
        - <<: *pkg_core-js/es6/parse-int
        - <<: *pkg_core-js/es6/parse-float
        - <<: *pkg_core-js/es6/number
        - <<: *pkg_core-js/es6/math
        - <<: *pkg_core-js/es6/string
        - <<: *pkg_core-js/es6/date
        - <<: *pkg_core-js/es6/array
        - <<: *pkg_core-js/es6/regexp
        - <<: *pkg_core-js/es6/map
        - <<: *pkg_core-js/es6/set
        - <<: *pkg_core-js/es6/weak-map
        - <<: *pkg_core-js/es6/weak-set
        - <<: *pkg_core-js/es6/typed
        - <<: *pkg_core-js/es6/reflect
        - <<: *pkg_core-js/es7/reflect
        - <<: *pkg_zone.js/dist/zone
        - <<: *pkg_ts-helpers

    frameworkTestPackages: &ng2TestPackages
      testPackages:  # Maps to Karma test.specs.js    https://github.com/AngularClass/angular2-webpack-starter/blob/master/config/spec-bundle.js
        - <<: *pkg_core-js/es6
        - <<: *pkg_core-js/es7/reflect
        - <<: *pkg_ts-helpers
        - <<: *pkg_zone.js/dist/zone
        - <<: *pkg_zone.js/dist/long-stack-trace-zone
        - <<: *pkg_zone.js/dist/proxy
        - <<: *pkg_zone.js/dist/sync-test
        - <<: *pkg_zone.js/dist/jasmine-patch
        - <<: *pkg_zone.js/dist/async-test
        - <<: *pkg_zone.js/dist/fake-async-test
        - <<: *pkg_rxjs/Rx
        # Angular2 source code is loaded by each component that is being tested. So no need to include Angular2 here.

  React (latest):
    ES6:
      entryPointFileName: ./<%- resources.sampleApp.demoDir %>app.jsx
    frameworkPackages: &reactPackages
      packages:
        - <<: *pkg_react
        - <<: *pkg_react-dom
    frameworkTestPackages: &reactTestPackages
      testPackages:
        - <<: *pkg_react
        - <<: *pkg_react-addons-test-utils
        - <<: *pkg_enzyme


buildAssets: {}

buildBrowser:
  defaults:
    browserSupport: ['latest']

  supportedBrowsers:
    latest:
      label: Latest Versions (major browsers)
      browserList: ['last 1 version']
    latest2:
      label: Latest 2 Versions (major browsers)
      browserList: ['last 2 versions']
    legacyIE:
      label: Legacy Internet Explorer (9, 10, 11)
      browserList: ['ie 9', 'ie 10', 'ie 11']
    legacyMobile:
      label: Legacy Mobile (Blackberry, Android Webview)
      browserList: ['bb', 'Android Webview']


# CSS configuration
buildCSS:
  defaults:
    sourceFormat: stylus

  sourceFormat:
    css:
      ext: ['css']
    sass:
      ext: ['sass', 'scss']
    stylus:
      ext: ['styl']

buildHTML: {}

buildJS:
  defaults:
    sourceFormat: ES6
    outputFormat: ES6
    # No default framework

  showVendorScripts: true     # Flag to indicate that whether the vendorScripts question in buildJS should be shown or not. Not used for Node projects.

  sourceFormat:
    ES6:
      ext: ['js', 'jsx']
    TypeScript:
      ext: ['ts']

  outputFormat:
    - ES5
    - ES6

  readme:
    extensionPoint:
      buildJS.frameworkScripts: >
        The `buildJS.frameworkScripts` array in <%= link(configFile) %> contains framework-specific scripts, and should not be modified.
        If a sample project is generated, the additional framework scripts needed by the sample app will also appear here.
        This property will be overwritten **every time** Confit is run.

      buildJS.vendorScripts: >
        The `buildJS.vendorScripts` array in <%= link(configFile) %> is designed to be edited manually.
        This property should contain NPM module names and/or references to JavaScript files (files must start with `./`).
        For example: `vendorScripts: ['jquery', './module/path/to/jsFile.js', 'moment/timezone',  ...]`

  configModules:
    - condition: <%- buildJS.sourceFormat === 'ES6' %>
      templateFiles:  # We need to use Babel EVEN when outputFormat is NOT ES5 so that browser unit testing works (as the new unit testing plugin is tied to Babel)
        - src: .babelrc.tpl
          dest: .babelrc
          overwrite: true
      packages:
        - <<: *pkg_babel-core
        #- <<: *pkg_babel-runtime          # TODO: This is the runtime for ES6 code - do we need this if we are not using the runtime-transform?
        - <<: *pkg_babel-preset-es2015
        #- <<: *pkg_babel-plugin-add-module-exports     # Generate the "default" export when using Babel 6: http://stackoverflow.com/questions/34736771/webpack-umd-library-return-object-default
                                                        # This causes issues for Angular 1 sampleApp.
      tasks: []

    - condition: <%- buildJS.sourceFormat === 'TypeScript' %>
      packages:
        - <<: *pkg_typescript
        - <<: *pkg_@types/node
      templateFiles:
        - src: tsconfig.json.tpl
          dest: tsconfig.json
          overwrite: true

    - condition: <%- buildJS.framework.indexOf('AngularJS 1.x') > -1 %>
      <<: *ng1Packages

    - condition: <%- buildJS.framework.indexOf('AngularJS 2.x') > -1 %>
      <<: *ng2Packages

    - condition: <%- buildJS.framework.indexOf('React (latest)') > -1 %>
      <<: *reactPackages

    - condition: <%- buildJS.framework.indexOf('React (latest)') > -1 %>
      packages:
        - <<: *pkg_babel-preset-react-app
        - <<: *pkg_eslint-config-react-app
        - <<: *pkg_eslint-plugin-import
        - <<: *pkg_eslint-plugin-jsx-a11y
        - <<: *pkg_eslint-plugin-react


entryPoint:
  readme:
    extensionPoint:
      entryPoint: >
        The `entryPoint.entryPoints` object in <%= link(configFile) %> is designed to be edited manually.
        It represents the starting-point(s) of the application (like a `main()` function). Normally an application has
        one entry point, but it is possible to have more than one.
        `entryPoint.entryPoints` must have at-least one property (e.g. `property: [file]`), where `file` is a list
        of NPM module names and/or references to JavaScript files (file references must start with `./`);

# Path Defaults
paths:
  prompts:
    - name: input.srcDir
      heading: |
        Source-code paths

      message: Path to SOURCE directory (relative to the current directory)

    - name: input.modulesSubDir
      message: Path to MODULES directory (relative to the SOURCE directory)

    - name: input.assetsDir
      message: Name of module ASSETS directory (for images, fonts)

    - name: input.stylesDir
      message: Name of module STYLES directory (for CSS)

    - name: input.templateDir
      message: Name of module TEMPLATE directory (for component HTML templates)

    - name: input.unitTestDir
      message: Name of module UNIT TEST directory

    - name: input.systemTestDir
      message: Name of module SYSTEM TEST (browser test) directory

    - name: output.devDir
      heading: |
        Output paths

      message: Path to DEV OUTPUT directory (relative to the current directory)

    - name: output.prodDir
      message: Path to PRODUCTION OUTPUT directory (relative to the current directory)

    - name: output.assetsSubDir
      message: Path to ASSETS sub-directory (relative to the OUTPUT directory)

    - name: output.cssSubDir
      message: Path to CSS sub-directory (relative to the OUTPUT directory)

    - name: output.jsSubDir
      message: Path to JS sub-directory (relative to OUTPUT directory)

    - name: output.vendorJSSubDir
      message: Path to VENDOR JS libraries sub-directory (relative to OUTPUT directory)

    - name: output.reportDir
      message: Path to TEST REPORTS directory (relative to the current directory)

    - name: config.configDir
      heading: |
        Config paths

      message: Path to CONFIG directory (relative to the current directory)

  defaults:
    input:
      srcDir: src/
      modulesSubDir: modules/
      assetsDir: assets/
      stylesDir: styles/
      templateDir: template/
      unitTestDir: unitTest/
      systemTestDir: systemTest/
      testDir: test/
    output:
      devDir: dev/
      prodDir: dist/
      assetsSubDir: assets/
      cssSubDir: css/
      jsSubDir: js/
      vendorJSSubDir: vendor/
      reportDir: reports/
    config:
      configDir: config/

  pathsToGenerate:
    - name: input.modulesDir
      value: <%- paths.input.srcDir + '/' + paths.input.modulesSubDir %>


# README section for the template tags that will appear inside the README.md template
readme:
  RM_DIR_STRUCTURE: |
    ## Directory Structure

    Code is organised into modules which contain one-or-more components. This a great way to ensure maintainable code by encapsulation of behavior logic. A component is basically a self contained app usually in a single file or a folder with each concern as a file: style, template, specs, e2e, and component class. Here's how it looks:
    ```<% var maxDirLen = 30; %>
    <%- pkg.name %>/
     ├──<%- rpad(paths.config.configDir, maxDirLen)%>* configuration files live here (e.g. webpack, <%- resources.documentation.configSubDir %>, <%- resources.testSystem.configSubDir %>, <%- resources.testUnit.configSubDir %>, <%- resources.testVisualRegression.configSubDir %>, <%- resources.verify.configSubDir %>)
     │
     ├──<%- rpad(paths.input.srcDir, maxDirLen) %>* source code files should be here
     │   └──<%- rpad(paths.input.modulesSubDir, maxDirLen - 4) %>* all source code modules|components|features should appear as sub-directories under this directory
     │       ├──<%- rpad('common/', maxDirLen - 8) %>
     │       ├──<%- rpad('featureA/', maxDirLen - 8) %>
     │       └──<%- rpad('featureB/', maxDirLen - 8) %>
     │           ├──<%- rpad(paths.input.assetsDir, maxDirLen - 12) %>
     │           │   ├──<%- rpad('font', maxDirLen - 16) %>* fonts for this module
     │           │   └──<%- rpad('img', maxDirLen - 16) %>* images for this module
     │           ├──<%- rpad(paths.input.stylesDir, maxDirLen - 12) %>* css source code for this module
     │           ├──<%- rpad(paths.input.templateDir, maxDirLen - 12) %>* HTML templates for this module
     │           ├──<%- rpad(paths.input.systemTestDir, maxDirLen - 12) %>* system test specs for this module
     │           ├──<%- rpad(paths.input.unitTestDir, maxDirLen - 12) %>* unit test specs for this module
     │           └──<%- rpad(testVisualRegression.moduleTestDir, maxDirLen - 12) %>* visual regression test specs for this module (if enabled)
     │
     ├──<%- rpad(paths.output.devDir, maxDirLen) %>* development-build code is output here (Webpack may keep it in memory for speed)
     ├──<%- rpad(paths.output.prodDir, maxDirLen) %>* production-build code is output here
     │   ├──<%- rpad(paths.output.assetsSubDir, maxDirLen - 4) %>* all assets appear here, under module sub-folders. e.g.:
     │   │   └──<%- rpad('featureB/', maxDirLen - 8) %>
     │   │       ├──<%- rpad('font', maxDirLen - 12) %>
     │   │       └──<%- rpad('img', maxDirLen - 12) %>
     │   ├──<%- rpad(paths.output.cssSubDir, maxDirLen - 4) %>* compiled CSS files
     │   ├──<%- rpad(paths.output.jsSubDir, maxDirLen - 4) %>* minified JS files
     │   └──<%- rpad(paths.output.vendorJSSubDir, maxDirLen - 4) %>* minified vendor JS files
     │
     ├──<%- rpad(paths.output.reportDir, maxDirLen) %>* test reports appear here<% if (documentation.generateDocs) { %>
     │
     ├──<%- rpad(documentation.srcDir, maxDirLen) %>* source/content for the documentation website goes here
     ├──<%- rpad(documentation.outputDir, maxDirLen) %>* the documentation website is generated here<% } %>
     │
     ├──<%- rpad(testVisualRegression.referenceImageDir, maxDirLen) %>* visual regression testing reference images (if enabled)
     │
     ├──<%- rpad(configFile, maxDirLen) %>* the project config file generated by 'yo confit'
     ├──<%- rpad('CONTRIBUTING.md', maxDirLen) %>* how to contribute to the project
     ├──<%- rpad('README.md', maxDirLen) %>* this file
     └──<%- rpad('package.json', maxDirLen) %>* NPM package description file
    ```

  RM_NEXT_STEPS: |
    ## *Next Steps to Setup your Project*

        Remove this section once you are comfortable updating your project.

    - [ ] Update [package.json](package.json) with a nice description, then run `yo confit --skip-install --skip-run` and see the README.md file is updated
    - [ ] Add a new **dependency** to your project:
      - For a **source-code** dependency:
        1. `npm i {nodeModule} --save`
        1. Edit <%- link(configFile) %> and include {nodeModule} as an item inside the `buildJS.vendorScripts` array
        1. `yo confit` to regenerate your build configuration
      - For a **development** dependency:
        1. `npm i {nodeModule} --save-dev`
        1. Edit the configuration file(s) that will need to use this dependency in the areas of the file that will not be overwritten when `yo confit` is run.
         For example:
         ```js

         // Changes in this region will be preserved.

         // START_CONFIT_GENERATED_CONTENT

           // Changes in this region will be overwritten if `yo confit` is run again.

         // END_CONFIT_GENERATED_CONTENT

         // Changes in this region will be preserved.

         ```
      - For a **test** dependency:
        1. `npm i {nodeModule} --save`
        1. Edit <%- link(configFile) %> and include {nodeModule} as an item inside the `testUnit.testDependencies` array
        1. Run `yo confit` to regenerate your build configuration
    <% if (release.useSemantic) { %>- [ ] Complete the installation of the **semantic release** tool:
      1. Make sure you have:
        - a GitHub login
        - an NPM login
        - a TravisCI login (though you can still proceed if you use a different CI tool)
      1. Run `semantic-release-cli setup` to complete the installation
    <% } -%>
    <% if (release.checkCodeCoverage && app.repositoryType === 'GitHub') { %>- [ ] Install code coverage:
      1. Make sure you have:
        - a TravisCI login (though you can still proceed if you use a different CI tool)
        - a [Coveralls](https://coveralls.io) account
      1. Push your code to GitHub.
      1. Login to [Coveralls](https://coveralls.io/).
      1. Press Add Repo. You may need to Sync your GitHub repos to see your new repo in the list.
      1. Select the repo and you will see a "Set Up Coveralls" page. Note the `repo_token` value.
      1. Login to [Travis CI](https://travis-ci.org/).
      1. Edit the settings for this repo (More Settings > Settings).
      1. In the Environment Variables section, create a new envrionment variable called `COVERALLS_REPO_TOKEN` and set its value to the *repo_token* value shown on the "Set Up Coveralls" page, and press "Add".
      1. Push another commit to GitHub and you should get a coverage report now!
    <% } -%>
    - [ ] Add a new module to `<%- paths.input.modulesDir %>`
    - [ ] Run `npm start`, change the stylesheet and see the changes appear immediately
    - [ ] Run `npm test` to execute the unit tests and see the test coverage
    - [ ] Run `npm start && test:system` to execute the browser tests
    <% if (release.commitMessageFormat === 'Conventional') { %>- [ ] Run `git cz` to commit changes with a conventional commit message
    <% } -%>



# Sample App
sampleApp:
  # There is a problem in eslintignore.yml.tpl whereby we want to refer to sampleApp.deomDir, but this variable also contains an EJS template
  # To work around this issue, we change eslintignore.yml.tpl to have a 'browser' and 'node' version of the directory to ignore.
  # This is not ideal, but less evil than changing all the generators to support this use-case.
  demoDirName: demoModule/
  demoDir: <%= paths.input.modulesSubDir %>demoModule/

  # Master config
  templateFiles:
    - src: assets/**/*
      dest: <%- paths.input.srcDir + resources.sampleApp.demoDir + paths.input.assetsDir %>
      overwrite: true
      noParse: true
    - src: systemTest/*
      dest: <%- paths.input.srcDir + resources.sampleApp.demoDir + paths.input.systemTestDir %>
      overwrite: true
      noParse: true

  configModules:
    - condition: <%= buildCSS.sourceFormat === 'css' %>
      templateFiles:
        - src: css/app.css
          dest: <%- paths.input.srcDir + resources.sampleApp.demoDir + paths.input.stylesDir %>app.css
          overwrite: true
        - src: css/iconFont.css
          dest: <%- paths.input.srcDir + resources.sampleApp.demoDir + paths.input.stylesDir %>iconFont.css
          overwrite: true

    - condition: <%= buildCSS.sourceFormat === 'sass' %>
      templateFiles:
        - src: css/app.sass
          dest: <%- paths.input.srcDir + resources.sampleApp.demoDir + paths.input.stylesDir %>app.sass
          overwrite: true
        - src: css/iconFont.css
          dest: <%- paths.input.srcDir + resources.sampleApp.demoDir + paths.input.stylesDir %>iconFont.css
          overwrite: true

    - condition: <%= buildCSS.sourceFormat === 'stylus' %>
      templateFiles:
        - src: css/app.styl
          dest: <%- paths.input.srcDir + resources.sampleApp.demoDir + paths.input.stylesDir %>app.styl
          overwrite: true
        - src: css/iconFont.css
          dest: <%- paths.input.srcDir + resources.sampleApp.demoDir + paths.input.stylesDir %>iconFont.css
          overwrite: true

    - condition: <%= testVisualRegression.enabled === true %>
      templateFiles:
        - src: visualTest/*
          dest: <%- paths.input.srcDir + resources.sampleApp.demoDir + testVisualRegression.moduleTestDir %>
          overwrite: true
          noParse: true

  # The SampleApp build tool needs to know what the entrypoint file name is.
  cssSourceFormat:
    css:
      entryPointFileNames:
        - app.css
    sass:
      entryPointFileNames:
        - app.sass
    stylus:
      entryPointFileNames:
        - app.styl



# Server - Development
serverDev:
  defaults:
    port: 3000
    hostname: localhost
    protocol: https


serverProd:
  defaults:
    port: 3000
    hostname: localhost
    protocol: https


testSystem: {}

testUnit:
  defaults:
    testFramework: jasmine

  testFrameworks:
    - jasmine
    - mocha

  configModules:
    - condition: <%- buildJS.framework.indexOf('AngularJS 1.x') > -1 %>
      <<: *ng1TestPackages

    - condition: <%- buildJS.framework.indexOf('AngularJS 2.x') > -1 %>
      <<: *ng2TestPackages

    - condition: <%- buildJS.framework.indexOf('React (latest)') > -1 %>
      <<: *reactTestPackages


testVisualRegression: {}


verify:
  verifyTasks: ['verify:js', 'verify:css']

  configModules:
    - packages:   # Common tools
        - <<: *pkg_eslint
        - <<: *pkg_babel-eslint     # We may not need this in the near future. ESLint can parse ES6 & ES7 things
        - <<: *pkg_eslint-friendly-formatter
      templateFiles:
        - src: eslintignore.yml.tpl
          dest: .eslintignore
          overwrite: true
        - src: .eslintrc.js.tpl
          dest: <%= paths.config.configDir + resources.verify.configSubDir %>.eslintrc.js
          overwrite: true

    - condition: <%- verify.jsCodingStandard === 'AirBnB' %>
      packages:
        - <<: *pkg_eslint-config-airbnb
        - <<: *pkg_eslint-plugin-import
        - <<: *pkg_eslint-plugin-react
        - <<: *pkg_eslint-plugin-jsx-a11y

    - condition: <%- verify.jsCodingStandard === 'Google' %>
      packages:
        - <<: *pkg_eslint-config-google

    - condition: <%- verify.jsCodingStandard === 'StandardJS' %>
      packages:
        - <<: *pkg_eslint-config-standard
        - <<: *pkg_eslint-plugin-standard
        - <<: *pkg_eslint-plugin-promise
        - <<: *pkg_eslint-plugin-import
        - <<: *pkg_eslint-plugin-node

    - condition: <%- verify.jsCodingStandard === 'TypeScript' %>
      packages:
        - <<: *pkg_tslint
      templateFiles:
        - src: tslint.json
          dest: <%= paths.config.configDir + resources.verify.configSubDir %>tslint.json

    - condition: <%- buildCSS.sourceFormat === 'sass' %>
      # No packages to install, as the build-tools will have their own
      templateFiles:
        - src: sasslint.yml
          dest: <%= paths.config.configDir + resources.verify.configSubDir %>sasslint.yml

    - condition: <%- buildCSS.sourceFormat === 'stylus' %>
      # No packages to install, as the build-tools will have their own
      templateFiles:
        - src: stylintrc
          dest: <%= paths.config.configDir + resources.verify.configSubDir %>.stylintrc

zzfinish:
  # For browser projects, after installation, start the project
  onEnd:
    - cmd: npm
      args: ['start']
