Skip to content
This repository was archived by the owner on Sep 6, 2021. It is now read-only.

Commit 92b872e

Browse files
mbhavinethip
authored andcommitted
AutoUpdate Framework (#14177)
* AutoUpdate Framework : Initial Changes * Addressing unit testing issues, error handling, code cleanup * Clean up of code and spaces * Error handling and code cleanup changes * Addressing Review comments * Code cleanup * Code cleanup, for event dispatching and handling * Addressing review comments, adding feature-flag/preference for AutoUpdate, making AutoUpdate no-op for Linux, Replacing icons * Addressing review comments, minor code cleanup * Handling the node domain failure scenarios * Adding update_download_url to config.json and brackets.config.dist.json * Fixing eslint and jslint errors, cleaning up package.json, adding console log message on node domain failure
1 parent d52f3c9 commit 92b872e

20 files changed

Lines changed: 2143 additions & 14 deletions

src/brackets.config.dist.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@
22
"healthDataServerURL" : "https://health.brackets.io/healthDataLog",
33
"analyticsDataServerURL" : "https://cc-api-data.adobe.io/ingest",
44
"serviceKey" : "brackets-service",
5-
"environment" : "production"
5+
"environment" : "production",
6+
"update_download_url" : "https://github.com/adobe/brackets/releases/download/"
67
}

src/config.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
"extension_url": "https://s3.amazonaws.com/extend.brackets/{0}/{0}-{1}.zip",
2121
"linting.enabled_by_default": true,
2222
"build_timestamp": "",
23+
"update_download_url": "https://github.com/adobe/brackets/releases/download/",
2324
"healthDataServerURL": "https://healthdev.brackets.io/healthDataLog",
2425
"analyticsDataServerURL": "https://cc-api-data-stage.adobe.io/ingest",
2526
"serviceKey": "brackets-service",

src/document/DocumentCommandHandlers.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ define(function (require, exports, module) {
3131
CommandManager = require("command/CommandManager"),
3232
Commands = require("command/Commands"),
3333
DeprecationWarning = require("utils/DeprecationWarning"),
34+
EventDispatcher = require("utils/EventDispatcher"),
3435
ProjectManager = require("project/ProjectManager"),
3536
DocumentManager = require("document/DocumentManager"),
3637
MainViewManager = require("view/MainViewManager"),
@@ -135,7 +136,14 @@ define(function (require, exports, module) {
135136
PreferencesManager.definePreference("defaultExtension", "string", "", {
136137
excludeFromHints: true
137138
});
139+
EventDispatcher.makeEventDispatcher(exports);
138140

141+
/**
142+
* Event triggered when File Save is cancelled, when prompted to save dirty files
143+
*/
144+
var APP_QUIT_CANCELLED = "appQuitCancelled";
145+
146+
139147
/**
140148
* JSLint workaround for circular dependency
141149
* @type {function}
@@ -847,6 +855,14 @@ define(function (require, exports, module) {
847855

848856
return result.promise();
849857
}
858+
859+
/**
860+
* Dispatches the app quit cancelled event
861+
*/
862+
function dispatchAppQuitCancelledEvent() {
863+
exports.trigger(exports.APP_QUIT_CANCELLED);
864+
}
865+
850866

851867
/**
852868
* Opens the native OS save as dialog and saves document.
@@ -996,6 +1012,7 @@ define(function (require, exports, module) {
9961012
if (selectedPath) {
9971013
_doSaveAfterSaveDialog(selectedPath);
9981014
} else {
1015+
dispatchAppQuitCancelledEvent();
9991016
result.reject(USER_CANCELED);
10001017
}
10011018
} else {
@@ -1217,6 +1234,7 @@ define(function (require, exports, module) {
12171234
)
12181235
.done(function (id) {
12191236
if (id === Dialogs.DIALOG_BTN_CANCEL) {
1237+
dispatchAppQuitCancelledEvent();
12201238
result.reject();
12211239
} else if (id === Dialogs.DIALOG_BTN_OK) {
12221240
// "Save" case: wait until we confirm save has succeeded before closing
@@ -1322,6 +1340,7 @@ define(function (require, exports, module) {
13221340
)
13231341
.done(function (id) {
13241342
if (id === Dialogs.DIALOG_BTN_CANCEL) {
1343+
dispatchAppQuitCancelledEvent();
13251344
result.reject();
13261345
} else if (id === Dialogs.DIALOG_BTN_OK) {
13271346
// Save all unsaved files, then if that succeeds, close all
@@ -1784,6 +1803,8 @@ define(function (require, exports, module) {
17841803

17851804
// Define public API
17861805
exports.showFileOpenError = showFileOpenError;
1806+
exports.APP_QUIT_CANCELLED = APP_QUIT_CANCELLED;
1807+
17871808

17881809
// Deprecated commands
17891810
CommandManager.register(Strings.CMD_ADD_TO_WORKING_SET, Commands.FILE_ADD_TO_WORKING_SET, handleFileAddToWorkingSet);
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright (c) 2018 - present Adobe Systems Incorporated. All rights reserved.
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a
5+
* copy of this software and associated documentation files (the "Software"),
6+
* to deal in the Software without restriction, including without limitation
7+
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+
* and/or sell copies of the Software, and to permit persons to whom the
9+
* Software is furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in
12+
* all copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20+
* DEALINGS IN THE SOFTWARE.
21+
*
22+
*/
23+
24+
define(function (require, exports, module) {
25+
"use strict";
26+
27+
exports.DOWNLOAD_INSTALLER = "node.downloadInstaller";
28+
exports.PERFORM_CLEANUP = "node.performCleanup";
29+
exports.VALIDATE_INSTALLER = "node.validateInstaller";
30+
exports.INITIALIZE_STATE = "node.initializeState";
31+
exports.SHOW_STATUS_INFO = "brackets.showStatusInfo";
32+
exports.NOTIFY_DOWNLOAD_SUCCESS = "brackets.notifyDownloadSuccess";
33+
exports.SHOW_ERROR_MESSAGE = "brackets.showErrorMessage";
34+
exports.NOTIFY_DOWNLOAD_FAILURE = "brackets.notifyDownloadFailure";
35+
exports.NOTIFY_SAFE_TO_DOWNLOAD = "brackets.notifySafeToDownload";
36+
exports.NOTIFY_INITIALIZATION_COMPLETE = "brackets.notifyinitializationComplete";
37+
exports.NOTIFY_VALIDATION_STATUS = "brackets.notifyvalidationStatus";
38+
exports.REGISTER_BRACKETS_FUNCTIONS = "brackets.registerBracketsFunctions";
39+
});
Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
/*
2+
* Copyright (c) 2018 - present Adobe Systems Incorporated. All rights reserved.
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a
5+
* copy of this software and associated documentation files (the "Software"),
6+
* to deal in the Software without restriction, including without limitation
7+
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+
* and/or sell copies of the Software, and to permit persons to whom the
9+
* Software is furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in
12+
* all copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20+
* DEALINGS IN THE SOFTWARE.
21+
*
22+
*/
23+
24+
define(function (require, exports, module) {
25+
"use strict";
26+
27+
var FileSystem = brackets.getModule("filesystem/FileSystem"),
28+
FileUtils = brackets.getModule("file/FileUtils");
29+
30+
var FILE_NOT_FOUND = 0,
31+
FILE_NOT_READ = 1,
32+
FILE_PARSE_EXCEPTION = 2,
33+
FILE_READ_FAIL = 3;
34+
35+
/**
36+
* @constructor
37+
* Creates a StateHandler object for a JSON file. It maintains the following :
38+
* path - path to the JSON file,
39+
* state - parsed content of the file
40+
* @param {string} path - path to the JSON file
41+
*/
42+
var StateHandler = function (path) {
43+
this.path = path;
44+
this.state = null;
45+
};
46+
47+
/**
48+
* Checks if the file exists
49+
* @returns {$.Deferred} - a jquery deferred promise,
50+
* that is resolved with existence or non-existence
51+
* of json file.
52+
*/
53+
StateHandler.prototype.exists = function () {
54+
var result = $.Deferred(),
55+
_file = FileSystem.getFileForPath(this.path);
56+
57+
_file.exists(function (err, exists) {
58+
if (err) {
59+
result.reject();
60+
} else if (exists) {
61+
result.resolve();
62+
} else {
63+
result.reject();
64+
}
65+
});
66+
67+
return result.promise();
68+
};
69+
70+
/**
71+
* Parses the JSON file, and maintains a state for the parsed data
72+
* @returns {$.Deferred} - a jquery deferred promise,
73+
* that is resolved with a parsing success or failure
74+
*/
75+
StateHandler.prototype.parse = function () {
76+
var result = $.Deferred(),
77+
_file = FileSystem.getFileForPath(this.path);
78+
var self = this;
79+
80+
this.exists()
81+
.done(function () {
82+
FileUtils.readAsText(_file)
83+
.done(function (text) {
84+
try {
85+
if (text) {
86+
self.state = JSON.parse(text);
87+
result.resolve();
88+
} else {
89+
result.reject(FILE_READ_FAIL);
90+
}
91+
} catch (error) {
92+
result.reject(FILE_PARSE_EXCEPTION);
93+
}
94+
})
95+
.fail(function () {
96+
result.reject(FILE_NOT_READ);
97+
});
98+
99+
})
100+
.fail(function () {
101+
result.reject(FILE_NOT_FOUND);
102+
});
103+
104+
return result.promise();
105+
};
106+
107+
/**
108+
* Sets the value of a key in a json file.
109+
* @param {string} key - key for which the value is to be set
110+
* @param {string} value - the value to be set for the given key
111+
* @returns {$.Deferred} - a jquery deferred promise, that is resolved with a write success or failure
112+
*/
113+
StateHandler.prototype.set = function (key, value) {
114+
this.state = this.state || {};
115+
this.state[key] = value;
116+
117+
return this.write(true);
118+
};
119+
120+
/**
121+
* Gets the value for a given key, from the in-memory state maintained for a json file.
122+
* @param {string} key - key for which value is to be retrieved
123+
* @returns {string} value for the given key
124+
*/
125+
StateHandler.prototype.get = function (key) {
126+
var retval = null;
127+
128+
if (this.state && this.state[key]) {
129+
retval = this.state[key];
130+
}
131+
132+
return retval;
133+
};
134+
135+
136+
/**
137+
* Performs the write of JSON object to a file.
138+
* @param {string} filepath - path to JSON file
139+
* @param {object} json - JSON object to write
140+
* @returns {$.Deferred} - a jquery deferred promise,
141+
* that is resolved with the write success or failure
142+
*/
143+
function _write(filePath, json) {
144+
var result = $.Deferred(),
145+
_file = FileSystem.getFileForPath(filePath);
146+
147+
if (_file) {
148+
149+
var content = JSON.stringify(json);
150+
FileUtils.writeText(_file, content, true)
151+
.done(function () {
152+
result.resolve();
153+
})
154+
.fail(function (err) {
155+
result.reject();
156+
});
157+
158+
} else {
159+
result.reject();
160+
}
161+
162+
return result.promise();
163+
}
164+
/**
165+
* Writes content into a json file
166+
* @param {boolean} overwrite - true if file is to be overwritten, false otherwise
167+
* @param {object} [content=this.state] - content to be written into the json file.
168+
* @returns {$.Deferred} - a jquery deferred promise, that is resolved with a write success or failure
169+
*/
170+
StateHandler.prototype.write = function (overwrite) {
171+
var result = $.Deferred(),
172+
self = this;
173+
174+
function writePromise(path, contentToWrite) {
175+
_write(path, contentToWrite)
176+
.done(function () {
177+
result.resolve();
178+
})
179+
.fail(function (err) {
180+
result.reject();
181+
});
182+
}
183+
184+
var content = self.state;
185+
if (overwrite) {
186+
writePromise(self.path, content);
187+
} else {
188+
//check for existence
189+
self.exists()
190+
.fail(function () {
191+
writePromise(self.path, content);
192+
}).done(function () {
193+
result.reject();
194+
});
195+
}
196+
197+
return result.promise();
198+
};
199+
200+
/**
201+
* Resets the content of the in-memory state
202+
*/
203+
StateHandler.prototype.reset = function () {
204+
this.state = null;
205+
};
206+
207+
exports.StateHandler = StateHandler;
208+
exports.MessageKeys = {
209+
FILE_NOT_FOUND: FILE_NOT_FOUND,
210+
FILE_NOT_READ: FILE_NOT_READ,
211+
FILE_PARSE_EXCEPTION: FILE_PARSE_EXCEPTION,
212+
FILE_READ_FAIL: FILE_READ_FAIL
213+
};
214+
});

0 commit comments

Comments
 (0)