Skip to content

Commit 5d5c55a

Browse files
authored
Merge pull request #47 from andyhot/feature/imports-rewrite
Imports rewrite for moved files
2 parents d4ed1a2 + 9db3d97 commit 5d5c55a

24 files changed

Lines changed: 373 additions & 108 deletions

File tree

.eslintrc.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
module.exports = {
22
"env": {
3-
"node": true
3+
"node": true,
4+
"es6": true
45
},
56
"extends": "eslint:recommended",
67
"rules": {

.travis.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
language: node_js
22
node_js:
3-
- "0.10"
4-
- "0.12"
53
- "4"
4+
- "6"
5+
- "7"
6+
- "8"
67
- "stable"

bin/ember-module-migrator

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,24 @@ var Migrator = require('../lib');
1313
var nopt = require("nopt");
1414
var options = {
1515
'project-root': [String],
16+
'project-name': [String],
1617
'engine': [String, 'classic']
1718
};
1819
var parsed = nopt(options);
1920

21+
var projectRoot = parsed['project-root'] || process.cwd();
22+
var projectName = parsed['project-name'];
23+
if (!projectName) {
24+
// determine name from package.json in projectRoot
25+
try {
26+
var fs = require('fs');
27+
projectName = JSON.parse(fs.readFileSync(projectRoot + '/package.json', 'utf8')).name;
28+
} catch (e) {}
29+
}
30+
2031
var migrator = new Migrator({
21-
projectRoot: parsed['project-root'] || process.cwd(),
32+
projectRoot: projectRoot,
33+
projectName: projectName,
2234
engine: parsed['engine'],
2335
verbose: true
2436
});

lib/engines/classic/test-file-info.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ var TestFileInfo = ClassicFileInfo.extend({
1818
}
1919

2020
this.populateBucket();
21+
this.populateFileContents();
2122

2223
this._fileInfoCollection.add(this);
2324
},

lib/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ var Engine = CoreObject.extend({
2222
}
2323

2424
if (!this.engine) {
25-
throw new Error('Can not fine engine to use for migration!');
25+
throw new Error('Can not find engine to use for migration!');
2626
}
2727

2828
this._promise = null;
@@ -139,6 +139,7 @@ var Engine = CoreObject.extend({
139139
fileInfoFor: function(path) {
140140
var fileInfo = this.engine.buildFor(path, {
141141
projectRoot: this.projectRoot,
142+
projectName: this.projectName,
142143
_fileInfoCollection: this._fileInfoCollection
143144
});
144145

lib/models/file-info.js

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ var path = require('path');
22
var CoreObject = require('core-object');
33
var fse = require('fs-extra');
44
var existsSync = require('exists-sync');
5+
var jscodeshift = require('jscodeshift');
56
var isTypeInSingleTypeCollection = require('../utils/is-type-in-single-type-collection');
67
var defaultTypeForCollection = require('../utils/default-type-for-collection');
78
var calculateCollectionInfo = require('../utils/calculate-collection-info');
9+
var importDeclarationsTransform = require('../transforms/import-declarations');
810

911
var FileInfo = CoreObject.extend({
1012
type: 'FileInfo',
@@ -95,7 +97,33 @@ var FileInfo = CoreObject.extend({
9597
this._fileContents = fse.readFileSync(fullPath, { encoding: 'utf8' });
9698
},
9799

100+
updateImports: function() {
101+
if (this.ext !== '.js' || !this._fileContents) { return; } // only process JavaScript files
102+
103+
var appName = this.options.projectName;
104+
105+
try {
106+
var newContents = importDeclarationsTransform(
107+
{ source: this._fileContents,
108+
fileInfo: this,
109+
appName: appName,
110+
fileInfos: this._fileInfoCollection._fileInfos
111+
},
112+
{ jscodeshift });
113+
114+
var fullPath = path.join(this.projectRoot, this.sourceRelativePath);
115+
116+
fse.writeFileSync(fullPath, newContents, { encoding: 'utf-8' });
117+
this._fileContents = newContents;
118+
} catch(e) {
119+
// eslint-disable-next-line no-console
120+
console.log('error parsing file `' + this.sourceRelativePath + '` failed to apply codeshift. Possible invalid JS file. Returning original file unchanged. error: ' + e.message);
121+
}
122+
},
123+
98124
repopulate: function() {
125+
this.updateImports();
126+
99127
var inComponentsCollection = this.collection === 'components';
100128
var renderableName = path.join(this.namespace, this.name);
101129

@@ -135,7 +163,7 @@ var FileInfo = CoreObject.extend({
135163
var fullPath = path.join(this.projectRoot, this.sourceRelativePath);
136164

137165
fse.writeFileSync(fullPath, newContents, { encoding: 'utf-8' });
138-
this._fileContents = fse.readFileSync(fullPath, { encoding: 'utf8' });
166+
this._fileContents = newContents;
139167
},
140168

141169
shouldUseDotFormNaming: function() {
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
var path_utils = require('../utils/path');
2+
3+
function transformer(file, api) {
4+
var j = api.jscodeshift;
5+
6+
return j(file.source)
7+
.find(j.ImportDeclaration)
8+
.find(j.Literal)
9+
.forEach(function(path) {
10+
var importPath = path.value.value + '.js';
11+
var appName = file.appName;
12+
13+
if (!appName) {
14+
// skip import transforms if appName is not set
15+
return;
16+
}
17+
18+
// determine the actual path that importPath points to
19+
// TODO: extract these resolutions into classic-file-info and test-file-info
20+
var relative = path_utils.isRelative(importPath);
21+
if (relative) {
22+
var sourceRelativePath = file.fileInfo.sourceRelativePath;
23+
24+
if (sourceRelativePath.startsWith('tests/')) {
25+
importPath = path_utils.makeAbsolute(appName + '/app/' + sourceRelativePath, importPath);
26+
27+
// see if we stayed within tests
28+
var inTestsPrefix = appName + '/app/tests/';
29+
if (importPath.startsWith(inTestsPrefix)) {
30+
importPath = appName + '/tests/' + importPath.substring(inTestsPrefix.length);
31+
}
32+
} else {
33+
importPath = path_utils.makeAbsolute(appName + '/' + sourceRelativePath, importPath);
34+
}
35+
} else {
36+
// check if import path starts with appName and add /app
37+
if (importPath.startsWith(appName + '/') && !importPath.startsWith(appName + '/app/')) {
38+
importPath = appName + '/app' + importPath.substring(appName.length);
39+
}
40+
}
41+
42+
var targetFileInfo = file.fileInfos.find(function(f) {
43+
return (appName + '/' + f.sourceRelativePath) === importPath;
44+
});
45+
46+
if (!targetFileInfo) {
47+
// TODO error message
48+
return;
49+
}
50+
51+
var newImportPath = appName + '/' + targetFileInfo.destRelativePath;
52+
if (relative) {
53+
newImportPath = path_utils.makeRelative(file.fileInfo.destRelativePath, targetFileInfo.destRelativePath);
54+
}
55+
// remove extension
56+
newImportPath = newImportPath.slice(0, -targetFileInfo.ext.length);
57+
j(path).replaceWith(j.literal(newImportPath));
58+
})
59+
.toSource();
60+
61+
}
62+
63+
module.exports = transformer;

lib/utils/path.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
var p = require('path');
2+
3+
function isRelative(path) {
4+
return path[0] === '.';
5+
}
6+
7+
function makeRelative(from, to) {
8+
var path = p.relative(p.dirname(from), to);
9+
if (!isRelative(path)) {
10+
path = './' + path;
11+
}
12+
return path;
13+
}
14+
15+
function makeAbsolute(base, path) {
16+
return p.resolve(p.dirname('/' + base), path).substring(1);
17+
}
18+
19+
module.exports = {
20+
isRelative,
21+
makeRelative,
22+
makeAbsolute
23+
};

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"assert-diff": "^1.0.1",
1818
"espower-loader": "^1.0.0",
1919
"fixturify": "^0.2.0",
20+
"jscodeshift": "^0.3.30",
2021
"mocha": "^2.4.5",
2122
"mocha-eslint": "^2.0.2",
2223
"power-assert": "^1.3.1",

test/engines/classic-test.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ describe('classic engine', function() {
1313

1414
beforeEach(function() {
1515
engine = new Migrator({
16-
projectRoot: '.'
16+
projectRoot: '.',
17+
projectName: 'my-app'
1718
});
1819
});
1920

@@ -148,7 +149,8 @@ describe('classic engine', function() {
148149
fixturify.writeSync(tmpPath, input);
149150

150151
var engine = new Migrator({
151-
projectRoot: tmpPath
152+
projectRoot: tmpPath,
153+
projectName: 'my-app'
152154
});
153155

154156
return engine.processFiles()

0 commit comments

Comments
 (0)