зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to autoland. a=merge CLOSED TREE
This commit is contained in:
Коммит
28e824acfe
3
.flake8
3
.flake8
|
@ -25,7 +25,8 @@ exclude =
|
|||
netwerk/protocol/http/make_incoming_tables.py,
|
||||
python/devtools/migrate-l10n/migrate/main.py,
|
||||
python/l10n/fluent_migrations,
|
||||
python/mozbuild,
|
||||
python/mozbuild/dumbmake,
|
||||
python/mozbuild/mozbuild,
|
||||
servo/components/style,
|
||||
testing/jsshell/benchmark.py,
|
||||
testing/marionette/mach_commands.py,
|
||||
|
|
|
@ -11,7 +11,8 @@
|
|||
<menu id="file-menu" label="&fileMenu.label;"
|
||||
accesskey="&fileMenu.accesskey;">
|
||||
<menupopup id="menu_FilePopup"
|
||||
onpopupshowing="updateFileMenuUserContextUIVisibility('menu_newUserContext');">
|
||||
onpopupshowing="updateFileMenuUserContextUIVisibility('menu_newUserContext');
|
||||
updateFileMenuImportUIVisibility('cmd_importFromAnotherBrowser');">
|
||||
<menuitem id="menu_newNavigatorTab"
|
||||
label="&tabCmd.label;"
|
||||
command="cmd_newNavigatorTab"
|
||||
|
@ -85,6 +86,11 @@
|
|||
key="printKb"
|
||||
command="cmd_print"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="menu_importFromAnotherBrowser"
|
||||
label="&importFromAnotherBrowserCmd.label;"
|
||||
accesskey="&importFromAnotherBrowserCmd.accesskey;"
|
||||
command="cmd_importFromAnotherBrowser"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="goOfflineMenuitem"
|
||||
label="&goOfflineCmd.label;"
|
||||
accesskey="&goOfflineCmd.accesskey;"
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
<command id="cmd_pageSetup" oncommand="PrintUtils.showPageSetup();"/>
|
||||
<command id="cmd_print" oncommand="PrintUtils.printWindow(window.gBrowser.selectedBrowser.outerWindowID, window.gBrowser.selectedBrowser);"/>
|
||||
<command id="cmd_printPreview" oncommand="PrintUtils.printPreview(PrintPreviewListener);"/>
|
||||
<command id="cmd_importFromAnotherBrowser" oncommand="MigrationUtils.showMigrationWizard(window, [MigrationUtils.MIGRATION_ENTRYPOINT_FILE_MENU]);"/>
|
||||
<command id="cmd_close" oncommand="BrowserCloseTabOrWindow(event);"/>
|
||||
<command id="cmd_closeWindow" oncommand="BrowserTryToCloseWindow()"/>
|
||||
<command id="cmd_toggleMute" oncommand="gBrowser.toggleMuteAudioOnMultiSelectedTabs(gBrowser.selectedTab)"/>
|
||||
|
|
|
@ -33,6 +33,7 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
|||
LightweightThemeManager: "resource://gre/modules/LightweightThemeManager.jsm",
|
||||
Log: "resource://gre/modules/Log.jsm",
|
||||
LoginManagerParent: "resource://gre/modules/LoginManagerParent.jsm",
|
||||
MigrationUtils: "resource:///modules/MigrationUtils.jsm",
|
||||
NetUtil: "resource://gre/modules/NetUtil.jsm",
|
||||
NewTabUtils: "resource://gre/modules/NewTabUtils.jsm",
|
||||
OpenInTabsUtils: "resource:///modules/OpenInTabsUtils.jsm",
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
"extends": [
|
||||
"plugin:mozilla/browser-test"
|
||||
]
|
||||
};
|
|
@ -0,0 +1,3 @@
|
|||
[DEFAULT]
|
||||
|
||||
[browser_file_menu_import_wizard.js]
|
|
@ -0,0 +1,13 @@
|
|||
add_task(async function file_menu_import_wizard() {
|
||||
// We can't call this code directly or our JS execution will get blocked on Windows/Linux where
|
||||
// the dialog is modal.
|
||||
executeSoon(() => document.getElementById("menu_importFromAnotherBrowser").doCommand());
|
||||
|
||||
await TestUtils.waitForCondition(() => Services.wm.getMostRecentWindow("Browser:MigrationWizard"),
|
||||
"Migrator window opened");
|
||||
|
||||
let migratorWindow = Services.wm.getMostRecentWindow("Browser:MigrationWizard");
|
||||
ok(migratorWindow, "Migrator window opened");
|
||||
|
||||
await BrowserTestUtils.closeWindow(migratorWindow);
|
||||
});
|
|
@ -1073,3 +1073,14 @@ function trimURL(aURL) {
|
|||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates visibility of "Import From Another Browser" command depending on
|
||||
* the DisableProfileImport policy.
|
||||
*/
|
||||
function updateFileMenuImportUIVisibility(id) {
|
||||
if (!Services.policies.isAllowed("profileImport")) {
|
||||
let command = document.getElementById(id);
|
||||
command.setAttribute("disabled", "true");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ BROWSER_CHROME_MANIFESTS += [
|
|||
'content/test/general/browser.ini',
|
||||
'content/test/historySwipeAnimation/browser.ini',
|
||||
'content/test/keyboard/browser.ini',
|
||||
'content/test/menubar/browser.ini',
|
||||
'content/test/metaTags/browser.ini',
|
||||
'content/test/pageActions/browser.ini',
|
||||
'content/test/pageinfo/browser.ini',
|
||||
|
|
|
@ -34,3 +34,19 @@ add_task(async function test_disable_profile_import() {
|
|||
|
||||
checkLockedPref("browser.newtabpage.activity-stream.migrationExpired", true);
|
||||
});
|
||||
|
||||
add_task(async function test_file_menu() {
|
||||
updateFileMenuImportUIVisibility("cmd_importFromAnotherBrowser");
|
||||
|
||||
let command = document.getElementById("cmd_importFromAnotherBrowser");
|
||||
ok(command.getAttribute("disabled"),
|
||||
"The `Import from Another Browser…` menu item command should be disabled");
|
||||
|
||||
if (Services.appinfo.OS == "Darwin") {
|
||||
// We would need to have a lot of boilerplate to open the menus on Windows
|
||||
// and Linux to test this there.
|
||||
let menuitem = document.getElementById("menu_importFromAnotherBrowser");
|
||||
ok(menuitem.disabled,
|
||||
"The `Import from Another Browser…` menu item should be disabled");
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1147,6 +1147,7 @@ var MigrationUtils = Object.freeze({
|
|||
MIGRATION_ENTRYPOINT_PLACES: 3,
|
||||
MIGRATION_ENTRYPOINT_PASSWORDS: 4,
|
||||
MIGRATION_ENTRYPOINT_NEWTAB: 5,
|
||||
MIGRATION_ENTRYPOINT_FILE_MENU: 6,
|
||||
|
||||
_sourceNameToIdMapping: {
|
||||
"nothing": 1,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
This is the PDF.js project output, https://github.com/mozilla/pdf.js
|
||||
|
||||
Current extension version is: 2.2.42
|
||||
Current extension version is: 2.2.51
|
||||
|
||||
Taken from upstream commit: 34022d2f
|
||||
Taken from upstream commit: c43396c2
|
||||
|
|
|
@ -123,8 +123,8 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
"use strict";
|
||||
|
||||
|
||||
var pdfjsVersion = '2.2.42';
|
||||
var pdfjsBuild = '34022d2f';
|
||||
var pdfjsVersion = '2.2.51';
|
||||
var pdfjsBuild = 'c43396c2';
|
||||
|
||||
var pdfjsSharedUtil = __w_pdfjs_require__(1);
|
||||
|
||||
|
@ -1295,7 +1295,7 @@ function _fetchDocument(worker, source, pdfDataRangeTransport, docId) {
|
|||
|
||||
return worker.messageHandler.sendWithPromise('GetDocRequest', {
|
||||
docId,
|
||||
apiVersion: '2.2.42',
|
||||
apiVersion: '2.2.51',
|
||||
source: {
|
||||
data: source.data,
|
||||
url: source.url,
|
||||
|
@ -3038,9 +3038,9 @@ const InternalRenderTask = function InternalRenderTaskClosure() {
|
|||
return InternalRenderTask;
|
||||
}();
|
||||
|
||||
const version = '2.2.42';
|
||||
const version = '2.2.51';
|
||||
exports.version = version;
|
||||
const build = '34022d2f';
|
||||
const build = 'c43396c2';
|
||||
exports.build = build;
|
||||
|
||||
/***/ }),
|
||||
|
@ -8457,6 +8457,14 @@ var renderTextLayer = function renderTextLayerClosure() {
|
|||
this._capability = (0, _util.createPromiseCapability)();
|
||||
this._renderTimer = null;
|
||||
this._bounds = [];
|
||||
|
||||
this._capability.promise.finally(() => {
|
||||
if (this._layoutTextCtx) {
|
||||
this._layoutTextCtx.canvas.width = 0;
|
||||
this._layoutTextCtx.canvas.height = 0;
|
||||
this._layoutTextCtx = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
TextLayerRenderTask.prototype = {
|
||||
|
@ -8465,20 +8473,20 @@ var renderTextLayer = function renderTextLayerClosure() {
|
|||
},
|
||||
|
||||
cancel: function TextLayer_cancel() {
|
||||
this._canceled = true;
|
||||
|
||||
if (this._reader) {
|
||||
this._reader.cancel(new _util.AbortException('text layer task cancelled'));
|
||||
this._reader.cancel(new _util.AbortException('TextLayer task cancelled.'));
|
||||
|
||||
this._reader = null;
|
||||
}
|
||||
|
||||
this._canceled = true;
|
||||
|
||||
if (this._renderTimer !== null) {
|
||||
clearTimeout(this._renderTimer);
|
||||
this._renderTimer = null;
|
||||
}
|
||||
|
||||
this._capability.reject('canceled');
|
||||
this._capability.reject(new Error('TextLayer task cancelled.'));
|
||||
},
|
||||
|
||||
_processItems(items, styleCache) {
|
||||
|
|
|
@ -123,8 +123,8 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
"use strict";
|
||||
|
||||
|
||||
const pdfjsVersion = '2.2.42';
|
||||
const pdfjsBuild = '34022d2f';
|
||||
const pdfjsVersion = '2.2.51';
|
||||
const pdfjsBuild = 'c43396c2';
|
||||
|
||||
const pdfjsCoreWorker = __w_pdfjs_require__(1);
|
||||
|
||||
|
@ -377,7 +377,7 @@ var WorkerMessageHandler = {
|
|||
var cancelXHRs = null;
|
||||
var WorkerTasks = [];
|
||||
let apiVersion = docParams.apiVersion;
|
||||
let workerVersion = '2.2.42';
|
||||
let workerVersion = '2.2.51';
|
||||
|
||||
if (apiVersion !== workerVersion) {
|
||||
throw new Error(`The API version "${apiVersion}" does not match ` + `the Worker version "${workerVersion}".`);
|
||||
|
@ -26752,17 +26752,19 @@ var Type1Font = function Type1FontClosure() {
|
|||
cff.strings = strings;
|
||||
cff.globalSubrIndex = new _cff_parser.CFFIndex();
|
||||
var count = glyphs.length;
|
||||
var charsetArray = [0];
|
||||
var charsetArray = ['.notdef'];
|
||||
var i, ii;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
var index = _cff_parser.CFFStandardStrings.indexOf(charstrings[i].glyphName);
|
||||
let glyphName = charstrings[i].glyphName;
|
||||
|
||||
let index = _cff_parser.CFFStandardStrings.indexOf(glyphName);
|
||||
|
||||
if (index === -1) {
|
||||
index = strings.add(charstrings[i].glyphName);
|
||||
strings.add(glyphName);
|
||||
}
|
||||
|
||||
charsetArray.push(index);
|
||||
charsetArray.push(glyphName);
|
||||
}
|
||||
|
||||
cff.charset = new _cff_parser.CFFCharset(false, 0, charsetArray);
|
||||
|
@ -27919,7 +27921,7 @@ var CFFStrings = function CFFStringsClosure() {
|
|||
return -1;
|
||||
},
|
||||
add: function CFFStrings_add(value) {
|
||||
return this.strings.push(value) + NUM_STANDARD_CFF_STRINGS - 1;
|
||||
this.strings.push(value);
|
||||
},
|
||||
|
||||
get count() {
|
||||
|
@ -28532,6 +28534,7 @@ var CFFCompiler = function CFFCompilerClosure() {
|
|||
out[0] = 0;
|
||||
let charsetIndex = 0;
|
||||
let numCharsets = charset.charset.length;
|
||||
let warned = false;
|
||||
|
||||
for (let i = 1; i < out.length; i += 2) {
|
||||
let sid = 0;
|
||||
|
@ -28542,7 +28545,11 @@ var CFFCompiler = function CFFCompilerClosure() {
|
|||
|
||||
if (sid === -1) {
|
||||
sid = 0;
|
||||
(0, _util.warn)(`Couldn't find ${name} in CFF strings`);
|
||||
|
||||
if (!warned) {
|
||||
warned = true;
|
||||
(0, _util.warn)(`Couldn't find ${name} in CFF strings`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ origin:
|
|||
|
||||
# Human-readable identifier for this version/release
|
||||
# Generally "version NNN", "tag SSS", "bookmark SSS"
|
||||
release: version 2.2.42
|
||||
release: version 2.2.51
|
||||
|
||||
# The package's license, where possible using the mnemonic from
|
||||
# https://spdx.org/licenses/
|
||||
|
|
|
@ -129,6 +129,8 @@ when there are no windows but Firefox is still running. -->
|
|||
<!ENTITY printCmd.label "Print…">
|
||||
<!ENTITY printCmd.accesskey "P">
|
||||
<!ENTITY printCmd.commandkey "p">
|
||||
<!ENTITY importFromAnotherBrowserCmd.label "Import from Another Browser…">
|
||||
<!ENTITY importFromAnotherBrowserCmd.accesskey "I">
|
||||
|
||||
<!ENTITY taskManagerCmd.label "Task Manager">
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "nsIScriptError.h"
|
||||
#include "nsIOutputStream.h"
|
||||
#include "nsIAsyncOutputStream.h"
|
||||
|
||||
using JS::SourceText;
|
||||
|
||||
|
@ -2870,7 +2870,7 @@ void ScriptLoader::EncodeRequestBytecode(JSContext* aCx,
|
|||
// Open the output stream to the cache entry alternate data storage. This
|
||||
// might fail if the stream is already open by another request, in which
|
||||
// case, we just ignore the current one.
|
||||
nsCOMPtr<nsIOutputStream> output;
|
||||
nsCOMPtr<nsIAsyncOutputStream> output;
|
||||
rv = aRequest->mCacheInfo->OpenAlternativeOutputStream(
|
||||
nsContentUtils::JSBytecodeMimeType(), aRequest->mScriptBytecode.length(),
|
||||
getter_AddRefs(output));
|
||||
|
@ -2882,8 +2882,9 @@ void ScriptLoader::EncodeRequestBytecode(JSContext* aCx,
|
|||
return;
|
||||
}
|
||||
MOZ_ASSERT(output);
|
||||
|
||||
auto closeOutStream = mozilla::MakeScopeExit([&]() {
|
||||
nsresult rv = output->Close();
|
||||
rv = output->CloseWithStatus(rv);
|
||||
LOG(("ScriptLoadRequest (%p): Closing (rv = %X)", aRequest, unsigned(rv)));
|
||||
});
|
||||
|
||||
|
|
|
@ -2337,19 +2337,6 @@ SkScalerContext* SkTypeface_Mac::onCreateScalerContext(const SkScalerContextEffe
|
|||
}
|
||||
|
||||
void SkTypeface_Mac::onFilterRec(SkScalerContextRec* rec) const {
|
||||
if (rec->fMaskFormat == SkMask::kLCD16_Format ||
|
||||
rec->fFlags & SkScalerContext::kGenA8FromLCD_Flag) {
|
||||
SkColor color = rec->getLuminanceColor();
|
||||
int r = SkColorGetR(color);
|
||||
int g = SkColorGetG(color);
|
||||
int b = SkColorGetB(color);
|
||||
// Choose whether to draw using a light-on-dark mask based on observed
|
||||
// color/luminance thresholds that CoreText uses.
|
||||
if (r >= 85 && g >= 85 && b >= 85 && r + g + b >= 2 * 255) {
|
||||
rec->fFlags |= SkScalerContext::kLightOnDark_Flag;
|
||||
}
|
||||
}
|
||||
|
||||
if (rec->fFlags & SkScalerContext::kLCD_BGROrder_Flag ||
|
||||
rec->fFlags & SkScalerContext::kLCD_Vertical_Flag)
|
||||
{
|
||||
|
@ -2431,6 +2418,21 @@ void SkTypeface_Mac::onFilterRec(SkScalerContextRec* rec) const {
|
|||
//CoreGraphics dialates smoothed text as needed.
|
||||
rec->setContrast(0);
|
||||
}
|
||||
|
||||
// Smoothing will be used if the format is either LCD or if there is hinting.
|
||||
// In those cases, we need to choose the proper dilation mask based on the color.
|
||||
if (rec->fMaskFormat == SkMask::kLCD16_Format ||
|
||||
(rec->fMaskFormat == SkMask::kA8_Format && rec->getHinting() != SkPaint::kNo_Hinting)) {
|
||||
SkColor color = rec->getLuminanceColor();
|
||||
int r = SkColorGetR(color);
|
||||
int g = SkColorGetG(color);
|
||||
int b = SkColorGetB(color);
|
||||
// Choose whether to draw using a light-on-dark mask based on observed
|
||||
// color/luminance thresholds that CoreText uses.
|
||||
if (r >= 85 && g >= 85 && b >= 85 && r + g + b >= 2 * 255) {
|
||||
rec->fFlags |= SkScalerContext::kLightOnDark_Flag;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Takes ownership of the CFStringRef. */
|
||||
|
|
|
@ -23,6 +23,7 @@ void brush_vs(
|
|||
#define BRUSH_FLAG_SEGMENT_REPEAT_X 4
|
||||
#define BRUSH_FLAG_SEGMENT_REPEAT_Y 8
|
||||
#define BRUSH_FLAG_TEXEL_RECT 16
|
||||
#define BRUSH_FLAG_SNAP_TO_PRIMITIVE 32
|
||||
|
||||
#define INVALID_SEGMENT_INDEX 0xffff
|
||||
|
||||
|
@ -63,13 +64,15 @@ void main(void) {
|
|||
|
||||
// Write the normal vertex information out.
|
||||
if (transform.is_axis_aligned) {
|
||||
bool snap_to_primitive = (brush_flags & BRUSH_FLAG_SNAP_TO_PRIMITIVE) != 0;
|
||||
vi = write_vertex(
|
||||
segment_rect,
|
||||
ph.local_clip_rect,
|
||||
ph.z,
|
||||
transform,
|
||||
pic_task,
|
||||
ph.local_rect
|
||||
ph.local_rect,
|
||||
snap_to_primitive
|
||||
);
|
||||
|
||||
// TODO(gw): transform bounds may be referenced by
|
||||
|
|
|
@ -94,7 +94,8 @@ VertexInfo write_vertex(RectWithSize instance_rect,
|
|||
float z,
|
||||
Transform transform,
|
||||
PictureTask task,
|
||||
RectWithSize snap_rect) {
|
||||
RectWithSize snap_rect,
|
||||
bool snap_to_primitive) {
|
||||
|
||||
// Select the corner of the local rect that we are processing.
|
||||
vec2 local_pos = instance_rect.p0 + instance_rect.size * aPosition.xy;
|
||||
|
@ -102,9 +103,16 @@ VertexInfo write_vertex(RectWithSize instance_rect,
|
|||
// Clamp to the two local clip rects.
|
||||
vec2 clamped_local_pos = clamp_rect(local_pos, local_clip_rect);
|
||||
|
||||
// Compute the visible rect to snap against. This ensures segments along the
|
||||
// edges are snapped consistently with other nearby primitives.
|
||||
RectWithSize visible_rect = intersect_rects(local_clip_rect, snap_rect);
|
||||
RectWithSize visible_rect;
|
||||
if (snap_to_primitive) {
|
||||
// We are producing a picture. The snap rect has already taken into
|
||||
// account the clipping we wish to consider for snapping purposes.
|
||||
visible_rect = snap_rect;
|
||||
} else {
|
||||
// Compute the visible rect to snap against. This ensures segments along
|
||||
// the edges are snapped consistently with other nearby primitives.
|
||||
visible_rect = intersect_rects(local_clip_rect, snap_rect);
|
||||
}
|
||||
|
||||
/// Compute the snapping offset.
|
||||
vec2 snap_offset = compute_snap_offset(
|
||||
|
|
|
@ -1072,12 +1072,19 @@ impl AlphaBatchBuilder {
|
|||
|
||||
match picture.raster_config {
|
||||
Some(ref raster_config) => {
|
||||
// All pictures must snap to their primitive rect instead of the
|
||||
// visible rect like most primitives. This is because the picture's
|
||||
// visible rect includes the effect of the picture's clip rect,
|
||||
// which was not considered by the picture's children. The primitive
|
||||
// rect however is simply the union of the visible rect of the
|
||||
// children, which they snapped to, which is precisely what we also
|
||||
// need to snap to in order to be consistent.
|
||||
let mut brush_flags = BrushFlags::SNAP_TO_PRIMITIVE;
|
||||
|
||||
// If the child picture was rendered in local space, we can safely
|
||||
// interpolate the UV coordinates with perspective correction.
|
||||
let brush_flags = if raster_config.establishes_raster_root {
|
||||
BrushFlags::PERSPECTIVE_INTERPOLATION
|
||||
} else {
|
||||
BrushFlags::empty()
|
||||
if raster_config.establishes_raster_root {
|
||||
brush_flags |= BrushFlags::PERSPECTIVE_INTERPOLATION;
|
||||
};
|
||||
|
||||
match raster_config.composite_mode {
|
||||
|
|
|
@ -332,6 +332,8 @@ bitflags! {
|
|||
const SEGMENT_REPEAT_Y = 0x8;
|
||||
/// The extra segment data is a texel rect.
|
||||
const SEGMENT_TEXEL_RECT = 0x10;
|
||||
/// Snap to the primitive rect instead of the visible rect.
|
||||
const SNAP_TO_PRIMITIVE = 0x20;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIOutputStream;
|
||||
interface nsIAsyncOutputStream;
|
||||
interface nsIInputStream;
|
||||
|
||||
%{C++
|
||||
|
@ -150,7 +150,10 @@ interface nsICacheInfoChannel : nsISupports
|
|||
* Must be called after the OnStopRequest that delivered the real data.
|
||||
* The consumer may choose to replace the saved alt representation.
|
||||
* Opening the output stream will fail if there are any open input streams
|
||||
* reading the already saved alt representation.
|
||||
* reading the already saved alt representation. After successfully opening
|
||||
* an output stream, if there is an error before the entire alt data can be
|
||||
* written successfully, the client must signal failure by passing an error
|
||||
* code to CloseWithStatus().
|
||||
*
|
||||
* @param type
|
||||
* type of the alternative data representation
|
||||
|
@ -160,5 +163,5 @@ interface nsICacheInfoChannel : nsISupports
|
|||
* an error is thrown. If the size isn't known in advance, -1 should be
|
||||
* passed.
|
||||
*/
|
||||
nsIOutputStream openAlternativeOutputStream(in ACString type, in long long predictedSize);
|
||||
nsIAsyncOutputStream openAlternativeOutputStream(in ACString type, in long long predictedSize);
|
||||
};
|
||||
|
|
|
@ -1223,9 +1223,9 @@ nsresult CacheEntry::OpenOutputStream(int64_t offset, int64_t predictedSize,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult CacheEntry::OpenAlternativeOutputStream(const nsACString &type,
|
||||
int64_t predictedSize,
|
||||
nsIOutputStream **_retval) {
|
||||
nsresult CacheEntry::OpenAlternativeOutputStream(
|
||||
const nsACString &type, int64_t predictedSize,
|
||||
nsIAsyncOutputStream **_retval) {
|
||||
LOG(("CacheEntry::OpenAlternativeOutputStream [this=%p, type=%s]", this,
|
||||
PromiseFlatCString(type).get()));
|
||||
|
||||
|
@ -1248,7 +1248,7 @@ nsresult CacheEntry::OpenAlternativeOutputStream(const nsACString &type,
|
|||
return NS_ERROR_FILE_TOO_BIG;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIOutputStream> stream;
|
||||
nsCOMPtr<nsIAsyncOutputStream> stream;
|
||||
rv = mFile->OpenAlternativeOutputStream(
|
||||
nullptr, PromiseFlatCString(type).get(), getter_AddRefs(stream));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
|
|
@ -94,7 +94,7 @@ class CacheEntry final : public nsIRunnable, public CacheFileListener {
|
|||
nsresult GetAltDataType(nsACString &aAltDataType);
|
||||
nsresult OpenAlternativeOutputStream(const nsACString &type,
|
||||
int64_t predictedSize,
|
||||
nsIOutputStream **_retval);
|
||||
nsIAsyncOutputStream **_retval);
|
||||
nsresult OpenAlternativeInputStream(const nsACString &type,
|
||||
nsIInputStream **_retval);
|
||||
nsresult GetLoadContextInfo(nsILoadContextInfo **aLoadContextInfo);
|
||||
|
@ -516,9 +516,9 @@ class CacheEntryHandle final : public nsICacheEntry {
|
|||
NS_IMETHOD GetAltDataType(nsACString &aType) override {
|
||||
return mEntry->GetAltDataType(aType);
|
||||
}
|
||||
NS_IMETHOD OpenAlternativeOutputStream(const nsACString &type,
|
||||
int64_t predictedSize,
|
||||
nsIOutputStream **_retval) override {
|
||||
NS_IMETHOD OpenAlternativeOutputStream(
|
||||
const nsACString &type, int64_t predictedSize,
|
||||
nsIAsyncOutputStream **_retval) override {
|
||||
return mEntry->OpenAlternativeOutputStream(type, predictedSize, _retval);
|
||||
}
|
||||
NS_IMETHOD OpenAlternativeInputStream(const nsACString &type,
|
||||
|
|
|
@ -902,7 +902,7 @@ nsresult CacheFile::OpenOutputStream(CacheOutputCloseListener *aCloseListener,
|
|||
|
||||
nsresult CacheFile::OpenAlternativeOutputStream(
|
||||
CacheOutputCloseListener *aCloseListener, const char *aAltDataType,
|
||||
nsIOutputStream **_retval) {
|
||||
nsIAsyncOutputStream **_retval) {
|
||||
CacheFileAutoLock lock(this);
|
||||
|
||||
MOZ_ASSERT(mHandle || mMemoryOnly || mOpeningFile);
|
||||
|
|
|
@ -81,7 +81,7 @@ class CacheFile final : public CacheFileChunkListener,
|
|||
nsIOutputStream **_retval);
|
||||
NS_IMETHOD OpenAlternativeOutputStream(
|
||||
CacheOutputCloseListener *aCloseListener, const char *aAltDataType,
|
||||
nsIOutputStream **_retval);
|
||||
nsIAsyncOutputStream **_retval);
|
||||
NS_IMETHOD SetMemoryOnly();
|
||||
NS_IMETHOD Doom(CacheFileListener *aCallback);
|
||||
|
||||
|
|
|
@ -42,9 +42,9 @@ class _OldCacheEntryWrapper : public nsICacheEntry {
|
|||
return !mOldDesc ? NS_ERROR_NULL_POINTER
|
||||
: mOldDesc->OpenOutputStream(offset, _retval);
|
||||
}
|
||||
NS_IMETHOD OpenAlternativeOutputStream(const nsACString &type,
|
||||
int64_t predictedSize,
|
||||
nsIOutputStream **_retval) override {
|
||||
NS_IMETHOD OpenAlternativeOutputStream(
|
||||
const nsACString &type, int64_t predictedSize,
|
||||
nsIAsyncOutputStream **_retval) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
NS_IMETHOD OpenAlternativeInputStream(const nsACString &type,
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
interface nsIInputStream;
|
||||
interface nsIOutputStream;
|
||||
interface nsIAsyncOutputStream;
|
||||
interface nsICacheEntryDoomCallback;
|
||||
|
||||
interface nsICacheListener;
|
||||
|
@ -265,7 +266,7 @@ interface nsICacheEntry : nsISupports
|
|||
*
|
||||
* If there is alt-data already saved, it will be overwritten.
|
||||
*/
|
||||
nsIOutputStream openAlternativeOutputStream(in ACString type, in long long predictedSize);
|
||||
nsIAsyncOutputStream openAlternativeOutputStream(in ACString type, in long long predictedSize);
|
||||
|
||||
/**
|
||||
* Opens and returns an input stream that can be used to read the alternative
|
||||
|
|
|
@ -357,7 +357,7 @@ PAltDataOutputStreamParent* NeckoParent::AllocPAltDataOutputStreamParent(
|
|||
const nsCString& type, const int64_t& predictedSize,
|
||||
PHttpChannelParent* channel) {
|
||||
HttpChannelParent* chan = static_cast<HttpChannelParent*>(channel);
|
||||
nsCOMPtr<nsIOutputStream> stream;
|
||||
nsCOMPtr<nsIAsyncOutputStream> stream;
|
||||
nsresult rv = chan->OpenAlternativeOutputStream(type, predictedSize,
|
||||
getter_AddRefs(stream));
|
||||
AltDataOutputStreamParent* parent = new AltDataOutputStreamParent(stream);
|
||||
|
|
|
@ -3076,7 +3076,7 @@ HttpChannelChild::GetAlternativeDataType(nsACString& aType) {
|
|||
NS_IMETHODIMP
|
||||
HttpChannelChild::OpenAlternativeOutputStream(const nsACString& aType,
|
||||
int64_t aPredictedSize,
|
||||
nsIOutputStream** _retval) {
|
||||
nsIAsyncOutputStream** _retval) {
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Main thread only");
|
||||
|
||||
if (mSynthesizedCacheInfo) {
|
||||
|
|
|
@ -2353,7 +2353,8 @@ void HttpChannelParent::NotifyDiversionFailed(nsresult aErrorCode) {
|
|||
}
|
||||
|
||||
nsresult HttpChannelParent::OpenAlternativeOutputStream(
|
||||
const nsACString& type, int64_t predictedSize, nsIOutputStream** _retval) {
|
||||
const nsACString& type, int64_t predictedSize,
|
||||
nsIAsyncOutputStream** _retval) {
|
||||
// We need to make sure the child does not call SendDocumentChannelCleanup()
|
||||
// before opening the altOutputStream, because that clears mCacheEntry.
|
||||
if (!mCacheEntry) {
|
||||
|
|
|
@ -101,9 +101,9 @@ class HttpChannelParent final : public nsIInterfaceRequestor,
|
|||
}
|
||||
}
|
||||
|
||||
MOZ_MUST_USE nsresult OpenAlternativeOutputStream(const nsACString& type,
|
||||
int64_t predictedSize,
|
||||
nsIOutputStream** _retval);
|
||||
MOZ_MUST_USE nsresult
|
||||
OpenAlternativeOutputStream(const nsACString& type, int64_t predictedSize,
|
||||
nsIAsyncOutputStream** _retval);
|
||||
|
||||
// Callbacks for each asynchronous tasks required in AsyncOpen
|
||||
// procedure, will call InvokeAsyncOpen when all the expected
|
||||
|
|
|
@ -1265,9 +1265,9 @@ InterceptedHttpChannel::GetAlternativeDataType(nsACString& aType) {
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
InterceptedHttpChannel::OpenAlternativeOutputStream(const nsACString& type,
|
||||
int64_t predictedSize,
|
||||
nsIOutputStream** _retval) {
|
||||
InterceptedHttpChannel::OpenAlternativeOutputStream(
|
||||
const nsACString& type, int64_t predictedSize,
|
||||
nsIAsyncOutputStream** _retval) {
|
||||
if (mSynthesizedCacheInfo) {
|
||||
return mSynthesizedCacheInfo->OpenAlternativeOutputStream(
|
||||
type, predictedSize, _retval);
|
||||
|
|
|
@ -8377,7 +8377,7 @@ nsHttpChannel::GetAlternativeDataType(nsACString &aType) {
|
|||
NS_IMETHODIMP
|
||||
nsHttpChannel::OpenAlternativeOutputStream(const nsACString &type,
|
||||
int64_t predictedSize,
|
||||
nsIOutputStream **_retval) {
|
||||
nsIAsyncOutputStream **_retval) {
|
||||
// OnStopRequest will clear mCacheEntry, but we may use mAltDataCacheEntry
|
||||
// if the consumer called PreferAlternativeDataType()
|
||||
nsCOMPtr<nsICacheEntry> cacheEntry =
|
||||
|
|
|
@ -84,6 +84,7 @@ def create_tar_gz_from_files(fp, files, filename=None, compresslevel=9):
|
|||
|
||||
class _BZ2Proxy(object):
|
||||
"""File object that proxies writes to a bz2 compressor."""
|
||||
|
||||
def __init__(self, fp, compresslevel=9):
|
||||
self.fp = fp
|
||||
self.compressor = bz2.BZ2Compressor(compresslevel=compresslevel)
|
||||
|
|
|
@ -17,6 +17,7 @@ class Flag(object):
|
|||
"flag=yes|true|1"
|
||||
"flag=no|false|0"
|
||||
'''
|
||||
|
||||
def __init__(self, name):
|
||||
'''
|
||||
Initialize a Flag with the given name.
|
||||
|
@ -72,6 +73,7 @@ class StringFlag(object):
|
|||
"flag=string"
|
||||
"flag!=string"
|
||||
'''
|
||||
|
||||
def __init__(self, name):
|
||||
'''
|
||||
Initialize a StringFlag with the given name.
|
||||
|
@ -141,6 +143,7 @@ class VersionFlag(object):
|
|||
"flag>=version"
|
||||
"flag>version"
|
||||
'''
|
||||
|
||||
def __init__(self, name):
|
||||
'''
|
||||
Initialize a VersionFlag with the given name.
|
||||
|
@ -237,10 +240,10 @@ class Flags(OrderedDict):
|
|||
for f in flags:
|
||||
name = self.RE.split(f)
|
||||
name = name[0]
|
||||
if not name in self.FLAGS:
|
||||
if name not in self.FLAGS:
|
||||
errors.fatal('Unknown flag: %s' % name)
|
||||
continue
|
||||
if not name in self:
|
||||
if name not in self:
|
||||
self[name] = self.FLAGS[name](name)
|
||||
self[name].add_definition(f)
|
||||
|
||||
|
@ -260,7 +263,7 @@ class Flags(OrderedDict):
|
|||
flags.match(application='foo', appversion='3.0') returns False
|
||||
'''
|
||||
for name, value in filter.iteritems():
|
||||
if not name in self:
|
||||
if name not in self:
|
||||
continue
|
||||
if not self[name].matches(value):
|
||||
return False
|
||||
|
|
|
@ -55,7 +55,7 @@ class ManifestEntry(object):
|
|||
if not all(f in self.allowed_flags for f in self.flags):
|
||||
errors.fatal('%s unsupported for %s manifest entries' %
|
||||
(','.join(f for f in self.flags
|
||||
if not f in self.allowed_flags), self.type))
|
||||
if f not in self.allowed_flags), self.type))
|
||||
|
||||
def serialize(self, *args):
|
||||
'''
|
||||
|
@ -96,6 +96,7 @@ class ManifestEntryWithRelPath(ManifestEntry):
|
|||
'''
|
||||
Abstract manifest entry type with a relative path definition.
|
||||
'''
|
||||
|
||||
def __init__(self, base, relpath, *flags):
|
||||
ManifestEntry.__init__(self, base, *flags)
|
||||
self.relpath = relpath
|
||||
|
@ -115,7 +116,7 @@ class ManifestEntryWithRelPath(ManifestEntry):
|
|||
@property
|
||||
def path(self):
|
||||
return mozpath.normpath(mozpath.join(self.base,
|
||||
self.relpath))
|
||||
self.relpath))
|
||||
|
||||
|
||||
class Manifest(ManifestEntryWithRelPath):
|
||||
|
@ -130,6 +131,7 @@ class ManifestChrome(ManifestEntryWithRelPath):
|
|||
'''
|
||||
Abstract class for chrome entries.
|
||||
'''
|
||||
|
||||
def __init__(self, base, name, relpath, *flags):
|
||||
ManifestEntryWithRelPath.__init__(self, base, relpath, *flags)
|
||||
self.name = name
|
||||
|
@ -320,10 +322,11 @@ class ManifestContract(ManifestEntry):
|
|||
def __str__(self):
|
||||
return self.serialize(self.contractID, self.cid)
|
||||
|
||||
|
||||
# All manifest classes by their type name.
|
||||
MANIFESTS_TYPES = dict([(c.type, c) for c in globals().values()
|
||||
if type(c) == type and issubclass(c, ManifestEntry)
|
||||
and hasattr(c, 'type') and c.type])
|
||||
if type(c) == type and issubclass(c, ManifestEntry)
|
||||
and hasattr(c, 'type') and c.type])
|
||||
|
||||
MANIFEST_RE = re.compile(r'^#.*$')
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ class FileRegistry(object):
|
|||
items = self.match(pattern)
|
||||
if not items:
|
||||
return errors.error("Can't remove %s: %s" % (pattern,
|
||||
"not matching anything previously added"))
|
||||
"not matching anything previously added"))
|
||||
for i in items:
|
||||
del self._files[i]
|
||||
self._required_directories.subtract(self._partial_paths(i))
|
||||
|
@ -262,6 +262,7 @@ class FileCopier(FileRegistry):
|
|||
FileRegistry with the ability to copy the registered files to a separate
|
||||
directory.
|
||||
'''
|
||||
|
||||
def copy(self, destination, skip_if_older=True,
|
||||
remove_unaccounted=True,
|
||||
remove_all_directory_symlinks=True,
|
||||
|
@ -319,7 +320,7 @@ class FileCopier(FileRegistry):
|
|||
|
||||
required_dirs = set([destination])
|
||||
required_dirs |= set(os.path.normpath(os.path.join(destination, d))
|
||||
for d in self.required_directories())
|
||||
for d in self.required_directories())
|
||||
|
||||
# Ensure destination directories are in place and proper.
|
||||
#
|
||||
|
@ -364,7 +365,7 @@ class FileCopier(FileRegistry):
|
|||
for p in remove_unaccounted.paths())
|
||||
existing_dirs = set(os.path.normpath(os.path.join(destination, p))
|
||||
for p in remove_unaccounted
|
||||
.required_directories())
|
||||
.required_directories())
|
||||
existing_dirs |= {os.path.normpath(destination)}
|
||||
else:
|
||||
# While we have remove_unaccounted, it doesn't apply to empty
|
||||
|
@ -423,7 +424,7 @@ class FileCopier(FileRegistry):
|
|||
destfile = os.path.normpath(os.path.join(destination, p))
|
||||
fs.append((destfile, e.submit(f.copy, destfile, skip_if_older)))
|
||||
|
||||
copy_results = [(destfile, f.result) for destfile, f in fs]
|
||||
copy_results = [(path, f.result) for path, f in fs]
|
||||
else:
|
||||
for p, f in self:
|
||||
destfile = os.path.normpath(os.path.join(destination, p))
|
||||
|
@ -507,6 +508,7 @@ class Jarrer(FileRegistry, BaseFile):
|
|||
FileRegistry with the ability to copy and pack the registered files as a
|
||||
jar file. Also acts as a BaseFile instance, to be copied with a FileCopier.
|
||||
'''
|
||||
|
||||
def __init__(self, compress=True):
|
||||
'''
|
||||
Create a Jarrer instance. See mozpack.mozjar.JarWriter documentation
|
||||
|
@ -540,6 +542,7 @@ class Jarrer(FileRegistry, BaseFile):
|
|||
dest.write(data) # Creates a Deflater and write data there
|
||||
dest.read() # Re-opens the Deflater and reads from it
|
||||
'''
|
||||
|
||||
def __init__(self, orig=None, compress=True):
|
||||
self.mode = None
|
||||
self.deflater = orig
|
||||
|
|
|
@ -24,6 +24,7 @@ UNKNOWN = 0
|
|||
MACHO = 1
|
||||
ELF = 2
|
||||
|
||||
|
||||
def get_type(path):
|
||||
'''
|
||||
Check the signature of the give file and returns what kind of executable
|
||||
|
@ -108,8 +109,8 @@ def may_elfhack(path):
|
|||
# the right flag, but checking the file extension works too.
|
||||
from buildconfig import substs
|
||||
return ('USE_ELF_HACK' in substs and substs['USE_ELF_HACK'] and
|
||||
path.endswith(substs['DLL_SUFFIX']) and
|
||||
'COMPILE_ENVIRONMENT' in substs and substs['COMPILE_ENVIRONMENT'])
|
||||
path.endswith(substs['DLL_SUFFIX']) and
|
||||
'COMPILE_ENVIRONMENT' in substs and substs['COMPILE_ENVIRONMENT'])
|
||||
|
||||
|
||||
def elfhack(path):
|
||||
|
@ -131,7 +132,7 @@ def xz_compress(path):
|
|||
if open(path, 'rb').read(5)[1:] == '7zXZ':
|
||||
print('%s is already compressed' % path)
|
||||
return
|
||||
|
||||
|
||||
from buildconfig import substs
|
||||
xz = substs.get('XZ')
|
||||
cmd = [xz, '-zkf', path]
|
||||
|
|
|
@ -70,6 +70,7 @@ else:
|
|||
else:
|
||||
raise TypeError('mismatched path types!')
|
||||
|
||||
|
||||
class Dest(object):
|
||||
'''
|
||||
Helper interface for BaseFile.copy. The interface works as follows:
|
||||
|
@ -80,6 +81,7 @@ class Dest(object):
|
|||
- a call to write() after a read() will re-open the underlying file,
|
||||
emptying it, and write to it.
|
||||
'''
|
||||
|
||||
def __init__(self, path):
|
||||
self.path = path
|
||||
self.mode = None
|
||||
|
@ -126,7 +128,7 @@ class BaseFile(object):
|
|||
# shutil.copystat only copies milliseconds, and seconds is not
|
||||
# enough precision.
|
||||
return int(os.path.getmtime(first) * 1000) \
|
||||
<= int(os.path.getmtime(second) * 1000)
|
||||
<= int(os.path.getmtime(second) * 1000)
|
||||
|
||||
@staticmethod
|
||||
def any_newer(dest, inputs):
|
||||
|
@ -155,7 +157,7 @@ class BaseFile(object):
|
|||
ret |= 0o0444
|
||||
if mode & 0o0100:
|
||||
ret |= 0o0111
|
||||
# - keep user write permissions
|
||||
# - keep user write permissions
|
||||
if mode & 0o0200:
|
||||
ret |= 0o0200
|
||||
# - leave away sticky bit, setuid, setgid
|
||||
|
@ -251,6 +253,7 @@ class File(BaseFile):
|
|||
'''
|
||||
File class for plain files.
|
||||
'''
|
||||
|
||||
def __init__(self, path):
|
||||
self.path = path
|
||||
|
||||
|
@ -282,6 +285,7 @@ class ExecutableFile(File):
|
|||
File class for executable and library files on OS/2, OS/X and ELF systems.
|
||||
(see mozpack.executables.is_executable documentation).
|
||||
'''
|
||||
|
||||
def __init__(self, path, xz_compress=False):
|
||||
File.__init__(self, path)
|
||||
self.xz_compress = xz_compress
|
||||
|
@ -479,6 +483,7 @@ class ExistingFile(BaseFile):
|
|||
existing file is required, it must exist during copy() or an error is
|
||||
raised.
|
||||
'''
|
||||
|
||||
def __init__(self, required):
|
||||
self.required = required
|
||||
|
||||
|
@ -493,7 +498,7 @@ class ExistingFile(BaseFile):
|
|||
|
||||
if not dest.exists():
|
||||
errors.fatal("Required existing file doesn't exist: %s" %
|
||||
dest.path)
|
||||
dest.path)
|
||||
|
||||
def inputs(self):
|
||||
return ()
|
||||
|
@ -504,6 +509,7 @@ class PreprocessedFile(BaseFile):
|
|||
File class for a file that is preprocessed. PreprocessedFile.copy() runs
|
||||
the preprocessor on the file to create the output.
|
||||
'''
|
||||
|
||||
def __init__(self, path, depfile_path, marker, defines, extra_depends=None,
|
||||
silence_missing_directive_warnings=False):
|
||||
self.path = path
|
||||
|
@ -588,6 +594,7 @@ class GeneratedFile(BaseFile):
|
|||
'''
|
||||
File class for content with no previous existence on the filesystem.
|
||||
'''
|
||||
|
||||
def __init__(self, content):
|
||||
self._content = content
|
||||
|
||||
|
@ -619,6 +626,7 @@ class DeflatedFile(BaseFile):
|
|||
File class for members of a jar archive. DeflatedFile.copy() effectively
|
||||
extracts the file from the jar archive.
|
||||
'''
|
||||
|
||||
def __init__(self, file):
|
||||
from mozpack.mozjar import JarFileReader
|
||||
assert isinstance(file, JarFileReader)
|
||||
|
@ -628,11 +636,13 @@ class DeflatedFile(BaseFile):
|
|||
self.file.seek(0)
|
||||
return self.file
|
||||
|
||||
|
||||
class ExtractedTarFile(GeneratedFile):
|
||||
'''
|
||||
File class for members of a tar archive. Contents of the underlying file
|
||||
are extracted immediately and stored in memory.
|
||||
'''
|
||||
|
||||
def __init__(self, tar, info):
|
||||
assert isinstance(info, TarInfo)
|
||||
assert isinstance(tar, TarFile)
|
||||
|
@ -646,6 +656,7 @@ class ExtractedTarFile(GeneratedFile):
|
|||
def read(self):
|
||||
return self.content
|
||||
|
||||
|
||||
class ManifestFile(BaseFile):
|
||||
'''
|
||||
File class for a manifest file. It takes individual manifest entries (using
|
||||
|
@ -661,6 +672,7 @@ class ManifestFile(BaseFile):
|
|||
time, e.g. to jar:foobar/omni.ja!/chrome.manifest, which we don't do
|
||||
currently but could in the future.
|
||||
'''
|
||||
|
||||
def __init__(self, base, entries=None):
|
||||
self._base = base
|
||||
self._entries = []
|
||||
|
@ -716,6 +728,7 @@ class MinifiedProperties(BaseFile):
|
|||
File class for minified properties. This wraps around a BaseFile instance,
|
||||
and removes lines starting with a # from its content.
|
||||
'''
|
||||
|
||||
def __init__(self, file):
|
||||
assert isinstance(file, BaseFile)
|
||||
self._file = file
|
||||
|
@ -733,6 +746,7 @@ class MinifiedJavaScript(BaseFile):
|
|||
'''
|
||||
File class for minifying JavaScript files.
|
||||
'''
|
||||
|
||||
def __init__(self, file, verify_command=None):
|
||||
assert isinstance(file, BaseFile)
|
||||
self._file = file
|
||||
|
@ -762,7 +776,7 @@ class MinifiedJavaScript(BaseFile):
|
|||
subprocess.check_output(args, stderr=subprocess.STDOUT)
|
||||
except subprocess.CalledProcessError as e:
|
||||
errors.warn('JS minification verification failed for %s:' %
|
||||
(getattr(self._file, 'path', '<unknown>')))
|
||||
(getattr(self._file, 'path', '<unknown>')))
|
||||
# Prefix each line with "Warning:" so mozharness doesn't
|
||||
# think these error messages are real errors.
|
||||
for line in e.output.splitlines():
|
||||
|
@ -775,7 +789,7 @@ class MinifiedJavaScript(BaseFile):
|
|||
|
||||
class BaseFinder(object):
|
||||
def __init__(self, base, minify=False, minify_js=False,
|
||||
minify_js_verify_command=None):
|
||||
minify_js_verify_command=None):
|
||||
'''
|
||||
Initializes the instance with a reference base directory.
|
||||
|
||||
|
@ -895,6 +909,7 @@ class FileFinder(BaseFinder):
|
|||
'''
|
||||
Helper to get appropriate BaseFile instances from the file system.
|
||||
'''
|
||||
|
||||
def __init__(self, base, find_executables=False, ignore=(),
|
||||
find_dotfiles=False, **kargs):
|
||||
'''
|
||||
|
@ -1010,6 +1025,7 @@ class JarFinder(BaseFinder):
|
|||
'''
|
||||
Helper to get appropriate DeflatedFile instances from a JarReader.
|
||||
'''
|
||||
|
||||
def __init__(self, base, reader, **kargs):
|
||||
'''
|
||||
Create a JarFinder for files in the given JarReader. The base argument
|
||||
|
@ -1032,6 +1048,7 @@ class TarFinder(BaseFinder):
|
|||
'''
|
||||
Helper to get files from a TarFile.
|
||||
'''
|
||||
|
||||
def __init__(self, base, tar, **kargs):
|
||||
'''
|
||||
Create a TarFinder for files in the given TarFile. The base argument
|
||||
|
@ -1062,6 +1079,7 @@ class ComposedFinder(BaseFinder):
|
|||
Note this could be optimized to be smarter than getting all the files
|
||||
in advance.
|
||||
'''
|
||||
|
||||
def __init__(self, finders):
|
||||
# Can't import globally, because of the dependency of mozpack.copier
|
||||
# on this module.
|
||||
|
@ -1081,6 +1099,7 @@ class ComposedFinder(BaseFinder):
|
|||
|
||||
class MercurialFile(BaseFile):
|
||||
"""File class for holding data from Mercurial."""
|
||||
|
||||
def __init__(self, client, rev, path):
|
||||
self._content = client.cat([path], rev=rev)
|
||||
|
||||
|
|
|
@ -124,7 +124,7 @@ class InstallManifest(object):
|
|||
version = fileobj.readline().rstrip()
|
||||
if version not in ('1', '2', '3', '4', '5'):
|
||||
raise UnreadableInstallManifest('Unknown manifest version: %s' %
|
||||
version)
|
||||
version)
|
||||
|
||||
for line in fileobj:
|
||||
line = line.rstrip()
|
||||
|
@ -167,8 +167,8 @@ class InstallManifest(object):
|
|||
dest, source, deps, marker, defines, warnings = fields[1:]
|
||||
|
||||
self.add_preprocess(source, dest, deps, marker,
|
||||
self._decode_field_entry(defines),
|
||||
silence_missing_directive_warnings=bool(int(warnings)))
|
||||
self._decode_field_entry(defines),
|
||||
silence_missing_directive_warnings=bool(int(warnings)))
|
||||
continue
|
||||
|
||||
if record_type == self.CONTENT:
|
||||
|
@ -182,7 +182,7 @@ class InstallManifest(object):
|
|||
# forward-compatibility with those we will add in the future.
|
||||
if record_type >= 0:
|
||||
raise UnreadableInstallManifest('Unknown record type: %d' %
|
||||
record_type)
|
||||
record_type)
|
||||
|
||||
def __len__(self):
|
||||
return len(self._dests)
|
||||
|
@ -294,7 +294,7 @@ class InstallManifest(object):
|
|||
<base>/foo/bar.h -> <dest>/foo/bar.h
|
||||
"""
|
||||
self._add_entry(mozpath.join(dest, pattern),
|
||||
(self.PATTERN_LINK, base, pattern, dest))
|
||||
(self.PATTERN_LINK, base, pattern, dest))
|
||||
|
||||
def add_pattern_copy(self, base, pattern, dest):
|
||||
"""Add a pattern match that results in copies.
|
||||
|
@ -302,7 +302,7 @@ class InstallManifest(object):
|
|||
See ``add_pattern_link()`` for usage.
|
||||
"""
|
||||
self._add_entry(mozpath.join(dest, pattern),
|
||||
(self.PATTERN_COPY, base, pattern, dest))
|
||||
(self.PATTERN_COPY, base, pattern, dest))
|
||||
|
||||
def add_preprocess(self, source, dest, deps, marker='#', defines={},
|
||||
silence_missing_directive_warnings=False):
|
||||
|
@ -427,12 +427,14 @@ class InstallManifest(object):
|
|||
defines = self._decode_field_entry(entry[4])
|
||||
if defines_override:
|
||||
defines.update(defines_override)
|
||||
registry.add(dest, PreprocessedFile(entry[1],
|
||||
depfile_path=entry[2],
|
||||
marker=entry[3],
|
||||
defines=defines,
|
||||
extra_depends=self._source_files,
|
||||
silence_missing_directive_warnings=bool(int(entry[5]))))
|
||||
registry.add(dest, PreprocessedFile(
|
||||
entry[1],
|
||||
depfile_path=entry[2],
|
||||
marker=entry[3],
|
||||
defines=defines,
|
||||
extra_depends=self._source_files,
|
||||
silence_missing_directive_warnings=bool(int(entry[5])),
|
||||
))
|
||||
|
||||
continue
|
||||
|
||||
|
@ -444,4 +446,4 @@ class InstallManifest(object):
|
|||
continue
|
||||
|
||||
raise Exception('Unknown install type defined in manifest: %d' %
|
||||
install_type)
|
||||
install_type)
|
||||
|
|
|
@ -73,7 +73,7 @@ class JarStruct(object):
|
|||
'''
|
||||
assert self.MAGIC and isinstance(self.STRUCT, OrderedDict)
|
||||
self.size_fields = set(t for t in self.STRUCT.itervalues()
|
||||
if not t in JarStruct.TYPE_MAPPING)
|
||||
if t not in JarStruct.TYPE_MAPPING)
|
||||
self._values = {}
|
||||
if data:
|
||||
self._init_data(data)
|
||||
|
@ -102,7 +102,7 @@ class JarStruct(object):
|
|||
value = data[offset:offset + size]
|
||||
if isinstance(value, memoryview):
|
||||
value = value.tobytes()
|
||||
if not name in sizes:
|
||||
if name not in sizes:
|
||||
self._values[name] = value
|
||||
else:
|
||||
sizes[name] = value
|
||||
|
@ -139,7 +139,7 @@ class JarStruct(object):
|
|||
'''
|
||||
serialized = struct.pack('<I', self.signature)
|
||||
sizes = dict((t, name) for name, t in self.STRUCT.iteritems()
|
||||
if not t in JarStruct.TYPE_MAPPING)
|
||||
if t not in JarStruct.TYPE_MAPPING)
|
||||
for name, t in self.STRUCT.iteritems():
|
||||
if t in JarStruct.TYPE_MAPPING:
|
||||
format, size = JarStruct.TYPE_MAPPING[t]
|
||||
|
@ -170,7 +170,7 @@ class JarStruct(object):
|
|||
return self._values[key]
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
if not key in self.STRUCT:
|
||||
if key not in self.STRUCT:
|
||||
raise KeyError(key)
|
||||
if key in self.size_fields:
|
||||
raise AttributeError("can't set attribute")
|
||||
|
@ -203,6 +203,7 @@ class JarCdirEnd(JarStruct):
|
|||
('comment', 'comment_size'),
|
||||
])
|
||||
|
||||
|
||||
CDIR_END_SIZE = JarCdirEnd().size
|
||||
|
||||
|
||||
|
@ -260,6 +261,7 @@ class JarFileReader(object):
|
|||
File-like class for use by JarReader to give access to individual files
|
||||
within a Jar archive.
|
||||
'''
|
||||
|
||||
def __init__(self, header, data):
|
||||
'''
|
||||
Initialize a JarFileReader. header is the local file header
|
||||
|
@ -341,6 +343,7 @@ class JarReader(object):
|
|||
Class with methods to read Jar files. Can open standard jar files as well
|
||||
as Mozilla jar files (see further details in the JarWriter documentation).
|
||||
'''
|
||||
|
||||
def __init__(self, file=None, fileobj=None, data=None):
|
||||
'''
|
||||
Opens the given file as a Jar archive. Use the given file-like object
|
||||
|
@ -474,6 +477,7 @@ class JarWriter(object):
|
|||
archives as well as jar archives optimized for Gecko. See the documentation
|
||||
for the close() member function for a description of both layouts.
|
||||
'''
|
||||
|
||||
def __init__(self, file=None, fileobj=None, compress=True, compress_level=9):
|
||||
'''
|
||||
Initialize a Jar archive in the given file. Use the given file-like
|
||||
|
@ -614,7 +618,7 @@ class JarWriter(object):
|
|||
compress = JAR_DEFLATED
|
||||
if compress is False:
|
||||
compress = JAR_STORED
|
||||
if (isinstance(data, (JarFileReader, Deflater)) and \
|
||||
if (isinstance(data, (JarFileReader, Deflater)) and
|
||||
data.compress == compress):
|
||||
deflater = data
|
||||
else:
|
||||
|
@ -661,12 +665,12 @@ class JarWriter(object):
|
|||
'''
|
||||
new_contents = OrderedDict()
|
||||
for f in files:
|
||||
if not f in self._contents:
|
||||
if f not in self._contents:
|
||||
continue
|
||||
new_contents[f] = self._contents[f]
|
||||
self._last_preloaded = f
|
||||
for f in self._contents:
|
||||
if not f in new_contents:
|
||||
if f not in new_contents:
|
||||
new_contents[f] = self._contents[f]
|
||||
self._contents = new_contents
|
||||
|
||||
|
@ -677,6 +681,7 @@ class Deflater(object):
|
|||
compressed unless the compressed form is smaller than the uncompressed
|
||||
data.
|
||||
'''
|
||||
|
||||
def __init__(self, compress=True, compress_level=9):
|
||||
'''
|
||||
Initialize a Deflater. The compress argument determines how to
|
||||
|
@ -789,9 +794,9 @@ class Brotli(object):
|
|||
@staticmethod
|
||||
@memoize
|
||||
def brotli_tool():
|
||||
from buildconfig import topobjdir, substs
|
||||
return os.path.join(topobjdir, 'dist', 'host', 'bin',
|
||||
'bro' + substs.get('BIN_SUFFIX', ''))
|
||||
from buildconfig import topobjdir, substs
|
||||
return os.path.join(topobjdir, 'dist', 'host', 'bin',
|
||||
'bro' + substs.get('BIN_SUFFIX', ''))
|
||||
|
||||
@staticmethod
|
||||
def run_brotli_tool(args, input):
|
||||
|
@ -813,7 +818,6 @@ class Brotli(object):
|
|||
return Brotli.run_brotli_tool(['--decompress'], data)
|
||||
|
||||
|
||||
|
||||
class BrotliCompress(object):
|
||||
def __init__(self):
|
||||
self._buf = BytesIO()
|
||||
|
@ -834,6 +838,7 @@ class JarLog(dict):
|
|||
access log as a list value. Only the first access to a given member of
|
||||
a jar is stored.
|
||||
'''
|
||||
|
||||
def __init__(self, file=None, fileobj=None):
|
||||
if not fileobj:
|
||||
fileobj = open(file, 'r')
|
||||
|
|
|
@ -28,10 +28,10 @@ class Component(object):
|
|||
'''
|
||||
Class that represents a component in a package manifest.
|
||||
'''
|
||||
|
||||
def __init__(self, name, destdir='', xz_compress=False):
|
||||
if name.find(' ') > 0:
|
||||
errors.fatal('Malformed manifest: space in component name "%s"'
|
||||
% component)
|
||||
errors.fatal('Malformed manifest: space in component name "%s"' % name)
|
||||
self._name = name
|
||||
self._destdir = destdir
|
||||
self._xz_compress = xz_compress
|
||||
|
@ -151,6 +151,7 @@ class PackageManifestParser(object):
|
|||
The add and remove methods of the sink object are called with the
|
||||
current Component instance and a path.
|
||||
'''
|
||||
|
||||
def __init__(self, sink):
|
||||
'''
|
||||
Initialize the package manifest parser with the given sink.
|
||||
|
@ -183,6 +184,7 @@ class PreprocessorOutputWrapper(object):
|
|||
File-like helper to handle the preprocessor output and send it to a parser.
|
||||
The parser's handle_line method is called in the relevant errors.context.
|
||||
'''
|
||||
|
||||
def __init__(self, preprocessor, parser):
|
||||
self._parser = parser
|
||||
self._pp = preprocessor
|
||||
|
@ -217,6 +219,7 @@ class CallDeque(deque):
|
|||
'''
|
||||
Queue of function calls to make.
|
||||
'''
|
||||
|
||||
def append(self, function, *args):
|
||||
deque.append(self, (errors.get_context(), function, args))
|
||||
|
||||
|
@ -240,6 +243,7 @@ class SimplePackager(object):
|
|||
given first that the simple manifest contents can't guarantee before the
|
||||
end of the input.
|
||||
'''
|
||||
|
||||
def __init__(self, formatter):
|
||||
self.formatter = formatter
|
||||
# Queue for formatter.add_interfaces()/add_manifest() calls.
|
||||
|
@ -287,7 +291,7 @@ class SimplePackager(object):
|
|||
parsed = json.loads(manifest)
|
||||
except ValueError:
|
||||
pass
|
||||
if isinstance(parsed, dict) and parsed.has_key('manifest_version'):
|
||||
if isinstance(parsed, dict) and 'manifest_version' in parsed:
|
||||
self._add_addon(mozpath.dirname(path), True)
|
||||
|
||||
def _add_addon(self, path, addon_type):
|
||||
|
@ -295,11 +299,11 @@ class SimplePackager(object):
|
|||
Add the given BaseFile to the collection of addons if a parent
|
||||
directory is not already in the collection.
|
||||
'''
|
||||
if mozpath.basedir(path, self._addons) != None:
|
||||
if mozpath.basedir(path, self._addons) is not None:
|
||||
return
|
||||
|
||||
for dir in self._addons:
|
||||
if mozpath.basedir(dir, [path]) != None:
|
||||
if mozpath.basedir(dir, [path]) is not None:
|
||||
del self._addons[dir]
|
||||
break
|
||||
|
||||
|
@ -345,7 +349,7 @@ class SimplePackager(object):
|
|||
'''
|
||||
all_bases = set(mozpath.dirname(m)
|
||||
for m in self._manifests
|
||||
- set(self._included_manifests))
|
||||
- set(self._included_manifests))
|
||||
if not addons:
|
||||
all_bases -= set(self._addons)
|
||||
else:
|
||||
|
@ -384,6 +388,7 @@ class SimpleManifestSink(object):
|
|||
Entries starting with bin/ are searched under bin/ in the FileFinder, but
|
||||
are packaged without the bin/ prefix.
|
||||
'''
|
||||
|
||||
def __init__(self, finder, formatter):
|
||||
'''
|
||||
Initialize the SimpleManifestSink. The given FileFinder is used to
|
||||
|
@ -438,7 +443,7 @@ class SimpleManifestSink(object):
|
|||
paths = [mozpath.dirname(m) for m in self._manifests]
|
||||
path = mozpath.dirname(mozpath.commonprefix(paths))
|
||||
for p, f in self._finder.find(mozpath.join(path,
|
||||
'chrome.manifest')):
|
||||
if not p in self._manifests:
|
||||
'chrome.manifest')):
|
||||
if p not in self._manifests:
|
||||
self.packager.add(SimpleManifestSink.normalize_path(p), f)
|
||||
self.packager.close()
|
||||
|
|
|
@ -6,7 +6,6 @@ from __future__ import absolute_import
|
|||
|
||||
from mozpack.chrome.manifest import (
|
||||
Manifest,
|
||||
ManifestEntryWithRelPath,
|
||||
ManifestInterfaces,
|
||||
ManifestChrome,
|
||||
ManifestBinaryComponent,
|
||||
|
@ -67,6 +66,7 @@ class PiecemealFormatter(object):
|
|||
Generic formatter that dispatches across different sub-formatters
|
||||
according to paths.
|
||||
'''
|
||||
|
||||
def __init__(self, copier):
|
||||
assert isinstance(copier, (FileRegistry, FileRegistrySubtree))
|
||||
self.copier = copier
|
||||
|
@ -116,6 +116,7 @@ class FlatFormatter(PiecemealFormatter):
|
|||
'''
|
||||
Formatter for the flat package format.
|
||||
'''
|
||||
|
||||
def _add_base(self, base, addon=False):
|
||||
self._sub_formatter[base] = FlatSubFormatter(
|
||||
FileRegistrySubtree(base, self.copier))
|
||||
|
@ -125,6 +126,7 @@ class FlatSubFormatter(object):
|
|||
'''
|
||||
Sub-formatter for the flat package format.
|
||||
'''
|
||||
|
||||
def __init__(self, copier):
|
||||
assert isinstance(copier, (FileRegistry, FileRegistrySubtree))
|
||||
self.copier = copier
|
||||
|
@ -149,7 +151,7 @@ class FlatSubFormatter(object):
|
|||
parent = mozpath.dirname(entry.base)
|
||||
relbase = mozpath.basename(entry.base)
|
||||
relpath = mozpath.join(relbase,
|
||||
mozpath.basename(path))
|
||||
mozpath.basename(path))
|
||||
self.add_manifest(Manifest(parent, relpath))
|
||||
self.copier.add(path, ManifestFile(entry.base))
|
||||
|
||||
|
@ -190,9 +192,10 @@ class JarFormatter(PiecemealFormatter):
|
|||
manifest entries for resources are registered after chrome manifest
|
||||
entries.
|
||||
'''
|
||||
|
||||
def __init__(self, copier, compress=True):
|
||||
PiecemealFormatter.__init__(self, copier)
|
||||
self._compress=compress
|
||||
self._compress = compress
|
||||
|
||||
def _add_base(self, base, addon=False):
|
||||
if addon is True:
|
||||
|
@ -212,6 +215,7 @@ class JarSubFormatter(PiecemealFormatter):
|
|||
dispatches the chrome data to, and a FlatSubFormatter for the non-chrome
|
||||
files.
|
||||
'''
|
||||
|
||||
def __init__(self, copier, compress=True):
|
||||
PiecemealFormatter.__init__(self, copier)
|
||||
self._frozen_chrome = False
|
||||
|
@ -252,6 +256,7 @@ class OmniJarFormatter(JarFormatter):
|
|||
'''
|
||||
Formatter for the omnijar package format.
|
||||
'''
|
||||
|
||||
def __init__(self, copier, omnijar_name, compress=True, non_resources=()):
|
||||
JarFormatter.__init__(self, copier, compress)
|
||||
self._omnijar_name = omnijar_name
|
||||
|
@ -277,6 +282,7 @@ class OmniJarSubFormatter(PiecemealFormatter):
|
|||
that dispatches between a FlatSubFormatter for the resources data and
|
||||
another FlatSubFormatter for the other files.
|
||||
'''
|
||||
|
||||
def __init__(self, copier, omnijar_name, compress=True, non_resources=()):
|
||||
PiecemealFormatter.__init__(self, copier)
|
||||
self._omnijar_name = omnijar_name
|
||||
|
@ -315,8 +321,8 @@ class OmniJarSubFormatter(PiecemealFormatter):
|
|||
return path[-1].endswith(('.js', '.xpt'))
|
||||
if path[0] == 'res':
|
||||
return len(path) == 1 or \
|
||||
(path[1] != 'cursors' and \
|
||||
path[1] != 'touchbar' and \
|
||||
(path[1] != 'cursors' and
|
||||
path[1] != 'touchbar' and
|
||||
path[1] != 'MainMenu.nib')
|
||||
if path[0] == 'defaults':
|
||||
return len(path) != 3 or \
|
||||
|
|
|
@ -175,7 +175,7 @@ def _repack(app_finder, l10n_finder, copier, formatter, non_chrome=set()):
|
|||
continue
|
||||
if key(e) not in l10n_paths[base]:
|
||||
errors.fatal("Locale doesn't have a manifest entry for '%s'" %
|
||||
e.name)
|
||||
e.name)
|
||||
# Allow errors to accumulate
|
||||
continue
|
||||
paths[e.path] = l10n_paths[base][key(e)]
|
||||
|
|
|
@ -40,6 +40,7 @@ class UnpackFinder(BaseFinder):
|
|||
The UnpackFinder is populated with files from this Finder instance,
|
||||
or with files from a FileFinder using the given path as its root.
|
||||
'''
|
||||
|
||||
def __init__(self, source, omnijar_name=None):
|
||||
if isinstance(source, BaseFinder):
|
||||
self._finder = source
|
||||
|
@ -90,7 +91,7 @@ class UnpackFinder(BaseFinder):
|
|||
if p.endswith('.xpi') and self._maybe_zip(f):
|
||||
self._fill_with_jar(p[:-4], self._open_jar(p, f))
|
||||
continue
|
||||
if not p in jars:
|
||||
if p not in jars:
|
||||
self.files.add(p, f)
|
||||
|
||||
def _fill_with_jar(self, base, jar):
|
||||
|
@ -126,11 +127,11 @@ class UnpackFinder(BaseFinder):
|
|||
jar = [f for p, f in self._finder.find(jarpath)]
|
||||
assert len(jar) == 1
|
||||
jar = jar[0]
|
||||
if not jarpath in jars:
|
||||
if jarpath not in jars:
|
||||
base = mozpath.splitext(jarpath)[0]
|
||||
for j in self._open_jar(jarpath, jar):
|
||||
self.files.add(mozpath.join(base,
|
||||
j.filename),
|
||||
j.filename),
|
||||
DeflatedFile(j))
|
||||
jars.add(jarpath)
|
||||
self.kind = 'jar'
|
||||
|
|
|
@ -119,6 +119,7 @@ class BaseTestFileRegistry(MatchTestTemplate):
|
|||
self.registry.remove('bar/zot')
|
||||
self.registry.add('bar/zot', GeneratedFile('barzot'))
|
||||
|
||||
|
||||
class TestFileRegistry(BaseTestFileRegistry, unittest.TestCase):
|
||||
def test_partial_paths(self):
|
||||
cases = {
|
||||
|
@ -180,7 +181,7 @@ class TestFileRegistrySubtree(BaseTestFileRegistry, unittest.TestCase):
|
|||
self.do_test_file_registry(self.create_registry())
|
||||
|
||||
def test_registry_paths_subtree(self):
|
||||
registry = FileRegistry()
|
||||
FileRegistry()
|
||||
self.do_test_registry_paths(self.create_registry())
|
||||
|
||||
|
||||
|
@ -215,7 +216,7 @@ class TestFileCopier(TestWithTmpDir):
|
|||
set(['foo/deep/nested/directory', 'qux']))
|
||||
|
||||
self.assertEqual(result.updated_files, set(self.tmppath(p) for p in
|
||||
self.all_files(self.tmpdir)))
|
||||
self.all_files(self.tmpdir)))
|
||||
self.assertEqual(result.existing_files, set())
|
||||
self.assertEqual(result.removed_files, set())
|
||||
self.assertEqual(result.removed_directories, set())
|
||||
|
@ -226,7 +227,8 @@ class TestFileCopier(TestWithTmpDir):
|
|||
self.assertEqual(self.all_files(self.tmpdir), set(copier.paths()))
|
||||
self.assertEqual(self.all_dirs(self.tmpdir), set(['qux']))
|
||||
self.assertEqual(result.removed_files, set(self.tmppath(p) for p in
|
||||
('foo/bar', 'foo/qux', 'foo/deep/nested/directory/file')))
|
||||
('foo/bar', 'foo/qux',
|
||||
'foo/deep/nested/directory/file')))
|
||||
|
||||
def test_symlink_directory_replaced(self):
|
||||
"""Directory symlinks in destination are replaced if they need to be
|
||||
|
@ -281,8 +283,8 @@ class TestFileCopier(TestWithTmpDir):
|
|||
# the symlinked directory remains (as does its containing
|
||||
# directory).
|
||||
result = copier.copy(dest, remove_unaccounted=False,
|
||||
remove_empty_directories=True,
|
||||
remove_all_directory_symlinks=False)
|
||||
remove_empty_directories=True,
|
||||
remove_all_directory_symlinks=False)
|
||||
|
||||
st = os.lstat(link)
|
||||
self.assertTrue(stat.S_ISLNK(st.st_mode))
|
||||
|
@ -297,8 +299,8 @@ class TestFileCopier(TestWithTmpDir):
|
|||
# If remove_unaccounted but not remove_empty_directories, then
|
||||
# only the symlinked directory is removed.
|
||||
result = copier.copy(dest, remove_unaccounted=True,
|
||||
remove_empty_directories=False,
|
||||
remove_all_directory_symlinks=False)
|
||||
remove_empty_directories=False,
|
||||
remove_all_directory_symlinks=False)
|
||||
|
||||
st = os.lstat(self.tmppath('dest/zot'))
|
||||
self.assertFalse(stat.S_ISLNK(st.st_mode))
|
||||
|
@ -316,8 +318,8 @@ class TestFileCopier(TestWithTmpDir):
|
|||
os.symlink(dummy, link)
|
||||
|
||||
result = copier.copy(dest, remove_unaccounted=True,
|
||||
remove_empty_directories=True,
|
||||
remove_all_directory_symlinks=False)
|
||||
remove_empty_directories=True,
|
||||
remove_all_directory_symlinks=False)
|
||||
|
||||
self.assertEqual(result.removed_files, set([link]))
|
||||
self.assertEqual(result.removed_directories, set([self.tmppath('dest/zot')]))
|
||||
|
@ -363,11 +365,11 @@ class TestFileCopier(TestWithTmpDir):
|
|||
result = copier.copy(self.tmpdir, remove_unaccounted=False)
|
||||
|
||||
self.assertEqual(self.all_files(self.tmpdir), set(['foo', 'bar',
|
||||
'populateddir/foo']))
|
||||
'populateddir/foo']))
|
||||
self.assertEqual(self.all_dirs(self.tmpdir), set(['populateddir']))
|
||||
self.assertEqual(result.removed_files, set())
|
||||
self.assertEqual(result.removed_directories,
|
||||
set([self.tmppath('emptydir')]))
|
||||
set([self.tmppath('emptydir')]))
|
||||
|
||||
def test_no_remove_empty_directories(self):
|
||||
copier = FileCopier()
|
||||
|
@ -384,12 +386,12 @@ class TestFileCopier(TestWithTmpDir):
|
|||
pass
|
||||
|
||||
result = copier.copy(self.tmpdir, remove_unaccounted=False,
|
||||
remove_empty_directories=False)
|
||||
remove_empty_directories=False)
|
||||
|
||||
self.assertEqual(self.all_files(self.tmpdir), set(['foo', 'bar',
|
||||
'populateddir/foo']))
|
||||
'populateddir/foo']))
|
||||
self.assertEqual(self.all_dirs(self.tmpdir), set(['emptydir',
|
||||
'populateddir']))
|
||||
'populateddir']))
|
||||
self.assertEqual(result.removed_files, set())
|
||||
self.assertEqual(result.removed_directories, set())
|
||||
|
||||
|
@ -433,15 +435,15 @@ class TestFileCopier(TestWithTmpDir):
|
|||
|
||||
os.makedirs(os.path.join(dest, 'bar'))
|
||||
with open(os.path.join(dest, 'bar', 'bar'), 'w') as fh:
|
||||
fh.write('barbar');
|
||||
fh.write('barbar')
|
||||
os.makedirs(os.path.join(dest, 'foo', 'toto'))
|
||||
with open(os.path.join(dest, 'foo', 'toto', 'toto'), 'w') as fh:
|
||||
fh.write('foototototo');
|
||||
fh.write('foototototo')
|
||||
|
||||
result = copier.copy(dest, remove_unaccounted=False)
|
||||
|
||||
self.assertEqual(self.all_files(dest),
|
||||
set(copier.paths()) | { 'foo/toto/toto', 'bar/bar'})
|
||||
set(copier.paths()) | {'foo/toto/toto', 'bar/bar'})
|
||||
self.assertEqual(self.all_dirs(dest),
|
||||
{'foo/bar', 'foo/hoge', 'foo/toto', 'bar'})
|
||||
|
||||
|
@ -453,14 +455,15 @@ class TestFileCopier(TestWithTmpDir):
|
|||
result = copier2.copy(dest, remove_unaccounted=copier)
|
||||
|
||||
self.assertEqual(self.all_files(dest),
|
||||
set(copier2.paths()) | { 'foo/toto/toto', 'bar/bar'})
|
||||
set(copier2.paths()) | {'foo/toto/toto', 'bar/bar'})
|
||||
self.assertEqual(self.all_dirs(dest),
|
||||
{'foo/hoge', 'foo/toto', 'bar'})
|
||||
self.assertEqual(result.updated_files,
|
||||
{self.tmppath('dest/foo/hoge/fuga')})
|
||||
self.assertEqual(result.existing_files, set())
|
||||
self.assertEqual(result.removed_files, {self.tmppath(p) for p in
|
||||
('dest/foo/bar/baz', 'dest/foo/bar/qux', 'dest/foo/toto/tata')})
|
||||
('dest/foo/bar/baz', 'dest/foo/bar/qux',
|
||||
'dest/foo/toto/tata')})
|
||||
self.assertEqual(result.removed_directories,
|
||||
{self.tmppath('dest/foo/bar')})
|
||||
|
||||
|
@ -506,10 +509,9 @@ class TestJarrer(unittest.TestCase):
|
|||
dest.seek(0)
|
||||
jar = JarReader(fileobj=dest)
|
||||
self.assertEqual([f.filename for f in jar], preloaded +
|
||||
[p for p in copier.paths() if not p in preloaded])
|
||||
[p for p in copier.paths() if p not in preloaded])
|
||||
self.assertEqual(jar.last_preloaded, preloaded[-1])
|
||||
|
||||
|
||||
def test_jarrer_compress(self):
|
||||
copier = Jarrer()
|
||||
copier.add('foo/bar', GeneratedFile('ffffff'))
|
||||
|
|
|
@ -89,5 +89,6 @@ class TestErrorsImpl(TestErrors, unittest.TestCase):
|
|||
'Error: foo:1: c',
|
||||
])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
mozunit.main()
|
||||
|
|
|
@ -101,7 +101,6 @@ class TestWithTmpDir(unittest.TestCase):
|
|||
|
||||
self.hardlink_supported = True
|
||||
|
||||
|
||||
def tearDown(self):
|
||||
mozfile.rmtree(self.tmpdir)
|
||||
|
||||
|
@ -159,6 +158,7 @@ class TestDest(TestWithTmpDir):
|
|||
dest.write('qux')
|
||||
self.assertEqual(dest.read(), 'qux')
|
||||
|
||||
|
||||
rand = ''.join(random.choice(string.letters) for i in xrange(131597))
|
||||
samples = [
|
||||
'',
|
||||
|
@ -573,13 +573,14 @@ class TestPreprocessedFile(TestWithTmpDir):
|
|||
tmp.write('#define FOO\nPREPROCESSED')
|
||||
|
||||
f = PreprocessedFile(pp_source, depfile_path=deps, marker='#',
|
||||
defines={'FOO': True})
|
||||
defines={'FOO': True})
|
||||
self.assertTrue(f.copy(dest))
|
||||
|
||||
self.assertEqual('PREPROCESSED', open(dest, 'rb').read())
|
||||
self.assertFalse(os.path.islink(dest))
|
||||
self.assertEqual('', open(source, 'rb').read())
|
||||
|
||||
|
||||
class TestExistingFile(TestWithTmpDir):
|
||||
def test_required_missing_dest(self):
|
||||
with self.assertRaisesRegexp(ErrorMessage, 'Required existing file'):
|
||||
|
@ -692,6 +693,7 @@ class TestGeneratedFile(TestWithTmpDir):
|
|||
self.assertEqual('content', f.read())
|
||||
self.assertEqual(data['num_calls'], 2)
|
||||
|
||||
|
||||
class TestDeflatedFile(TestWithTmpDir):
|
||||
def test_deflated_file(self):
|
||||
'''
|
||||
|
@ -807,6 +809,7 @@ class TestManifestFile(TestWithTmpDir):
|
|||
self.assertEqual(content[:42], f.open().read(42))
|
||||
self.assertEqual(content, f.open().read())
|
||||
|
||||
|
||||
# Compiled typelib for the following IDL:
|
||||
# interface foo;
|
||||
# [scriptable, uuid(5f70da76-519c-4858-b71e-e3c92333e2d6)]
|
||||
|
@ -903,7 +906,7 @@ class TestMinifiedJavaScript(TestWithTmpDir):
|
|||
def test_minified_verify_success(self):
|
||||
orig_f = GeneratedFile('\n'.join(self.orig_lines))
|
||||
min_f = MinifiedJavaScript(orig_f,
|
||||
verify_command=self._verify_command('0'))
|
||||
verify_command=self._verify_command('0'))
|
||||
|
||||
mini_lines = min_f.open().readlines()
|
||||
self.assertTrue(mini_lines)
|
||||
|
@ -913,14 +916,14 @@ class TestMinifiedJavaScript(TestWithTmpDir):
|
|||
orig_f = GeneratedFile('\n'.join(self.orig_lines))
|
||||
errors.out = StringIO()
|
||||
min_f = MinifiedJavaScript(orig_f,
|
||||
verify_command=self._verify_command('1'))
|
||||
verify_command=self._verify_command('1'))
|
||||
|
||||
mini_lines = min_f.open().readlines()
|
||||
output = errors.out.getvalue()
|
||||
errors.out = sys.stderr
|
||||
self.assertEqual(output,
|
||||
'Warning: JS minification verification failed for <unknown>:\n'
|
||||
'Warning: Error message\n')
|
||||
'Warning: JS minification verification failed for <unknown>:\n'
|
||||
'Warning: Error message\n')
|
||||
self.assertEqual(mini_lines, orig_f.open().readlines())
|
||||
|
||||
|
||||
|
@ -1060,9 +1063,9 @@ class TestFileFinder(MatchTestTemplate, TestWithTmpDir):
|
|||
|
||||
self.finder = FileFinder(self.tmpdir, ignore=['foo/bar', 'bar'])
|
||||
self.do_check('**', ['barz', 'foo/baz', 'foo/qux/1', 'foo/qux/2/test',
|
||||
'foo/qux/2/test2', 'foo/qux/bar'])
|
||||
'foo/qux/2/test2', 'foo/qux/bar'])
|
||||
self.do_check('foo/**', ['foo/baz', 'foo/qux/1', 'foo/qux/2/test',
|
||||
'foo/qux/2/test2', 'foo/qux/bar'])
|
||||
'foo/qux/2/test2', 'foo/qux/bar'])
|
||||
|
||||
def test_ignored_patterns(self):
|
||||
"""Ignore entries with patterns should be honored."""
|
||||
|
@ -1079,15 +1082,15 @@ class TestFileFinder(MatchTestTemplate, TestWithTmpDir):
|
|||
self.prepare_match_test(with_dotfiles=True)
|
||||
self.finder = FileFinder(self.tmpdir, find_dotfiles=True)
|
||||
self.do_check('**', ['bar', 'foo/.foo', 'foo/.bar/foo',
|
||||
'foo/bar', 'foo/baz', 'foo/qux/1', 'foo/qux/bar',
|
||||
'foo/qux/2/test', 'foo/qux/2/test2'])
|
||||
'foo/bar', 'foo/baz', 'foo/qux/1', 'foo/qux/bar',
|
||||
'foo/qux/2/test', 'foo/qux/2/test2'])
|
||||
|
||||
def test_dotfiles_plus_ignore(self):
|
||||
self.prepare_match_test(with_dotfiles=True)
|
||||
self.finder = FileFinder(self.tmpdir, find_dotfiles=True,
|
||||
ignore=['foo/.bar/**'])
|
||||
self.do_check('foo/**', ['foo/.foo', 'foo/bar', 'foo/baz',
|
||||
'foo/qux/1', 'foo/qux/bar', 'foo/qux/2/test', 'foo/qux/2/test2'])
|
||||
'foo/qux/1', 'foo/qux/bar', 'foo/qux/2/test', 'foo/qux/2/test2'])
|
||||
|
||||
|
||||
class TestJarFinder(MatchTestTemplate, TestWithTmpDir):
|
||||
|
@ -1108,6 +1111,7 @@ class TestJarFinder(MatchTestTemplate, TestWithTmpDir):
|
|||
self.assertIsNone(self.finder.get('does-not-exist'))
|
||||
self.assertIsInstance(self.finder.get('bar'), DeflatedFile)
|
||||
|
||||
|
||||
class TestTarFinder(MatchTestTemplate, TestWithTmpDir):
|
||||
def add(self, path):
|
||||
self.tar.addfile(tarfile.TarInfo(name=path))
|
||||
|
|
|
@ -28,7 +28,7 @@ class TestInstallManifest(TestWithTmpDir):
|
|||
f = self.tmppath('manifest')
|
||||
open(f, 'wb').write('junk\n')
|
||||
with self.assertRaises(UnreadableInstallManifest):
|
||||
m = InstallManifest(f)
|
||||
InstallManifest(f)
|
||||
|
||||
def test_adds(self):
|
||||
m = InstallManifest()
|
||||
|
@ -77,7 +77,8 @@ class TestInstallManifest(TestWithTmpDir):
|
|||
m = InstallManifest()
|
||||
m.add_link(self.tmppath('s_source'), 's_dest')
|
||||
m.add_copy(self.tmppath('c_source'), 'c_dest')
|
||||
m.add_preprocess(self.tmppath('p_source'), 'p_dest', self.tmppath('p_source.pp'), '#', {'FOO':'BAR', 'BAZ':'QUX'})
|
||||
m.add_preprocess(self.tmppath('p_source'), 'p_dest', self.tmppath(
|
||||
'p_source.pp'), '#', {'FOO': 'BAR', 'BAZ': 'QUX'})
|
||||
m.add_required_exists('e_dest')
|
||||
m.add_optional_exists('o_dest')
|
||||
m.add_pattern_link('ps_base', '*', 'ps_dest')
|
||||
|
@ -226,7 +227,7 @@ class TestInstallManifest(TestWithTmpDir):
|
|||
self.assertEqual(result.updated_files, set(self.tmppath(p) for p in (
|
||||
'dest/s_dest', 'dest/c_dest', 'dest/p_dest', 'dest/content')))
|
||||
self.assertEqual(result.existing_files,
|
||||
set([self.tmppath('dest/e_dest'), self.tmppath('dest/o_dest')]))
|
||||
set([self.tmppath('dest/e_dest'), self.tmppath('dest/o_dest')]))
|
||||
self.assertEqual(result.removed_files, {to_delete})
|
||||
self.assertEqual(result.removed_directories, set())
|
||||
|
||||
|
@ -251,7 +252,8 @@ class TestInstallManifest(TestWithTmpDir):
|
|||
# Create and write a manifest with the preprocessed file, then apply it.
|
||||
# This should write out our preprocessed file.
|
||||
m = InstallManifest()
|
||||
m.add_preprocess(self.tmppath('p_source'), 'p_dest', deps, '#', {'FOO':'BAR', 'BAZ':'QUX'})
|
||||
m.add_preprocess(self.tmppath('p_source'), 'p_dest',
|
||||
deps, '#', {'FOO': 'BAR', 'BAZ': 'QUX'})
|
||||
m.write(path=manifest)
|
||||
|
||||
m = InstallManifest(path=manifest)
|
||||
|
@ -268,7 +270,7 @@ class TestInstallManifest(TestWithTmpDir):
|
|||
# Since this manifest does not exist on the disk, there should not be a
|
||||
# dependency on it, and the preprocessed file should not be modified.
|
||||
m2 = InstallManifest()
|
||||
m2.add_preprocess(self.tmppath('p_source'), 'p_dest', deps, '#', {'DEPTEST':True})
|
||||
m2.add_preprocess(self.tmppath('p_source'), 'p_dest', deps, '#', {'DEPTEST': True})
|
||||
c = FileCopier()
|
||||
m2.populate_registry(c)
|
||||
result = c.copy(dest)
|
||||
|
@ -332,7 +334,7 @@ class TestInstallManifest(TestWithTmpDir):
|
|||
|
||||
# Create and write a manifest with the preprocessed file.
|
||||
m = InstallManifest()
|
||||
m.add_preprocess(source, 'p_dest', deps, '#', {'FOO':'BAR', 'BAZ':'QUX'})
|
||||
m.add_preprocess(source, 'p_dest', deps, '#', {'FOO': 'BAR', 'BAZ': 'QUX'})
|
||||
m.write(path=manifest)
|
||||
|
||||
time = os.path.getmtime(source) - 5
|
||||
|
|
|
@ -164,10 +164,10 @@ class TestJar(unittest.TestCase):
|
|||
|
||||
if os.sep == '\\':
|
||||
self.assertEqual(files[3].filename, 'baz/backslash',
|
||||
'backslashes in filenames on Windows should get normalized')
|
||||
'backslashes in filenames on Windows should get normalized')
|
||||
else:
|
||||
self.assertEqual(files[3].filename, 'baz\\backslash',
|
||||
'backslashes in filenames on POSIX platform are untouched')
|
||||
'backslashes in filenames on POSIX platform are untouched')
|
||||
|
||||
s = MockDest()
|
||||
with JarWriter(fileobj=s, compress=False) as jar:
|
||||
|
@ -307,8 +307,10 @@ class TestJarLog(unittest.TestCase):
|
|||
' deeply/nested/stuff',
|
||||
]))
|
||||
log = JarLog(fileobj=s)
|
||||
canonicalize = lambda p: \
|
||||
mozpath.normsep(os.path.normcase(os.path.realpath(p)))
|
||||
|
||||
def canonicalize(p):
|
||||
return mozpath.normsep(os.path.normcase(os.path.realpath(p)))
|
||||
|
||||
baz_jar = canonicalize('bar/baz.jar')
|
||||
qux_zip = canonicalize('qux.zip')
|
||||
self.assertEqual(set(log.keys()), set([
|
||||
|
|
|
@ -243,7 +243,8 @@ class TestSimplePackager(unittest.TestCase):
|
|||
'<RDF>\n<... em:unpack=\'false\'>\n<...>\n</RDF>')
|
||||
packager.add('addon11/install.rdf', install_rdf_addon11)
|
||||
|
||||
we_manifest = GeneratedFile('{"manifest_version": 2, "name": "Test WebExtension", "version": "1.0"}')
|
||||
we_manifest = GeneratedFile(
|
||||
'{"manifest_version": 2, "name": "Test WebExtension", "version": "1.0"}')
|
||||
# hybrid and hybrid2 are both bootstrapped extensions with
|
||||
# embedded webextensions, they differ in the order in which
|
||||
# the manifests are added to the packager.
|
||||
|
@ -365,8 +366,8 @@ class TestSimplePackager(unittest.TestCase):
|
|||
packager.close()
|
||||
|
||||
self.assertEqual(e.exception.message,
|
||||
'Error: "bar/baz.manifest" is included from "base.manifest", '
|
||||
'which is outside "bar"')
|
||||
'Error: "bar/baz.manifest" is included from "base.manifest", '
|
||||
'which is outside "bar"')
|
||||
|
||||
# bar/ is detected as a separate base because of chrome.manifest that
|
||||
# is included nowhere, but top-level includes another manifest inside
|
||||
|
@ -384,8 +385,8 @@ class TestSimplePackager(unittest.TestCase):
|
|||
packager.close()
|
||||
|
||||
self.assertEqual(e.exception.message,
|
||||
'Error: "bar/baz.manifest" is included from "base.manifest", '
|
||||
'which is outside "bar"')
|
||||
'Error: "bar/baz.manifest" is included from "base.manifest", '
|
||||
'which is outside "bar"')
|
||||
|
||||
# bar/ is detected as a separate base because of chrome.manifest that
|
||||
# is included nowhere, but chrome.manifest includes baz.manifest from
|
||||
|
@ -487,13 +488,13 @@ class TestComponent(unittest.TestCase):
|
|||
self.do_split('trailingspace ', 'trailingspace', {})
|
||||
self.do_split(' leadingspace', 'leadingspace', {})
|
||||
self.do_split(' trim ', 'trim', {})
|
||||
self.do_split(' trim key="value"', 'trim', {'key':'value'})
|
||||
self.do_split(' trim empty=""', 'trim', {'empty':''})
|
||||
self.do_split(' trim space=" "', 'trim', {'space':' '})
|
||||
self.do_split(' trim key="value"', 'trim', {'key': 'value'})
|
||||
self.do_split(' trim empty=""', 'trim', {'empty': ''})
|
||||
self.do_split(' trim space=" "', 'trim', {'space': ' '})
|
||||
self.do_split('component key="value" key2="second" ',
|
||||
'component', {'key':'value', 'key2':'second'})
|
||||
self.do_split( 'trim key=" value with spaces " key2="spaces again"',
|
||||
'trim', {'key':' value with spaces ', 'key2': 'spaces again'})
|
||||
'component', {'key': 'value', 'key2': 'second'})
|
||||
self.do_split('trim key=" value with spaces " key2="spaces again"',
|
||||
'trim', {'key': ' value with spaces ', 'key2': 'spaces again'})
|
||||
|
||||
def do_split_error(self, string):
|
||||
self.assertRaises(ValueError, Component._split_component_and_options, string)
|
||||
|
|
|
@ -23,7 +23,6 @@ from mozpack.chrome.manifest import (
|
|||
ManifestLocale,
|
||||
)
|
||||
from mozpack.errors import (
|
||||
errors,
|
||||
ErrorMessage,
|
||||
)
|
||||
from mozpack.test.test_files import (
|
||||
|
@ -264,6 +263,7 @@ EXTRA_CONTENTS = {
|
|||
|
||||
CONTENTS_WITH_BASE['files'].update(EXTRA_CONTENTS)
|
||||
|
||||
|
||||
def result_with_base(results):
|
||||
result = {
|
||||
mozpath.join('base/root', p): v
|
||||
|
@ -272,6 +272,7 @@ def result_with_base(results):
|
|||
result.update(EXTRA_CONTENTS)
|
||||
return result
|
||||
|
||||
|
||||
RESULT_FLAT_WITH_BASE = result_with_base(RESULT_FLAT)
|
||||
RESULT_JAR_WITH_BASE = result_with_base(RESULT_JAR)
|
||||
RESULT_OMNIJAR_WITH_BASE = result_with_base(RESULT_OMNIJAR)
|
||||
|
@ -447,8 +448,8 @@ class TestFormatters(TestErrors, unittest.TestCase):
|
|||
f.add_manifest(ManifestContent('chrome', 'foo', 'foo/'))
|
||||
|
||||
self.assertEqual(e.exception.message,
|
||||
'Error: "content foo foo/" overrides '
|
||||
'"content foo foo/unix"')
|
||||
'Error: "content foo foo/" overrides '
|
||||
'"content foo foo/unix"')
|
||||
|
||||
# Chrome with the same name and same flags overrides the previous
|
||||
# registration.
|
||||
|
@ -456,8 +457,8 @@ class TestFormatters(TestErrors, unittest.TestCase):
|
|||
f.add_manifest(ManifestContent('chrome', 'foo', 'foo/', 'os=WINNT'))
|
||||
|
||||
self.assertEqual(e.exception.message,
|
||||
'Error: "content foo foo/ os=WINNT" overrides '
|
||||
'"content foo foo/win os=WINNT"')
|
||||
'Error: "content foo foo/ os=WINNT" overrides '
|
||||
'"content foo foo/win os=WINNT"')
|
||||
|
||||
# We may start with the more specific entry first
|
||||
f.add_manifest(ManifestContent('chrome', 'bar', 'bar/win', 'os=WINNT'))
|
||||
|
@ -466,8 +467,8 @@ class TestFormatters(TestErrors, unittest.TestCase):
|
|||
f.add_manifest(ManifestContent('chrome', 'bar', 'bar/unix'))
|
||||
|
||||
self.assertEqual(e.exception.message,
|
||||
'Error: "content bar bar/unix" overrides '
|
||||
'"content bar bar/win os=WINNT"')
|
||||
'Error: "content bar bar/unix" overrides '
|
||||
'"content bar bar/win os=WINNT"')
|
||||
|
||||
# Adding something more specific still works.
|
||||
f.add_manifest(ManifestContent('chrome', 'bar', 'bar/win',
|
||||
|
@ -480,9 +481,9 @@ class TestFormatters(TestErrors, unittest.TestCase):
|
|||
'foo/skin/modern/'))
|
||||
|
||||
f.add_manifest(ManifestLocale('chrome', 'foo', 'en-US',
|
||||
'foo/locale/en-US/'))
|
||||
'foo/locale/en-US/'))
|
||||
f.add_manifest(ManifestLocale('chrome', 'foo', 'ja-JP',
|
||||
'foo/locale/ja-JP/'))
|
||||
'foo/locale/ja-JP/'))
|
||||
|
||||
# But same-skin/locale still error out.
|
||||
with self.assertRaises(ErrorMessage) as e:
|
||||
|
@ -490,16 +491,16 @@ class TestFormatters(TestErrors, unittest.TestCase):
|
|||
'foo/skin/classic/foo'))
|
||||
|
||||
self.assertEqual(e.exception.message,
|
||||
'Error: "skin foo classic/1.0 foo/skin/classic/foo" overrides '
|
||||
'"skin foo classic/1.0 foo/skin/classic/"')
|
||||
'Error: "skin foo classic/1.0 foo/skin/classic/foo" overrides '
|
||||
'"skin foo classic/1.0 foo/skin/classic/"')
|
||||
|
||||
with self.assertRaises(ErrorMessage) as e:
|
||||
f.add_manifest(ManifestLocale('chrome', 'foo', 'en-US',
|
||||
'foo/locale/en-US/foo'))
|
||||
'foo/locale/en-US/foo'))
|
||||
|
||||
self.assertEqual(e.exception.message,
|
||||
'Error: "locale foo en-US foo/locale/en-US/foo" overrides '
|
||||
'"locale foo en-US foo/locale/en-US/"')
|
||||
'Error: "locale foo en-US foo/locale/en-US/foo" overrides '
|
||||
'"locale foo en-US foo/locale/en-US/"')
|
||||
|
||||
# Duplicating existing manifest entries is not an error.
|
||||
f.add_manifest(ManifestContent('chrome', 'foo', 'foo/unix'))
|
||||
|
|
|
@ -58,6 +58,7 @@ class TestUnpack(TestWithTmpDir):
|
|||
def _omni_foo_formatter(name):
|
||||
class OmniFooFormatter(OmniJarFormatter):
|
||||
OMNIJAR_NAME = name
|
||||
|
||||
def __init__(self, registry):
|
||||
super(OmniFooFormatter, self).__init__(registry, name)
|
||||
return OmniFooFormatter
|
||||
|
|
|
@ -239,7 +239,7 @@ to the standard.
|
|||
[Jeremy Lempereur].
|
||||
|
||||
- Many documentation improvements, now published on
|
||||
https://firefox-source-docs.mozilla.org/testing/geckodriver/geckodriver/.
|
||||
https://firefox-source-docs.mozilla.org/testing/geckodriver/.
|
||||
|
||||
|
||||
0.21.0 (2018-06-15)
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
Please see our contributor documentation at
|
||||
https://firefox-source-docs.mozilla.org/testing/geckodriver/geckodriver/#for-developers.
|
||||
https://firefox-source-docs.mozilla.org/testing/geckodriver/#for-developers.
|
||||
|
|
|
@ -13,7 +13,7 @@ geckodriver’s [source code] is made available under the [Mozilla
|
|||
Public License].
|
||||
|
||||
[WebDriver protocol]: https://w3c.github.io/webdriver/#protocol
|
||||
[Firefox remote protocol]: https://firefox-source-docs.mozilla.org/testing/marionette/marionette/Protocol.html
|
||||
[Firefox remote protocol]: https://firefox-source-docs.mozilla.org/testing/marionette/Protocol.html
|
||||
[source code]: https://hg.mozilla.org/mozilla-unified/file/tip/testing/geckodriver
|
||||
[Mozilla Public License]: https://www.mozilla.org/en-US/MPL/2.0/
|
||||
[WebDriver]: https://developer.mozilla.org/en-US/docs/Web/WebDriver
|
||||
|
@ -44,14 +44,14 @@ Documentation
|
|||
* [Python API](https://seleniumhq.github.io/selenium/docs/api/py/)
|
||||
* [Ruby API](https://seleniumhq.github.io/selenium/docs/api/rb/)
|
||||
|
||||
* [geckodriver usage](https://firefox-source-docs.mozilla.org/testing/geckodriver/geckodriver/Usage.html)
|
||||
* [Supported platforms](https://firefox-source-docs.mozilla.org/testing/geckodriver/geckodriver/Support.html)
|
||||
* [Firefox capabilities](https://firefox-source-docs.mozilla.org/testing/geckodriver/geckodriver/Capabilities.html)
|
||||
* [Capabilities example](https://firefox-source-docs.mozilla.org/testing/geckodriver/geckodriver/Capabilities.html#capabilities-example)
|
||||
* [Enabling trace logs](https://firefox-source-docs.mozilla.org/testing/geckodriver/geckodriver/TraceLogs.html)
|
||||
* [Analyzing crash data from Firefox](https://firefox-source-docs.mozilla.org/testing/geckodriver/geckodriver/CrashReports.html)
|
||||
* [geckodriver usage](https://firefox-source-docs.mozilla.org/testing/geckodriver/Usage.html)
|
||||
* [Supported platforms](https://firefox-source-docs.mozilla.org/testing/geckodriver/Support.html)
|
||||
* [Firefox capabilities](https://firefox-source-docs.mozilla.org/testing/geckodriver/Capabilities.html)
|
||||
* [Capabilities example](https://firefox-source-docs.mozilla.org/testing/geckodriver/Capabilities.html#capabilities-example)
|
||||
* [Enabling trace logs](https://firefox-source-docs.mozilla.org/testing/geckodriver/TraceLogs.html)
|
||||
* [Analyzing crash data from Firefox](https://firefox-source-docs.mozilla.org/testing/geckodriver/CrashReports.html)
|
||||
|
||||
* [Contributing](https://firefox-source-docs.mozilla.org/testing/geckodriver/geckodriver/#for-developers)
|
||||
* [Contributing](https://firefox-source-docs.mozilla.org/testing/geckodriver/#for-developers)
|
||||
|
||||
|
||||
Source code
|
||||
|
@ -62,7 +62,7 @@ We only use this GitHub repository for issue tracking and making releases.
|
|||
See our [contribution documentation] for more information.
|
||||
|
||||
[mozilla-central]: https://hg.mozilla.org/mozilla-central/file/tip/testing/geckodriver
|
||||
[contribution documentation]: https://firefox-source-docs.mozilla.org/testing/geckodriver/geckodriver/#for-developers
|
||||
[contribution documentation]: https://firefox-source-docs.mozilla.org/testing/geckodriver/#for-developers
|
||||
|
||||
|
||||
Contact
|
||||
|
|
|
@ -55,4 +55,4 @@ flag to geckodriver through WPT:
|
|||
[headless mode]: https://developer.mozilla.org/en-US/Firefox/Headless_mode
|
||||
[mozconfig]: https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Build_Instructions/Configuring_Build_Options
|
||||
[trace-level logs]: TraceLogs.html
|
||||
[Marionette protocol]: https://firefox-source-docs.mozilla.org/testing/marionette/marionette/Protocol.html
|
||||
[Marionette protocol]: https://firefox-source-docs.mozilla.org/testing/marionette/Protocol.html
|
||||
|
|
|
@ -14,7 +14,7 @@ You can consult the `change log`_ for a record of all notable changes
|
|||
to the program. Releases_ are made available on GitHub.
|
||||
|
||||
.. _WebDriver protocol: https://w3c.github.io/webdriver/#protocol
|
||||
.. _Firefox remote protocol: https://firefox-source-docs.mozilla.org/testing/marionette/marionette/Protocol.html
|
||||
.. _Firefox remote protocol: https://firefox-source-docs.mozilla.org/testing/marionette/Protocol.html
|
||||
.. _change log: https://github.com/mozilla/geckodriver/releases
|
||||
.. _Releases: https://github.com/mozilla/geckodriver/releases
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ def get_version():
|
|||
setup(name='marionette_driver',
|
||||
version=get_version(),
|
||||
description="Marionette Driver",
|
||||
long_description='See http://marionette-client.readthedocs.org/en/latest/',
|
||||
long_description='See https://firefox-source-docs.mozilla.org/python/marionette_driver.html',
|
||||
# Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers
|
||||
classifiers=[
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
|
|
|
@ -60,12 +60,12 @@ Assertions are provided courtesy of [unittest]. For example:
|
|||
The API
|
||||
-------
|
||||
|
||||
The full API documentation is found at
|
||||
<http://marionette-client.readthedocs.io>, but the key objects are:
|
||||
The full API documentation is found [here], but the key objects are:
|
||||
|
||||
* `MarionetteTestCase`: a subclass for `unittest.TestCase`
|
||||
used as a base class for all tests to run.
|
||||
|
||||
* [`Marionette`]: client that speaks to Firefox.
|
||||
|
||||
[`Marionette`]: http://marionette-client.readthedocs.io/en/master/reference.html#marionette
|
||||
[here]: ../../../python/marionette_driver.html
|
||||
[`Marionette`]: ../../../python/marionette_driver.html#marionette_driver.marionette.Marionette
|
||||
|
|
|
@ -15,7 +15,7 @@ visual section of Firefox's browser UI. For example, there are different
|
|||
libraries for the tab bar, the navigation bar, etc.
|
||||
|
||||
.. _Firefox Puppeteer: http://firefox-puppeteer.readthedocs.io/
|
||||
.. _Marionette Python client: http://marionette-client.readthedocs.org/
|
||||
.. _Marionette Python client: https://firefox-source-docs.mozilla.org/python/marionette_driver.html
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
|
|
@ -239,7 +239,7 @@ class SeleniumProtocol(Protocol):
|
|||
|
||||
|
||||
### Firefox
|
||||
We use the [set window rect](http://marionette-client.readthedocs.io/en/master/reference.html#marionette_driver.marionette.Marionette.set_window_rect) Marionette command.
|
||||
We use the [set window rect](https://firefox-source-docs.mozilla.org/python/marionette_driver.html#marionette_driver.marionette.Marionette.set_window_rect) Marionette command.
|
||||
|
||||
We will use [executormarionette](tools/wptrunner/wptrunner/executors/executormarionette.py) and use the Marionette Python API.
|
||||
|
||||
|
|
|
@ -6307,7 +6307,7 @@
|
|||
"kind": "enumerated",
|
||||
"n_values": 10,
|
||||
"releaseChannelCollection": "opt-out",
|
||||
"description": "Where the migration wizard was entered from. 0=Other/catch-all, 1=first-run, 2=refresh-firefox, 3=Places window, 4=Password manager"
|
||||
"description": "Where the migration wizard was entered from. 0=Other/catch-all, 1=first-run, 2=refresh-firefox, 3=Places window, 4=Password manager, 5=New tab, 6=File menu"
|
||||
},
|
||||
"FX_MIGRATION_SOURCE_BROWSER": {
|
||||
"record_in_processes": ["main", "content"],
|
||||
|
|
Загрузка…
Ссылка в новой задаче