Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
Kelly Selden committed Jul 9, 2016
1 parent 3c93b94 commit d87d374
Show file tree
Hide file tree
Showing 3 changed files with 249 additions and 215 deletions.
232 changes: 19 additions & 213 deletions app/components/dependency-component.js
Original file line number Diff line number Diff line change
@@ -1,219 +1,36 @@
import Ember from 'ember';
import computed from 'ember-computed-decorators';
import { task } from 'ember-concurrency';
import promiseArray from 'ember-awesome-macros/promise-array';
import normalizeDependencies from '../utils/normalize-dependencies';
import mergeModules from '../utils/merge-modules';
import getRealVersion from '../utils/get-real-version';

const {
Component,
inject: { service },
get, set, setProperties,
computed: { not, or, readOnly }
get,
computed: { readOnly }
} = Ember;

const groups = [
['Dependencies', 'dependencies'],
['Dev Dependencies', 'devDependencies'],
['Optional Dependencies', 'optionalDependencies']
];

export default Component.extend({
task: service(),
treeBuilder: service(),

@computed('repoUrl', 'repo')
isRepoUrlInvalid(repoUrl, repo) {
return repoUrl && !repo;
},

@computed('firstJson', 'secondJson')
dependencyGroups(firstJson, secondJson) {
// we are creating new dependency objects
// so cancel all the promises that set values on the old dependency objects
this._cancelAll();

let treeBuilder = get(this, 'treeBuilder');

let dependencyGroups = groups.map(([title, prop]) => {
let firstDependencies = normalizeDependencies(firstJson[prop]);
let secondDependencies = normalizeDependencies(secondJson[prop]);

let dependencies = this._getDependencies(firstDependencies, secondDependencies);

let dependencyGroup = Ember.Object.create({
title,
dependencies
});

treeBuilder.setupComputeds(dependencyGroup, false);

return dependencyGroup;
}).filter(dependencyGroup => get(dependencyGroup, 'dependencies').length);

return dependencyGroups;
// watching dates because even though commits might not change,
// nested versions might have
@computed('firstJson', 'secondJson', 'repoWorkingDate', 'repoBrokenDate')
dependencyGroups(firstJson, secondJson, repoWorkingDate, repoBrokenDate) {
return get(this, 'treeBuilder').getDependencyGroups({
firstJson,
secondJson,
repoWorkingDate,
repoBrokenDate
});
},

// to reuse the crawling logic
dependencies: readOnly('dependencyGroups'),

_getDependencies(firstDependencies, secondDependencies) {
let dependencies = mergeModules(firstDependencies, secondDependencies);

let treeBuilder = get(this, 'treeBuilder');

for (let dependency of dependencies) {
this._setupVersions(dependency);

treeBuilder.setupComputeds(dependency);
}

return dependencies;
},

_setupVersions(dependency) {
setProperties(dependency, {
versionsPromise: get(this, '_setupVersionsTask').perform(dependency)
});

this._setupDependencies(dependency);
},

_setupVersionsTask: task(function * (dependency) {
let module = get(dependency, 'module');
let firstVersionHint = get(dependency, 'firstVersionHint');
let secondVersionHint = get(dependency, 'secondVersionHint');

let versions;
try {
versions = yield get(this, 'task.getVersions').perform(module);
} catch (error) {
set(dependency, 'versionsError', error.errorThrown);

return true;
}

let firstVersion = this._getFirstVersion(versions, firstVersionHint);
let secondVersion = this._getSecondVersion(versions, secondVersionHint);

setProperties(dependency, {
firstVersion,
secondVersion,
isFirstVersionMissing: not('firstVersion'),
isSecondVersionMissing: not('secondVersion'),
isOneMissing: or('isFirstVersionMissing', 'isSecondVersionMissing')
});

this._checkForCircularReference(dependency, 'firstVersion', 'hasFirstCircularReference');
this._checkForCircularReference(dependency, 'secondVersion', 'hasSecondCircularReference');

return false;
}),

_getFirstVersion(versions, firstVersionHint) {
return this._getRealVersion(versions, firstVersionHint, 'repoWorkingDate');
},
_getSecondVersion(versions, secondVersionHint) {
return this._getRealVersion(versions, secondVersionHint, 'repoBrokenDate');
},
_getRealVersion(versions, versionHint, repoDateProp) {
let repoDate = get(this, repoDateProp);

let realVersion = getRealVersion(
versionHint,
versions,
repoDate
);

return realVersion;
},

_checkForCircularReference(dependency, versionProp, hasCircularReferenceProp) {
let module = get(dependency, 'module');
let version = get(dependency, versionProp);
let parent = get(dependency, 'parent');
while (parent) {
let parentModule = get(parent, 'module');
let parentVersion = get(parent, versionProp);
if (parentModule == module &&
parentVersion == version) {
set(dependency, hasCircularReferenceProp, true);

break;
}

parent = get(parent, 'parent');
}
},

_setupDependencies(dependency) {
let nestedDependenciesPromise = get(this, '_setupDependenciesTask').perform(dependency);

setProperties(dependency, {
nestedDependenciesPromise,
dependencies: promiseArray(() => {
return nestedDependenciesPromise.catch(() => {
// catch means task was canceled, return empty array to continue
return [];
});
})
});
},

_setupDependenciesTask: task(function * (dependency) {
let wasErrorThrown = yield get(dependency, 'versionsPromise');
if (wasErrorThrown) {
return;
}

let getDependenciesTask = get(this, 'getDependenciesTask');
let firstDependencies = yield getDependenciesTask.perform(dependency, 'firstVersion', 'firstDependenciesError', 'hasFirstCircularReference');
let secondDependencies = yield getDependenciesTask.perform(dependency, 'secondVersion', 'secondDependenciesError', 'hasSecondCircularReference');

return this._getNestedDependencies(firstDependencies, secondDependencies, dependency);
}),

getDependenciesTask: task(function * (dependency, versionProp, errorProp, hasCircularReferenceProp) {
let dependencies;

let hasCircularReference = get(dependency, hasCircularReferenceProp);
if (hasCircularReference) {
dependencies = [];
} else {
let module = get(dependency, 'module');
let version = get(dependency, versionProp);

// missing from either side
if (!version) {
dependencies = [];
} else {
try {
dependencies = yield get(this, 'task.getDependencies').perform(module, version);
} catch (error) {
set(dependency, errorProp, error.errorThrown);
}
}
}

return dependencies;
}),

_getNestedDependencies(firstDependencies, secondDependencies, parentDependency) {
// error or cancel
if (!firstDependencies || !secondDependencies) {
return [];
}

let dependencies = this._getDependencies(firstDependencies, secondDependencies);

for (let dependency of dependencies) {
set(dependency, 'parent', parentDependency);
}

return dependencies;
},

@computed(
'repo',
'repoWorkingDateError',
Expand Down Expand Up @@ -242,22 +59,8 @@ export default Component.extend({
get(this, 'treeBuilder').setupComputeds(this, false);
},

_cancelAll() {
get(this, '_setupVersionsTask').cancelAll();
get(this, '_setupDependenciesTask').cancelAll();
},

_restartAll(dependency) {
let versionsPromise = get(dependency, 'versionsPromise');
let nestedDependenciesPromise = get(dependency, 'nestedDependenciesPromise');

if (versionsPromise && get(versionsPromise, 'isCanceled')) {
this._setupVersions(dependency);
} else if (nestedDependenciesPromise && get(nestedDependenciesPromise, 'isCanceled')) {
this._setupDependencies(dependency);
} else {
get(dependency, 'dependencies').forEach(this._restartAll.bind(this));
}
willDestroyElement() {
get(this, 'treeBuilder').cancelAll();
},

actions: {
Expand All @@ -271,11 +74,14 @@ export default Component.extend({
this.sendAction('repoBrokenDateUpdated', date);
},
toggleCrawling() {
let treeBuilder = get(this, 'treeBuilder');
let stopCrawling = this.toggleProperty('stopCrawling');
if (stopCrawling) {
this._cancelAll();
treeBuilder.cancelAll();
} else {
this._restartAll(this);
let repoWorkingDate = get(this, 'repoWorkingDate');
let repoBrokenDate = get(this, 'repoBrokenDate');
treeBuilder.restartAll(this, repoWorkingDate, repoBrokenDate);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion app/routes/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export default Route.extend(ApplicationRouteMixin, {
let { controller } = this;
if (controller) {
scheduleOnce('afterRender', () => {
controller.rebuild();
// controller.rebuild();
});
}
}
Expand Down

0 comments on commit d87d374

Please sign in to comment.