-
Notifications
You must be signed in to change notification settings - Fork 7.6k
Auto install bundle #9490
Auto install bundle #9490
Changes from 7 commits
2c75710
f4b1dd0
be1fcd6
d2b3163
c758209
a4d4c58
7881005
7d311b9
4af80b1
89550d7
1e6b6b0
3341176
8ec89c8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -38,15 +38,16 @@ | |
define(function (require, exports, module) { | ||
"use strict"; | ||
|
||
var _ = require("thirdparty/lodash"), | ||
Package = require("extensibility/Package"), | ||
Async = require("utils/Async"), | ||
ExtensionLoader = require("utils/ExtensionLoader"), | ||
ExtensionUtils = require("utils/ExtensionUtils"), | ||
FileSystem = require("filesystem/FileSystem"), | ||
Strings = require("strings"), | ||
StringUtils = require("utils/StringUtils"), | ||
ThemeManager = require("view/ThemeManager"); | ||
var _ = require("thirdparty/lodash"), | ||
Package = require("extensibility/Package"), | ||
Async = require("utils/Async"), | ||
ExtensionLoader = require("utils/ExtensionLoader"), | ||
ExtensionUtils = require("utils/ExtensionUtils"), | ||
FileSystem = require("filesystem/FileSystem"), | ||
FileUtils = require("file/FileUtils"), | ||
Strings = require("strings"), | ||
StringUtils = require("utils/StringUtils"), | ||
ThemeManager = require("view/ThemeManager"); | ||
|
||
// semver.browser is an AMD-compatible module | ||
var semver = require("extensibility/node/node_modules/semver/semver.browser"); | ||
|
@@ -600,12 +601,99 @@ define(function (require, exports, module) { | |
}, []); | ||
} | ||
|
||
function _autoInstallBundles() { | ||
// Get list of extension bundles | ||
var validatePromise, | ||
srcPath = FileUtils.getNativeBracketsDirectoryPath(), | ||
dirPath = srcPath.substr(0, srcPath.lastIndexOf("/")) + "/bundles/", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: might be nicer to say `dirPath = FileUtils.getDirectoryPath(FileUtils.getNativeBracketsDirectoryPath()) + "bundles/"; There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For the folder name, something a little more self-explanatory might be good... e.g. Also might be good to move the folder name into a constant... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @dangoor It depends on where we want to put the folder. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @peterflynn I started with "bundles" just to get the code going, but I agree that it's not quite right. To me, the "bundle" is the "installer plus the extensions" (not just the extensions). Unless I hear any better suggestions, I'll change it to "auto-install-extensions" and put it in a constant. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not so.
I agree with Peter's points also about There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @dangoor Ah, I missed that point. Done. |
||
bundles = [], | ||
installZips = [], | ||
updateZips = [], | ||
deferred = new $.Deferred(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Code style: this would look a bit better like so: var validatePromise,
srcPath = FileUtils.getNativeBracketsDirectoryPath(),
dirPath = srcPath.substr(0, srcPath.lastIndexOf("/")) + "/bundles/",
deferred = new $.Deferred(),
bundles = [],
updateZips = [],
installZips = []; There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FWIW, I find the "Align It!" extension really handy for this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done, but I indented everything to same level. |
||
|
||
FileSystem.getDirectoryForPath(dirPath).getContents(function (err, contents) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if the "bundles" folder doesn't exist? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
if (!err) { | ||
var i, dirItem; | ||
|
||
for (i = 0; i < contents.length; i++) { | ||
dirItem = contents[i]; | ||
if (dirItem.isFile && FileUtils.getFileExtension(dirItem.fullPath) === "zip") { | ||
bundles.push(dirItem); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You could use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks -- much cleaner. Looking at this code also made me realize that the callback from |
||
} | ||
} | ||
} | ||
}); | ||
|
||
// Process bundles | ||
// TODO - currently we're looking for extension .zip files in "bundles" folder | ||
// - not really "bundles", right? Just need better terminology. | ||
|
||
// Parse zip files and separate new installs vs. updates | ||
validatePromise = Async.doInParallel(bundles, function (file) { | ||
var result = new $.Deferred(); | ||
|
||
// Call validate() so that we open the local zip file and parse the | ||
// package.json. We need the name to detect if this zip will be a | ||
// new install or an update. | ||
Package.validate(file.fullPath, { requirePackageJSON: true }).done(function (info) { | ||
if (info.errors.length) { | ||
result.reject(Package.formatError(info.errors)); | ||
return; | ||
} | ||
|
||
var extensionName = info.metadata.name, | ||
extensionInfo = extensions[extensionName], | ||
isUpdate = extensionInfo && !!extensionInfo.installInfo; | ||
|
||
if (isUpdate) { | ||
updateZips.push(file); | ||
} else { | ||
installZips.push(file); | ||
} | ||
|
||
result.resolve(); | ||
}).fail(function (err) { | ||
result.reject(Package.formatError(err)); | ||
}); | ||
|
||
return result.promise(); | ||
}); | ||
|
||
|
||
validatePromise.done(function () { | ||
var installPromise = Async.doSequentially(installZips, function (file) { | ||
return Package.installFromPath(file.fullPath); | ||
}); | ||
|
||
var updatePromise = installPromise.always(function () { | ||
return Async.doSequentially(updateZips, function (file) { | ||
return Package.installUpdate(file.fullPath); | ||
}); | ||
}); | ||
|
||
// Always resolve the outer promise | ||
updatePromise.always(deferred.resolve); | ||
}).fail(function (errorArray) { | ||
deferred.reject(errorArray); | ||
}); | ||
|
||
return deferred.promise(); | ||
} | ||
|
||
function autoInstallBundles() { | ||
// TODO: make _getNodeConnectionDeferred() public? | ||
Package._getNodeConnectionDeferred().done(function () { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I haven't looked at Package recently, but is this even required? It seems like the node connection should be an implementation detail of Package that the caller need not be aware of. (In other words, you can call validate and it will return after it has a connection and is ready to return a value.) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Without waiting on this promise to finish, I get: "extensionManager domain is undefined" and everything fails. Let me know if you can think of a cleaner way to do this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah... it looks like Package easily could wait until Node is ready, but it doesn't. All the calls are wrapped through |
||
_autoInstallBundles(); | ||
}); | ||
} | ||
|
||
// Listen to extension load and loadFailed events | ||
$(ExtensionLoader) | ||
.on("load", _handleExtensionLoad) | ||
.on("loadFailed", _handleExtensionLoad); | ||
|
||
// Public exports | ||
exports.autoInstallBundles = autoInstallBundles; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should call this private API. The only caller of this should be Brackets itself. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @dangoor What if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That would be fine, too. |
||
exports.downloadRegistry = downloadRegistry; | ||
exports.getCompatibilityInfo = getCompatibilityInfo; | ||
exports.getExtensionURL = getExtensionURL; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't need that extra indent level.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch! I removed the dependency that I increased the indentation for :)