├── .bowerrc ├── .editorconfig ├── .ember-cli ├── .gitignore ├── .travis.yml ├── Brocfile.js ├── README.md ├── addon └── .gitkeep ├── app └── .gitkeep ├── bower.json ├── config └── environment.js ├── index.js ├── lib ├── commands │ ├── depodify.js │ └── podify.js └── tasks │ └── generate-file-list.js ├── package.json ├── podify_spec.md ├── testem.json ├── tests ├── .jshintrc ├── dummy │ ├── .jshintrc │ ├── app │ │ ├── app.js │ │ ├── components │ │ │ └── .gitkeep │ │ ├── controllers │ │ │ └── .gitkeep │ │ ├── helpers │ │ │ └── .gitkeep │ │ ├── index.html │ │ ├── models │ │ │ └── .gitkeep │ │ ├── router.js │ │ ├── routes │ │ │ └── .gitkeep │ │ ├── styles │ │ │ ├── .gitkeep │ │ │ └── app.css │ │ ├── templates │ │ │ ├── .gitkeep │ │ │ ├── application.hbs │ │ │ └── components │ │ │ │ └── .gitkeep │ │ └── views │ │ │ └── .gitkeep │ ├── config │ │ └── environment.js │ └── public │ │ ├── .gitkeep │ │ ├── crossdomain.xml │ │ └── robots.txt ├── helpers │ ├── resolver.js │ └── start-app.js ├── index.html ├── test-helper.js └── unit │ └── .gitkeep └── vendor └── .gitkeep /.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "bower_components", 3 | "analytics": false 4 | } 5 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | 8 | [*] 9 | end_of_line = lf 10 | charset = utf-8 11 | trim_trailing_whitespace = true 12 | insert_final_newline = true 13 | indent_style = space 14 | indent_size = 2 15 | 16 | [*.js] 17 | indent_style = space 18 | indent_size = 2 19 | 20 | [*.hbs] 21 | indent_style = space 22 | indent_size = 2 23 | 24 | [*.css] 25 | indent_style = space 26 | indent_size = 2 27 | 28 | [*.html] 29 | indent_style = space 30 | indent_size = 2 31 | 32 | [*.md] 33 | trim_trailing_whitespace = false 34 | -------------------------------------------------------------------------------- /.ember-cli: -------------------------------------------------------------------------------- 1 | { 2 | /** 3 | Ember CLI sends analytics information by default. The data is completely 4 | anonymous, but there are times when you might want to disable this behavior. 5 | 6 | Setting `disableAnalytics` to true will prevent any data from being sent. 7 | */ 8 | "disableAnalytics": false 9 | } 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | 7 | # dependencies 8 | /node_modules 9 | /bower_components 10 | 11 | # misc 12 | /.sass-cache 13 | /connect.lock 14 | /coverage/* 15 | /libpeerconnection.log 16 | npm-debug.log 17 | testem.log 18 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | language: node_js 3 | 4 | sudo: false 5 | 6 | cache: 7 | directories: 8 | - node_modules 9 | 10 | before_install: 11 | - "npm config set spin false" 12 | - "npm install -g npm@^2" 13 | 14 | install: 15 | - npm install -g bower 16 | - npm install 17 | - bower install 18 | 19 | script: 20 | - npm test 21 | -------------------------------------------------------------------------------- /Brocfile.js: -------------------------------------------------------------------------------- 1 | /* global require, module */ 2 | 3 | var EmberAddon = require('ember-cli/lib/broccoli/ember-addon'); 4 | 5 | var app = new EmberAddon(); 6 | 7 | // Use `app.import` to add additional libraries to the generated 8 | // output files. 9 | // 10 | // If you need to use different assets in different 11 | // environments, specify an object as the first parameter. That 12 | // object's keys should be the environment name and the values 13 | // should be the asset to use in that environment. 14 | // 15 | // If the library that you are including contains AMD or ES6 16 | // modules that you would like to import into your application 17 | // please specify an object with the list of modules as keys 18 | // along with the exports of each module as its value. 19 | 20 | module.exports = app.toTree(); 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ember-cli-podify 2 | 3 | ## This addon has been deprecated and is no longer maintained. Pods are not recommended in ember-cli, instead the [new module unification](https://github.com/emberjs/rfcs/blob/master/text/0143-module-unification.md) structure should be used when it is ready. 4 | -------------------------------------------------------------------------------- /addon/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trabus/ember-cli-podify/b00e26c562a15903a9df04663a6f0c6548db2282/addon/.gitkeep -------------------------------------------------------------------------------- /app/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trabus/ember-cli-podify/b00e26c562a15903a9df04663a6f0c6548db2282/app/.gitkeep -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ember-cli-podify", 3 | "dependencies": { 4 | "handlebars": "~1.3.0", 5 | "jquery": "^1.11.1", 6 | "ember": "1.8.1", 7 | "ember-data": "1.0.0-beta.11", 8 | "ember-resolver": "~0.1.10", 9 | "loader.js": "stefanpenner/loader.js#1.0.1", 10 | "ember-cli-shims": "stefanpenner/ember-cli-shims#0.0.3", 11 | "ember-cli-test-loader": "rwjblue/ember-cli-test-loader#0.0.4", 12 | "ember-load-initializers": "stefanpenner/ember-load-initializers#0.0.2", 13 | "ember-qunit": "0.1.8", 14 | "ember-qunit-notifications": "0.0.4", 15 | "qunit": "~1.15.0" 16 | } 17 | } -------------------------------------------------------------------------------- /config/environment.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(/* environment, appConfig */) { 4 | return { }; 5 | }; 6 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | name: 'ember-cli-podify', 3 | includedCommands: function() { 4 | return { 5 | 'podify': require('./lib/commands/podify'), 6 | 'depodify': require('./lib/commands/depodify') 7 | } 8 | } 9 | } 10 | /* 11 | returns files for defined path 12 | */ 13 | function files(){ 14 | 15 | } 16 | -------------------------------------------------------------------------------- /lib/commands/depodify.js: -------------------------------------------------------------------------------- 1 | var GenerateFileList = require('../tasks/generate-file-list'); 2 | var merge = require('lodash-node/modern/objects/merge'); 3 | 4 | module.exports = { 5 | name: 'depodify', 6 | aliases: ['depod','dp'], 7 | works: 'insideProject', 8 | availableOptions: [ 9 | { name: 'dry-run', type: Boolean, default: false, aliases: ['d'] } 10 | ], 11 | 12 | run: function(commandOptions, rawArgs) { 13 | console.log('running depodify'); 14 | 15 | var task = new GenerateFileList({ 16 | ui: this.ui, 17 | analytics: this.analytics, 18 | project: this.project, 19 | testing: this.testing 20 | }); 21 | 22 | var taskArgs = { 23 | args: rawArgs, 24 | targetFiles: rawArgs || '', 25 | ignored: commandOptions.ignore || [], 26 | operation: 'depodify' 27 | }; 28 | 29 | var taskOptions = merge(taskArgs, commandOptions || {}); 30 | // console.log(taskOptions); 31 | return task.run(commandOptions,taskOptions); 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /lib/commands/podify.js: -------------------------------------------------------------------------------- 1 | var GenerateFileList = require('../tasks/generate-file-list'); 2 | var merge = require('lodash-node/modern/objects/merge'); 3 | 4 | module.exports = { 5 | name: 'podify', 6 | description: 'Converts files into pod structure.', 7 | aliases: ['pod','pf'], 8 | works: 'insideProject', 9 | availableOptions: [ 10 | { name: 'dry-run', type: Boolean, default: false, aliases: ['d'] }, 11 | { name: 'ignore', type: Array, default: [], aliases: ['i']} 12 | ], 13 | anonymousOptions: [ 14 | '' 15 | ], 16 | run: function(commandOptions, rawArgs) { 17 | console.log('running podify'); 18 | var task = new GenerateFileList({ 19 | ui: this.ui, 20 | analytics: this.analytics, 21 | project: this.project, 22 | testing: this.testing 23 | }); 24 | 25 | var taskArgs = { 26 | args: rawArgs, 27 | targetFiles: rawArgs || '', 28 | ignored: commandOptions.ignore || [], 29 | operation: 'podify' 30 | }; 31 | 32 | var taskOptions = merge(taskArgs, commandOptions || {}); 33 | console.log(taskOptions); 34 | return task.run(commandOptions, taskOptions); 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /lib/tasks/generate-file-list.js: -------------------------------------------------------------------------------- 1 | var Blueprint = require('ember-cli/lib/models/blueprint'); 2 | var FileInfo = require('ember-cli/lib/models/file-info'); 3 | var Task = require('ember-cli/lib/models/task'); 4 | var Promise = require('ember-cli/lib/ext/promise'); 5 | var walkSync = require('walk-sync'); 6 | var path = require('path'); 7 | var fs = require('fs-extra'); 8 | var inflector = require('inflection'); 9 | var without = require('lodash-node/modern/arrays/without'); 10 | var filter = require('lodash-node/modern/collections/filter'); 11 | var chalk = require('chalk'); 12 | var nodeMkdirp =require('mkdirp'); 13 | var rename = Promise.denodeify(fs.rename); 14 | var rmdir = Promise.denodeify(fs.rmdir); 15 | var mkdirp = Promise.denodeify(nodeMkdirp); 16 | 17 | module.exports = Task.extend({ 18 | run: function(commandOptions, options) { 19 | // console.log('Running task: generate-file-list, operation:', options.operation); 20 | this.operation = options.operation; 21 | this.appPath = path.join(this.project.root,"app"); 22 | this.testPath = path.join(this.project.root,"tests"); 23 | this.ignoredTypes = options.ignored; 24 | //this.getPodBlueprints(); 25 | var files = this.files("app"); 26 | // console.log(options); 27 | // this.ui.writeLine(this.operation); 28 | // console.log(this.appPath,this.project.pkg); 29 | // console.log('files',files); 30 | if (options.dryRun) { 31 | this.ui.writeLine(chalk.yellow('You specified the dry-run flag, so no changes will be written.')); 32 | } 33 | 34 | var fileInfos = files.map(this.buildFileInfo.bind(this, "app")); 35 | fileInfos = without(fileInfos,undefined); 36 | // console.log(fileInfos); 37 | var operations = fileInfos.map(this.buildFileOperation.bind(this)); 38 | // console.log(operations); 39 | operations = filter(operations,{operation:this.operation}); 40 | // console.log('operations:',operations); 41 | return Promise.resolve(operations) 42 | .map(this.processFile.bind(this, options)) 43 | .then(function(result){ 44 | // console.log(result); 45 | if (options.dryRun) { 46 | this.ui.writeLine(chalk.yellow('Run of ' + options.operation + ' dry run complete. No changes were written.')); 47 | } 48 | return result; 49 | }.bind(this)); 50 | }, 51 | 52 | files: function(file) { 53 | var filePath = path.join(this.project.root,file); 54 | if(fs.existsSync(filePath)) { 55 | return walkSync(filePath); 56 | } 57 | }, 58 | 59 | /* 60 | Build file info object for processing 61 | */ 62 | buildFileInfo: function(file, filePath) { 63 | // process each file to get info for later processing 64 | /* 65 | * rename all files in hash 66 | * get podModulePrefix from config 67 | * match(/podModulePrefix/); 68 | * get root path 69 | * get type of blueprint 70 | * extract properties for renaming 71 | * type 72 | * root path 73 | * resource path 74 | * extension 75 | */ 76 | var podlist = this.getPodBlueprints(); 77 | var originPath = path.resolve(this.project.root, file, filePath); 78 | var isFile = fs.statSync(originPath).isFile(); 79 | var segments = filePath.split('/'); 80 | var fileName = segments[segments.length - 1].split('.'); 81 | var extension = fileName[1]; 82 | var isIgnoredFile = this.getIgnoredFiles().indexOf(fileName[1]) !== -1; 83 | var type, paths, pathName; 84 | // console.log(fileName, this.getIgnoredFiles().indexOf(fileName[1])); 85 | // console.log('type',type, segments.length); 86 | segments[segments.length - 1] = fileName[0]; 87 | segments.some(function(segment){ 88 | var item = inflector.singularize(segment); 89 | if(podlist.indexOf(item) !== -1){ 90 | type = item; 91 | } 92 | return type === item; 93 | }); 94 | // TODO: find a better way to detect type than this temporary fix for component templates 95 | if (extension === 'hbs') { 96 | type = 'template'; 97 | } 98 | segments = without(segments, 'pods'); 99 | if(isFile && !isIgnoredFile && !this.isIgnoredType(type) && segments.length > 1 && type !== undefined){ 100 | // console.log('processing:',filePath); 101 | paths = segments.map(function(segment){ 102 | var item = inflector.singularize(segment); 103 | if(podlist.indexOf(item) !== -1){ 104 | return ''; 105 | } else { 106 | return segment; 107 | } 108 | }); 109 | paths = without(paths, ''); 110 | return { 111 | root: this.project.root, 112 | base: file, 113 | segments: segments, 114 | pathName: paths.join('/'), 115 | extension: extension, 116 | type: type, 117 | pod: type === segments.slice(-1)[0], 118 | originPath: originPath, 119 | isComponent: originPath.match(/component/) 120 | }; 121 | } 122 | }, 123 | 124 | buildFileOperation: function(file) { 125 | var filepath = outputPath(file); 126 | var output = { 127 | type: file.type, 128 | filename: file.pathName, 129 | inputPath: file.originPath, 130 | outputPath: outputPath(file), 131 | outputDir: outputDir(filepath), 132 | inputDir: inputDir(file) 133 | }; 134 | if(file.pod){ 135 | output.operation = 'depodify'; 136 | } else { 137 | output.operation = 'podify'; 138 | } 139 | return output; 140 | }, 141 | 142 | processFile: function(options, file) { 143 | // console.log('file',file); 144 | // console.log('options',options) 145 | // console.log('renaming:', file.type, file.filename); 146 | // console.log('isFile:',fs.statSync(file.inputPath).isFile(),(file.inputPath === file.originPath)); 147 | // console.log(file); 148 | var outputDir = file.outputDir; 149 | if (!fs.existsSync(file.outputDir)) { 150 | // console.log('nodir ',file.outputDir); 151 | } 152 | if (options.dryRun) { 153 | outputDir = ''; 154 | } 155 | return mkdirp(outputDir) 156 | .then(function(){ 157 | console.log(outputDir); 158 | this.ui.writeLine(chalk.green('renaming file: ') + '\'' + file.inputPath + '\' to ' + chalk.green('\'' + file.outputPath + '\'')); 159 | if(options.dryRun) { 160 | return true; 161 | } else { 162 | return rename(file.inputPath,file.outputPath); 163 | } 164 | }.bind(this)) 165 | .then(function(){ 166 | this.ui.writeLine(chalk.red('deleting empty directory: ' + file.inputDir)); 167 | // console.log('deleting dir:',file.inputDir); 168 | if(options.dryRun) { 169 | return true; 170 | } else { 171 | return rmdir(file.inputDir); 172 | } 173 | }.bind(this)) 174 | .catch(function(err){ 175 | //console.log(err); 176 | //this.ui.writeLine(chalk.red('deleting directory failed: ' + err.path)); 177 | return true; 178 | }.bind(this)); 179 | }, 180 | 181 | getPodBlueprints: function(options) { 182 | // fake list for now 183 | return [ 184 | 'adapter', 185 | 'controller', 186 | 'component', 187 | 'model', 188 | 'resource', 189 | 'route', 190 | 'serializer', 191 | 'template', 192 | 'transform', 193 | 'view' 194 | ]; 195 | /* 196 | var lookupPaths = this.project.blueprintLookupPaths(); 197 | var blueprintList = Blueprint.list({ paths: lookupPaths }); 198 | // loop through list 199 | console.log(lookupPaths); 200 | //console.log(blueprintList); 201 | var path; 202 | blueprintList.forEach(function(collection){ 203 | // console.log(collection.blueprints); 204 | collection.blueprints.forEach(function(blueprint){ 205 | if(blueprint && blueprint.name){ 206 | //console.log(blueprint); 207 | //console.log(blueprint.name); 208 | try { 209 | path = blueprint.files().join(); 210 | if(path.match(/__path__/)) { 211 | console.log(blueprint.name); 212 | } 213 | } 214 | catch(e){ 215 | console.log('error',e); 216 | } 217 | 218 | } 219 | }); 220 | }); 221 | */ 222 | }, 223 | 224 | getIgnoredFiles: function() { 225 | return [ 226 | 'DS_Store', 227 | 'gitkeep' 228 | ]; 229 | }, 230 | 231 | isIgnoredType: function(type) { 232 | return this.ignoredTypes.indexOf(type) !== -1; 233 | } 234 | }); 235 | 236 | function inputDir(file) { 237 | return file.originPath.split('/').slice(0,-1).join('/'); 238 | } 239 | 240 | function outputPath(file) { 241 | // if file is already pod 242 | var subpath = ''; 243 | if (file.pod) { 244 | // if the file is a template 245 | if(file.type === 'template' && file.isComponent) { 246 | subpath = 'components'; 247 | } 248 | // 249 | return path.join(file.root, file.base, inflector.pluralize(file.type), subpath, file.pathName + '.' + file.extension); 250 | } else { 251 | var podpath = 'pods'; 252 | if(file.type === 'component') { 253 | podpath += '/' + inflector.pluralize(file.type); 254 | } 255 | if(file.type === 'template' && file.isComponent) { 256 | subpath = 'components'; 257 | } 258 | return path.join(file.root, file.base, podpath, subpath, file.pathName, file.type + '.' + file.extension); 259 | } 260 | } 261 | 262 | function outputDir(filePath) { 263 | // console.log('filepath',filePath,filePath.split('/').slice(0,-1).join('/')); 264 | return filePath.split('/').slice(0,-1).join('/'); 265 | } 266 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ember-cli-podify", 3 | "version": "0.0.0", 4 | "directories": { 5 | "doc": "doc", 6 | "test": "tests" 7 | }, 8 | "scripts": { 9 | "start": "ember server", 10 | "build": "ember build", 11 | "test": "ember test" 12 | }, 13 | "repository": "", 14 | "engines": { 15 | "node": ">= 0.10.0" 16 | }, 17 | "author": "", 18 | "license": "MIT", 19 | "devDependencies": { 20 | "body-parser": "^1.2.0", 21 | "broccoli-asset-rev": "0.3.1", 22 | "broccoli-ember-hbs-template-compiler": "^1.6.1", 23 | "chalk": "^0.5.1", 24 | "ember-cli": "0.1.2", 25 | "ember-cli-content-security-policy": "0.3.0", 26 | "ember-cli-dependency-checker": "0.0.6", 27 | "ember-cli-esnext": "0.1.1", 28 | "ember-cli-ic-ajax": "0.1.1", 29 | "ember-cli-inject-live-reload": "^1.3.0", 30 | "ember-cli-qunit": "0.1.0", 31 | "ember-data": "1.0.0-beta.11", 32 | "ember-export-application-global": "^1.0.0", 33 | "express": "^4.8.5", 34 | "glob": "^4.0.5", 35 | "inflection": "^1.5.3", 36 | "lodash-node": "^2.4.1", 37 | "mkdirp": "^0.5.0" 38 | }, 39 | "description": "The default blueprint for ember-cli addons.", 40 | "keywords": [ 41 | "ember-addon" 42 | ], 43 | "ember-addon": { 44 | "configPath": "tests/dummy/config" 45 | }, 46 | "dependencies": { 47 | "fs-extra": "^0.12.0", 48 | "path": "^0.4.9", 49 | "walk-sync": "^0.1.3", 50 | "rsvp": "3.0.16" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /podify_spec.md: -------------------------------------------------------------------------------- 1 | ## Pod conversion utility 2 | As an ember-cli application grows, a user may choose to convert their app from the default structure to use pods. Converting assets into a pod structure can be time consuming and error-prone. By providing an automated conversion command, a user could convert an entire application to pod structure (and back) in one command. 3 | 4 | Because the two structures are known, transformation between the two should be a relatively simple task. The primary concern is changing between the two without side effects. 5 | 6 | ### Command specs 7 | The command(s) should work with or without arguments. When no argument is passed, the entire app will be scanned for resources that can be converted. When an arguments are passed, the resources named will converted. 8 | 9 | If a resource already has assets in the format to be converted to, the command will pass over the resource. 10 | 11 | ### Command process 12 | Process steps: 13 | 14 | * identify files to process 15 | * get all files in relevant folders (app, tests, bundles) 16 | * ignore folders for types that don't support pods 17 | * use lookupBlueprints to find folders that have a `__path__` token to get list 18 | * filter using _.intersect() from glob in command arguments 19 | * if no files are matched, nothing is processed (abort) 20 | * if files that don't support pods are matched, ignore and move on 21 | * create hash of files to process 22 | * group files by name/path 23 | * for example all `user` or `users/profile/edit` files 24 | * route 25 | * template 26 | * controller 27 | * maintain path from root level, so we can accomodate test folder too 28 | * rename all files in hash 29 | * get podModulePrefix from config 30 | * match(/podModulePrefix/); 31 | * get root path 32 | * get type of blueprint 33 | * extract properties for transform 34 | * type 35 | * root path 36 | * resource path 37 | * suffix 38 | * components require a special case 39 | * component templates 40 | 41 | * isolate chunks as tokens to swap 42 | * `app/routes/user.js` 43 | * `app` 44 | * `routes` 45 | * `user` 46 | * `.js` 47 | * `app/routes/users/profile/edit.js` 48 | * `app` 49 | * `users/profile/edit` 50 | * `routes` 51 | * `.js` 52 | * `app/pods/user/route.js` 53 | * `app/pods` 54 | * `user` 55 | * `route` 56 | * `.js` 57 | * `tests/unit/routes/user.js` 58 | * `tests/unit` 59 | * `routes` 60 | * `user` 61 | * `.js` 62 | * `app/components/taco-shell.js` 63 | * `app` 64 | * `components` 65 | * `taco-shell` 66 | * `.js` 67 | * `app/templates/components/taco-shell.hbs` 68 | * `app` 69 | * `templates/components` 70 | * `taco-shell` 71 | * `.hbs` 72 | * use properties to create values to replace tokens 73 | 74 | ### Example 75 | 76 | ``` 77 | ember podify 78 | ember podify taco 79 | ember podify taco burrito chimichanga 80 | ember depodify 81 | ``` 82 | 83 | Given the following example: 84 | 85 | ``` 86 | app 87 | ├- adapters 88 | | └- taco.js 89 | ├- controllers 90 | | ├- burrito.js 91 | | └- taco.js 92 | ├- mixins 93 | | └- beef.js 94 | ├- models 95 | | ├- burrito.js 96 | | └- taco.js 97 | ├- routes 98 | | ├- burrito.js 99 | | └- taco.js 100 | ├- templates 101 | | ├- burrito.js 102 | | └- taco.js 103 | └- views 104 | ├- burrito.js 105 | └- taco.js 106 | 107 | tests 108 | └- unit 109 | ├- adapters 110 | | └- taco-test.js 111 | ├- controllers 112 | | ├- burrito-test.js 113 | | └- taco-test.js 114 | ├- mixins 115 | | └- beef-test.js 116 | ├- models 117 | | ├- burrito-test.js 118 | | └- taco-test.js 119 | ├- routes 120 | | ├- burrito-test.js 121 | | └- taco-test.js 122 | └- views 123 | ├- burrito-test.js 124 | └- taco-test.js 125 | ``` 126 | 127 | Running `ember podify taco` would result in the following: 128 | 129 | ``` 130 | app 131 | ├- controllers 132 | | └- burrito.js 133 | ├- mixins 134 | | └- beef.js 135 | ├- models 136 | | └- burrito.js 137 | ├- pods 138 | | └- taco 139 | | ├- adapter.js 140 | | ├- controller.js 141 | | ├- model.js 142 | | ├- route.js 143 | | ├- template.js 144 | | └- view.js 145 | ├- routes 146 | | └- burrito.js 147 | ├- templates 148 | | └- burrito.js 149 | └- views 150 | └- burrito.js 151 | 152 | tests 153 | └- unit 154 | ├- controllers 155 | | └- burrito-test.js 156 | ├- mixins 157 | | └- beef-test.js 158 | ├- models 159 | | └- burrito-test.js 160 | ├- pods 161 | | └- taco 162 | | ├- adapter-test.js 163 | | ├- controller-test.js 164 | | ├- model-test.js 165 | | ├- route-test.js 166 | | └- view-test.js 167 | ├- routes 168 | | └- burrito-test.js 169 | └- views 170 | └- burrito-test.js 171 | ``` 172 | 173 | Running `ember podify` would result in the following: 174 | 175 | ``` 176 | app 177 | ├- mixins 178 | | └- beef.js 179 | └- pods 180 | ├- burrito 181 | | ├- controller.js 182 | | ├- model.js 183 | | ├- route.js 184 | | ├- template.js 185 | | └- view.js 186 | └- taco 187 | ├- adapter.js 188 | ├- controller.js 189 | ├- model.js 190 | ├- route.js 191 | ├- template.js 192 | └- view.js 193 | 194 | tests 195 | └- unit 196 | ├- mixins 197 | | └- beef-test.js 198 | └-- pods 199 | ├- burrito 200 | | ├- controller-test.js 201 | | ├- model-test.js 202 | | ├- route-test.js 203 | | └- view-test.js 204 | └- taco 205 | ├- adapter-test.js 206 | ├- controller-test.js 207 | ├- model-test.js 208 | ├- route-test.js 209 | └- view-test.js 210 | 211 | ``` 212 | 213 | Running `ember depodify` would revert to the original format. 214 | 215 | ### Risks 216 | Renaming the assets should be pretty simple, and carries almost no risk of breaking an app. The issue that could break would be when a module has been included with an explicit path. We would need to re-path references to modules that have changed, but that as well is a fairly simple task. 217 | 218 | ### Testing 219 | #### fixtures 220 | * podModulePrefix 221 | * modulePrefix 222 | * type only 223 | * pods only 224 | * some pods, some type 225 | * custom pod type 226 | * import pods (for renaming) 227 | 228 | #### tests 229 | * `ember podify` 230 | * ignores files already in pod format (noop) 231 | * renames imports for changed paths 232 | 233 | * `ember podify foo` 234 | 235 | * `ember depodify` 236 | 237 | * `ember depodify foo` -------------------------------------------------------------------------------- /testem.json: -------------------------------------------------------------------------------- 1 | { 2 | "framework": "qunit", 3 | "test_page": "tests/index.html", 4 | "launch_in_ci": [ 5 | "PhantomJS" 6 | ], 7 | "launch_in_dev": [ 8 | "PhantomJS", 9 | "Chrome" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /tests/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "predef": [ 3 | "document", 4 | "window", 5 | "location", 6 | "setTimeout", 7 | "$", 8 | "-Promise", 9 | "QUnit", 10 | "define", 11 | "console", 12 | "equal", 13 | "notEqual", 14 | "notStrictEqual", 15 | "test", 16 | "asyncTest", 17 | "testBoth", 18 | "testWithDefault", 19 | "raises", 20 | "throws", 21 | "deepEqual", 22 | "start", 23 | "stop", 24 | "ok", 25 | "strictEqual", 26 | "module", 27 | "moduleFor", 28 | "moduleForComponent", 29 | "moduleForModel", 30 | "process", 31 | "expect", 32 | "visit", 33 | "exists", 34 | "fillIn", 35 | "click", 36 | "keyEvent", 37 | "triggerEvent", 38 | "find", 39 | "findWithAssert", 40 | "wait", 41 | "DS", 42 | "isolatedContainer", 43 | "startApp", 44 | "andThen", 45 | "currentURL", 46 | "currentPath", 47 | "currentRouteName" 48 | ], 49 | "node": false, 50 | "browser": false, 51 | "boss": true, 52 | "curly": false, 53 | "debug": false, 54 | "devel": false, 55 | "eqeqeq": true, 56 | "evil": true, 57 | "forin": false, 58 | "immed": false, 59 | "laxbreak": false, 60 | "newcap": true, 61 | "noarg": true, 62 | "noempty": false, 63 | "nonew": false, 64 | "nomen": false, 65 | "onevar": false, 66 | "plusplus": false, 67 | "regexp": false, 68 | "undef": true, 69 | "sub": true, 70 | "strict": false, 71 | "white": false, 72 | "eqnull": true, 73 | "esnext": true 74 | } 75 | -------------------------------------------------------------------------------- /tests/dummy/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "predef": [ 3 | "document", 4 | "window", 5 | "-Promise" 6 | ], 7 | "browser": true, 8 | "boss": true, 9 | "curly": true, 10 | "debug": false, 11 | "devel": true, 12 | "eqeqeq": true, 13 | "evil": true, 14 | "forin": false, 15 | "immed": false, 16 | "laxbreak": false, 17 | "newcap": true, 18 | "noarg": true, 19 | "noempty": false, 20 | "nonew": false, 21 | "nomen": false, 22 | "onevar": false, 23 | "plusplus": false, 24 | "regexp": false, 25 | "undef": true, 26 | "sub": true, 27 | "strict": false, 28 | "white": false, 29 | "eqnull": true, 30 | "esnext": true, 31 | "unused": true 32 | } 33 | -------------------------------------------------------------------------------- /tests/dummy/app/app.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import Resolver from 'ember/resolver'; 3 | import loadInitializers from 'ember/load-initializers'; 4 | import config from './config/environment'; 5 | 6 | Ember.MODEL_FACTORY_INJECTIONS = true; 7 | 8 | var App = Ember.Application.extend({ 9 | modulePrefix: config.modulePrefix, 10 | podModulePrefix: config.podModulePrefix, 11 | Resolver: Resolver 12 | }); 13 | 14 | loadInitializers(App, config.modulePrefix); 15 | 16 | export default App; 17 | -------------------------------------------------------------------------------- /tests/dummy/app/components/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trabus/ember-cli-podify/b00e26c562a15903a9df04663a6f0c6548db2282/tests/dummy/app/components/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/controllers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trabus/ember-cli-podify/b00e26c562a15903a9df04663a6f0c6548db2282/tests/dummy/app/controllers/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/helpers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trabus/ember-cli-podify/b00e26c562a15903a9df04663a6f0c6548db2282/tests/dummy/app/helpers/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Dummy 7 | 8 | 9 | 10 | {{content-for 'head'}} 11 | 12 | 13 | 14 | 15 | 16 | {{content-for 'body'}} 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /tests/dummy/app/models/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trabus/ember-cli-podify/b00e26c562a15903a9df04663a6f0c6548db2282/tests/dummy/app/models/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/router.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import config from './config/environment'; 3 | 4 | var Router = Ember.Router.extend({ 5 | location: config.locationType 6 | }); 7 | 8 | Router.map(function() { 9 | }); 10 | 11 | export default Router; 12 | -------------------------------------------------------------------------------- /tests/dummy/app/routes/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trabus/ember-cli-podify/b00e26c562a15903a9df04663a6f0c6548db2282/tests/dummy/app/routes/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/styles/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trabus/ember-cli-podify/b00e26c562a15903a9df04663a6f0c6548db2282/tests/dummy/app/styles/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/styles/app.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | margin: 20px; 3 | } 4 | -------------------------------------------------------------------------------- /tests/dummy/app/templates/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trabus/ember-cli-podify/b00e26c562a15903a9df04663a6f0c6548db2282/tests/dummy/app/templates/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/templates/application.hbs: -------------------------------------------------------------------------------- 1 |

Welcome to Ember.js

2 | 3 | {{outlet}} 4 | -------------------------------------------------------------------------------- /tests/dummy/app/templates/components/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trabus/ember-cli-podify/b00e26c562a15903a9df04663a6f0c6548db2282/tests/dummy/app/templates/components/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/views/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trabus/ember-cli-podify/b00e26c562a15903a9df04663a6f0c6548db2282/tests/dummy/app/views/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/config/environment.js: -------------------------------------------------------------------------------- 1 | /* jshint node: true */ 2 | 3 | module.exports = function(environment) { 4 | var ENV = { 5 | modulePrefix: 'dummy', 6 | environment: environment, 7 | baseURL: '/', 8 | locationType: 'auto', 9 | EmberENV: { 10 | FEATURES: { 11 | // Here you can enable experimental features on an ember canary build 12 | // e.g. 'with-controller': true 13 | } 14 | }, 15 | 16 | APP: { 17 | // Here you can pass flags/options to your application instance 18 | // when it is created 19 | } 20 | }; 21 | 22 | if (environment === 'development') { 23 | // ENV.APP.LOG_RESOLVER = true; 24 | ENV.APP.LOG_ACTIVE_GENERATION = true; 25 | // ENV.APP.LOG_TRANSITIONS = true; 26 | // ENV.APP.LOG_TRANSITIONS_INTERNAL = true; 27 | ENV.APP.LOG_VIEW_LOOKUPS = true; 28 | } 29 | 30 | if (environment === 'test') { 31 | // Testem prefers this... 32 | ENV.baseURL = '/'; 33 | ENV.locationType = 'auto'; 34 | 35 | // keep test console output quieter 36 | ENV.APP.LOG_ACTIVE_GENERATION = false; 37 | ENV.APP.LOG_VIEW_LOOKUPS = false; 38 | 39 | ENV.APP.rootElement = '#ember-testing'; 40 | } 41 | 42 | if (environment === 'production') { 43 | 44 | } 45 | 46 | return ENV; 47 | }; 48 | -------------------------------------------------------------------------------- /tests/dummy/public/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trabus/ember-cli-podify/b00e26c562a15903a9df04663a6f0c6548db2282/tests/dummy/public/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/public/crossdomain.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 15 | 16 | -------------------------------------------------------------------------------- /tests/dummy/public/robots.txt: -------------------------------------------------------------------------------- 1 | # robotstxt.org/ 2 | 3 | User-agent: * 4 | -------------------------------------------------------------------------------- /tests/helpers/resolver.js: -------------------------------------------------------------------------------- 1 | import Resolver from 'ember/resolver'; 2 | import config from '../../config/environment'; 3 | 4 | var resolver = Resolver.create(); 5 | 6 | resolver.namespace = { 7 | modulePrefix: config.modulePrefix, 8 | podModulePrefix: config.podModulePrefix 9 | }; 10 | 11 | export default resolver; 12 | -------------------------------------------------------------------------------- /tests/helpers/start-app.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import Application from '../../app'; 3 | import Router from '../../router'; 4 | import config from '../../config/environment'; 5 | 6 | export default function startApp(attrs) { 7 | var App; 8 | 9 | var attributes = Ember.merge({}, config.APP); 10 | attributes = Ember.merge(attributes, attrs); // use defaults, but you can override; 11 | 12 | Ember.run(function() { 13 | App = Application.create(attributes); 14 | App.setupForTesting(); 15 | App.injectTestHelpers(); 16 | }); 17 | 18 | App.reset(); // this shouldn't be needed, i want to be able to "start an app at a specific URL" 19 | 20 | return App; 21 | } 22 | -------------------------------------------------------------------------------- /tests/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Dummy Tests 7 | 8 | 9 | 10 | {{content-for 'head'}} 11 | {{content-for 'test-head'}} 12 | 13 | 14 | 15 | 16 | 32 | 33 | 34 |
35 |
36 | 37 | {{content-for 'body'}} 38 | {{content-for 'test-body'}} 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /tests/test-helper.js: -------------------------------------------------------------------------------- 1 | import resolver from './helpers/resolver'; 2 | import { 3 | setResolver 4 | } from 'ember-qunit'; 5 | 6 | setResolver(resolver); 7 | 8 | document.write('
'); 9 | 10 | QUnit.config.urlConfig.push({ id: 'nocontainer', label: 'Hide container'}); 11 | var containerVisibility = QUnit.urlParams.nocontainer ? 'hidden' : 'visible'; 12 | document.getElementById('ember-testing-container').style.visibility = containerVisibility; 13 | -------------------------------------------------------------------------------- /tests/unit/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trabus/ember-cli-podify/b00e26c562a15903a9df04663a6f0c6548db2282/tests/unit/.gitkeep -------------------------------------------------------------------------------- /vendor/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trabus/ember-cli-podify/b00e26c562a15903a9df04663a6f0c6548db2282/vendor/.gitkeep --------------------------------------------------------------------------------