forked from mirrors/gecko-dev
Merge release to esr128. a=release
This commit is contained in:
commit
309c863f48
357 changed files with 1083 additions and 1068 deletions
|
|
@ -430,6 +430,9 @@ pref("browser.urlbar.scotchBonnet.enableOverride", false);
|
|||
|
||||
// Enable trending suggestions and recent searches.
|
||||
pref("browser.urlbar.trending.featureGate", true);
|
||||
#if defined(RELEASE_OR_BETA)
|
||||
pref("browser.urlbar.trending.enabledLocales", "en-US, en-CA");
|
||||
#endif
|
||||
pref("browser.urlbar.trending.requireSearchMode", false);
|
||||
pref("browser.urlbar.recentsearches.featureGate", true);
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ Preferences.addAll([
|
|||
{ id: "browser.search.separatePrivateDefault.ui.enabled", type: "bool" },
|
||||
{ id: "browser.urlbar.suggest.trending", type: "bool" },
|
||||
{ id: "browser.urlbar.trending.featureGate", type: "bool" },
|
||||
{ id: "browser.urlbar.trending.enabledLocales", type: "string" },
|
||||
{ id: "browser.urlbar.recentsearches.featureGate", type: "bool" },
|
||||
{ id: "browser.urlbar.suggest.recentsearches", type: "bool" },
|
||||
]);
|
||||
|
|
@ -283,8 +284,18 @@ var gSearchPane = {
|
|||
let trendingSupported = (
|
||||
await Services.search.getDefault()
|
||||
).supportsResponseType(lazy.SearchUtils.URL_TYPE.TRENDING_JSON);
|
||||
trendingBox.hidden = !Preferences.get("browser.urlbar.trending.featureGate")
|
||||
.value;
|
||||
let trendingEnabled = Preferences.get(
|
||||
"browser.urlbar.trending.featureGate"
|
||||
).value;
|
||||
let enabledLocales = Preferences.get(
|
||||
"browser.urlbar.trending.enabledLocales"
|
||||
).value;
|
||||
if (trendingEnabled && enabledLocales) {
|
||||
trendingEnabled = enabledLocales.includes(
|
||||
Services.locale.appLocaleAsBCP47
|
||||
);
|
||||
}
|
||||
trendingBox.hidden = !trendingEnabled;
|
||||
trendingCheckBox.disabled = suggestDisabled || !trendingSupported;
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -452,6 +452,11 @@ const PREF_URLBAR_DEFAULTS = new Map([
|
|||
// Feature gate pref for trending suggestions in the urlbar.
|
||||
["trending.featureGate", true],
|
||||
|
||||
// Only enable trending suggestions if the users browser locale is contained
|
||||
// in this list; enable in all locales if empty.
|
||||
// (if the value was "en-US", trending would only be enabled for en-US users).
|
||||
["trending.enabledLocales", ""],
|
||||
|
||||
// The maximum number of trending results to show while not in search mode.
|
||||
["trending.maxResultsNoSearchMode", 10],
|
||||
|
||||
|
|
|
|||
|
|
@ -601,9 +601,16 @@ class ProviderSearchSuggestions extends UrlbarProvider {
|
|||
* Whether we should fetch trending results.
|
||||
*/
|
||||
#shouldFetchTrending(queryContext) {
|
||||
let trendingEnabled = lazy.UrlbarPrefs.get("trending.featureGate");
|
||||
let enabledLocales = lazy.UrlbarPrefs.get("trending.enabledLocales");
|
||||
if (trendingEnabled && enabledLocales) {
|
||||
trendingEnabled = enabledLocales.includes(
|
||||
Services.locale.appLocaleAsBCP47
|
||||
);
|
||||
}
|
||||
return !!(
|
||||
queryContext.searchString == "" &&
|
||||
lazy.UrlbarPrefs.get("trending.featureGate") &&
|
||||
trendingEnabled &&
|
||||
lazy.UrlbarPrefs.get("suggest.trending") &&
|
||||
(queryContext.searchMode ||
|
||||
!lazy.UrlbarPrefs.get("trending.requireSearchMode"))
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@ export const ThemeVariableMap = [
|
|||
"--lwt-tab-line-color",
|
||||
{
|
||||
lwtProperty: "tab_line",
|
||||
optionalElementID: "TabsToolbar",
|
||||
},
|
||||
],
|
||||
[
|
||||
|
|
|
|||
|
|
@ -20,13 +20,21 @@
|
|||
--tab-selected-textcolor: var(--toolbar-color);
|
||||
--tab-selected-bgcolor: var(--toolbar-bgcolor);
|
||||
--tab-selected-color-scheme: var(--toolbar-color-scheme);
|
||||
|
||||
&[lwt-tab-selected="light"] {
|
||||
--tab-selected-color-scheme: light;
|
||||
}
|
||||
&[lwt-tab-selected="dark"] {
|
||||
--tab-selected-color-scheme: dark;
|
||||
}
|
||||
--tab-selected-outline-color: transparent;
|
||||
--tab-hover-outline-color: transparent;
|
||||
@media (prefers-contrast) {
|
||||
--tab-selected-outline-color: currentColor;
|
||||
--tab-hover-outline-color: currentColor;
|
||||
}
|
||||
&[lwtheme] {
|
||||
--tab-selected-outline-color: var(--lwt-tab-line-color, currentColor);
|
||||
}
|
||||
}
|
||||
|
||||
#tabbrowser-tabs {
|
||||
|
|
@ -123,13 +131,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
/* tabbrowser-tab keyboard focus */
|
||||
&.keyboard-focused-tab > .tab-stack > .tab-background,
|
||||
&:focus:not([aria-activedescendant]) > .tab-stack > .tab-background {
|
||||
outline: var(--focus-outline);
|
||||
outline-offset: var(--focus-outline-inset);
|
||||
}
|
||||
|
||||
#tabbrowser-tabs[movingtab] > #tabbrowser-arrowscrollbox > &:is([selected], [multiselected]) {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
|
|
@ -563,11 +564,8 @@
|
|||
#TabsToolbar #firefox-view-button:hover:not([open]) > .toolbarbutton-icon,
|
||||
.tabbrowser-tab:hover > .tab-stack > .tab-background:not([selected], [multiselected]) {
|
||||
background-color: color-mix(in srgb, currentColor 11%, transparent);
|
||||
}
|
||||
|
||||
#TabsToolbar #firefox-view-button[open] > .toolbarbutton-icon,
|
||||
#tabbrowser-tabs:not([noshadowfortests]) .tab-background:is([selected], [multiselected]) {
|
||||
box-shadow: 0 0 4px rgba(0,0,0,.4);
|
||||
outline: 1px solid var(--tab-hover-outline-color);
|
||||
outline-offset: -1px;
|
||||
}
|
||||
|
||||
#TabsToolbar #firefox-view-button[open] > .toolbarbutton-icon,
|
||||
|
|
@ -575,6 +573,13 @@
|
|||
background-color: var(--tab-selected-bgcolor);
|
||||
background-origin: border-box;
|
||||
background-repeat: repeat-x;
|
||||
box-shadow: 0 0 4px rgba(0,0,0,.4);
|
||||
outline: 1px solid var(--tab-selected-outline-color);
|
||||
outline-offset: -1px;
|
||||
|
||||
#tabbrowser-tabs[noshadowfortests] & {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
#TabsToolbar #firefox-view-button[open] > .toolbarbutton-icon,
|
||||
|
|
@ -583,23 +588,6 @@
|
|||
color-scheme: var(--tab-selected-color-scheme);
|
||||
}
|
||||
|
||||
@media (prefers-contrast) {
|
||||
#TabsToolbar #firefox-view-button:is([open], :hover):not(:focus-visible) > .toolbarbutton-icon,
|
||||
.tab-background[selected],
|
||||
.tabbrowser-tab:hover > .tab-stack > .tab-background {
|
||||
outline: 1px solid currentColor;
|
||||
outline-offset: -1px;
|
||||
}
|
||||
}
|
||||
|
||||
@media not (prefers-contrast) {
|
||||
:root[lwtheme] #TabsToolbar #firefox-view-button[open]:not(:focus-visible) > .toolbarbutton-icon,
|
||||
:root[lwtheme] .tab-background[selected]:not([multiselected]) {
|
||||
outline: 1px solid var(--lwt-tab-line-color, var(--lwt-tabs-border-color, currentColor));
|
||||
outline-offset: -1px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add a focus outline on top of the multiselected tabs, with the currently selected
|
||||
tab getting a slightly thicker outline. */
|
||||
.tab-background[multiselected] {
|
||||
|
|
@ -612,6 +600,13 @@
|
|||
}
|
||||
}
|
||||
|
||||
/* Keyboard focus outline */
|
||||
#TabsToolbar #firefox-view-button:focus-visible > .toolbarbutton-icon,
|
||||
.tabbrowser-tab:is(.keyboard-focused-tab, :focus:not([aria-activedescendant])) > .tab-stack > .tab-background {
|
||||
outline: var(--focus-outline);
|
||||
outline-offset: var(--focus-outline-inset);
|
||||
}
|
||||
|
||||
/* Pinned tabs */
|
||||
|
||||
.tabbrowser-tab:is([image], [pinned]) > .tab-stack > .tab-content[attention]:not([selected]),
|
||||
|
|
|
|||
|
|
@ -3991,7 +3991,7 @@ nsresult HTMLInputElement::PostHandleEvent(EventChainPostVisitor& aVisitor) {
|
|||
if (mType == FormControlType::InputSearch) {
|
||||
if (nsSearchControlFrame* searchControlFrame =
|
||||
do_QueryFrame(GetPrimaryFrame())) {
|
||||
Element* clearButton = searchControlFrame->GetAnonClearButton();
|
||||
Element* clearButton = searchControlFrame->GetButton();
|
||||
if (clearButton &&
|
||||
aVisitor.mEvent->mOriginalTarget == clearButton) {
|
||||
SetUserInput(EmptyString(),
|
||||
|
|
@ -4005,7 +4005,7 @@ nsresult HTMLInputElement::PostHandleEvent(EventChainPostVisitor& aVisitor) {
|
|||
} else if (mType == FormControlType::InputPassword) {
|
||||
if (nsTextControlFrame* textControlFrame =
|
||||
do_QueryFrame(GetPrimaryFrame())) {
|
||||
auto* reveal = textControlFrame->GetRevealButton();
|
||||
auto* reveal = textControlFrame->GetButton();
|
||||
if (reveal && aVisitor.mEvent->mOriginalTarget == reveal) {
|
||||
SetRevealPassword(!RevealPassword());
|
||||
// TODO(emilio): This should focus the input, but calling
|
||||
|
|
@ -6974,20 +6974,20 @@ Maybe<int32_t> HTMLInputElement::GetNumberInputCols() const {
|
|||
(size.mAfterDecimal ? 1 : 0));
|
||||
}
|
||||
|
||||
int32_t HTMLInputElement::GetCols() {
|
||||
Maybe<int32_t> HTMLInputElement::GetCols() {
|
||||
if (const nsAttrValue* attr = GetParsedAttr(nsGkAtoms::size);
|
||||
attr && attr->Type() == nsAttrValue::eInteger) {
|
||||
int32_t cols = attr->GetIntegerValue();
|
||||
if (cols > 0) {
|
||||
return cols;
|
||||
return Some(cols);
|
||||
}
|
||||
}
|
||||
|
||||
if (Maybe<int32_t> cols = GetNumberInputCols(); cols && *cols > 0) {
|
||||
return *cols;
|
||||
return cols;
|
||||
}
|
||||
|
||||
return DEFAULT_COLS;
|
||||
return {};
|
||||
}
|
||||
|
||||
int32_t HTMLInputElement::GetWrapCols() {
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@ class HTMLInputElement final : public TextControlElement,
|
|||
bool IsSingleLineTextControl() const override;
|
||||
bool IsTextArea() const override;
|
||||
bool IsPasswordTextControl() const override;
|
||||
int32_t GetCols() override;
|
||||
Maybe<int32_t> GetCols() override;
|
||||
int32_t GetWrapCols() override;
|
||||
int32_t GetRows() override;
|
||||
void GetDefaultValueFromContent(nsAString& aValue, bool aForDisplay) override;
|
||||
|
|
|
|||
|
|
@ -1053,7 +1053,13 @@ bool HTMLTextAreaElement::IsTextArea() const { return true; }
|
|||
|
||||
bool HTMLTextAreaElement::IsPasswordTextControl() const { return false; }
|
||||
|
||||
int32_t HTMLTextAreaElement::GetCols() { return Cols(); }
|
||||
Maybe<int32_t> HTMLTextAreaElement::GetCols() {
|
||||
const nsAttrValue* value = GetParsedAttr(nsGkAtoms::cols);
|
||||
if (!value || value->Type() != nsAttrValue::eInteger) {
|
||||
return {};
|
||||
}
|
||||
return Some(value->GetIntegerValue());
|
||||
}
|
||||
|
||||
int32_t HTMLTextAreaElement::GetWrapCols() {
|
||||
nsHTMLTextWrap wrapProp;
|
||||
|
|
@ -1064,7 +1070,7 @@ int32_t HTMLTextAreaElement::GetWrapCols() {
|
|||
}
|
||||
|
||||
// Otherwise we just wrap at the given number of columns
|
||||
return GetCols();
|
||||
return GetColsOrDefault();
|
||||
}
|
||||
|
||||
int32_t HTMLTextAreaElement::GetRows() {
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ class HTMLTextAreaElement final : public TextControlElement,
|
|||
bool IsSingleLineTextControl() const override;
|
||||
bool IsTextArea() const override;
|
||||
bool IsPasswordTextControl() const override;
|
||||
int32_t GetCols() override;
|
||||
Maybe<int32_t> GetCols() override;
|
||||
int32_t GetWrapCols() override;
|
||||
int32_t GetRows() override;
|
||||
void GetDefaultValueFromContent(nsAString& aValue, bool aForDisplay) override;
|
||||
|
|
@ -171,7 +171,7 @@ class HTMLTextAreaElement final : public TextControlElement,
|
|||
void SetAutocomplete(const nsAString& aValue, ErrorResult& aRv) {
|
||||
SetHTMLAttr(nsGkAtoms::autocomplete, aValue, aRv);
|
||||
}
|
||||
uint32_t Cols() { return GetUnsignedIntAttr(nsGkAtoms::cols, DEFAULT_COLS); }
|
||||
uint32_t Cols() { return GetColsOrDefault(); }
|
||||
void SetCols(uint32_t aCols, ErrorResult& aError) {
|
||||
uint32_t cols = aCols ? aCols : DEFAULT_COLS;
|
||||
SetUnsignedIntAttr(nsGkAtoms::cols, cols, DEFAULT_COLS, aError);
|
||||
|
|
|
|||
|
|
@ -76,7 +76,8 @@ class TextControlElement : public nsGenericHTMLFormControlElementWithState {
|
|||
* Get the cols attribute (if textarea) or a default
|
||||
* @return the number of columns to use
|
||||
*/
|
||||
virtual int32_t GetCols() = 0;
|
||||
virtual Maybe<int32_t> GetCols() = 0;
|
||||
int32_t GetColsOrDefault() { return GetCols().valueOr(DEFAULT_COLS); }
|
||||
|
||||
/**
|
||||
* Get the column index to wrap at, or -1 if we shouldn't wrap
|
||||
|
|
@ -216,10 +217,10 @@ class TextControlElement : public nsGenericHTMLFormControlElementWithState {
|
|||
MOZ_CAN_RUN_SCRIPT virtual nsresult SetValueFromSetRangeText(
|
||||
const nsAString& aValue) = 0;
|
||||
|
||||
static const int32_t DEFAULT_COLS = 20;
|
||||
static const int32_t DEFAULT_ROWS = 1;
|
||||
static const int32_t DEFAULT_ROWS_TEXTAREA = 2;
|
||||
static const int32_t DEFAULT_UNDO_CAP = 1000;
|
||||
inline static constexpr int32_t DEFAULT_COLS = 20;
|
||||
inline static constexpr int32_t DEFAULT_ROWS = 1;
|
||||
inline static constexpr int32_t DEFAULT_ROWS_TEXTAREA = 2;
|
||||
inline static constexpr int32_t DEFAULT_UNDO_CAP = 1000;
|
||||
|
||||
// wrap can be one of these three values.
|
||||
typedef enum {
|
||||
|
|
|
|||
|
|
@ -324,7 +324,7 @@ class TextControlState final : public SupportsWeakPtr {
|
|||
bool IsPasswordTextControl() const {
|
||||
return mTextCtrlElement->IsPasswordTextControl();
|
||||
}
|
||||
int32_t GetCols() { return mTextCtrlElement->GetCols(); }
|
||||
int32_t GetColsOrDefault() { return mTextCtrlElement->GetColsOrDefault(); }
|
||||
int32_t GetWrapCols() {
|
||||
int32_t wrapCols = mTextCtrlElement->GetWrapCols();
|
||||
MOZ_ASSERT(wrapCols >= 0);
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ export class PrivateAttributionService {
|
|||
await impressionStore.put(impressions, key);
|
||||
}
|
||||
|
||||
async compareImpression(cur, impression) {
|
||||
compareImpression(cur, impression) {
|
||||
return cur.source === impression.source && cur.target === impression.target;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -81,27 +81,7 @@ class GCLocProviderPriv final : public nsIGeolocationProvider,
|
|||
|
||||
GCLocProviderPriv();
|
||||
|
||||
void UpdateLastPosition();
|
||||
|
||||
private:
|
||||
class LocationTimerCallback final : public nsITimerCallback, public nsINamed {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSITIMERCALLBACK
|
||||
|
||||
explicit LocationTimerCallback(GCLocProviderPriv* aParent)
|
||||
: mParent(aParent) {}
|
||||
|
||||
NS_IMETHOD GetName(nsACString& aName) override {
|
||||
aName.AssignLiteral("GCLocProvider::LocationTimerCallback");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
~LocationTimerCallback() = default;
|
||||
WeakPtr<GCLocProviderPriv> mParent;
|
||||
};
|
||||
|
||||
enum class Accuracy { Unset, Low, High };
|
||||
// States:
|
||||
// Uninit: The default / initial state, with no client proxy yet.
|
||||
|
|
@ -232,7 +212,6 @@ class GCLocProviderPriv final : public nsIGeolocationProvider,
|
|||
MOZ_CAN_RUN_SCRIPT static void GCManagerOwnerNotify(GObject* aObject,
|
||||
GParamSpec* aPSpec,
|
||||
gpointer aUserData);
|
||||
|
||||
static void GCClientSignal(GDBusProxy* aProxy, gchar* aSenderName,
|
||||
gchar* aSignalName, GVariant* aParameters,
|
||||
gpointer aUserData);
|
||||
|
|
@ -242,8 +221,13 @@ class GCLocProviderPriv final : public nsIGeolocationProvider,
|
|||
static void ConnectLocationResponse(GObject* aObject, GAsyncResult* aResult,
|
||||
gpointer aUserData);
|
||||
|
||||
void SetLocationTimer();
|
||||
void StopLocationTimer();
|
||||
void StartLastPositionTimer();
|
||||
void StopPositionTimer();
|
||||
void UpdateLastPosition();
|
||||
|
||||
void StartMLSFallbackTimerIfNeeded();
|
||||
void StopMLSFallbackTimer();
|
||||
void MLSFallbackTimerFired();
|
||||
|
||||
bool InDBusCall();
|
||||
bool InDBusStoppingCall();
|
||||
|
|
@ -266,10 +250,44 @@ class GCLocProviderPriv final : public nsIGeolocationProvider,
|
|||
nsCOMPtr<nsIGeolocationUpdate> mCallback;
|
||||
ClientState mClientState = ClientState::Uninit;
|
||||
RefPtr<nsIDOMGeoPosition> mLastPosition;
|
||||
RefPtr<nsITimer> mLocationTimer;
|
||||
RefPtr<nsITimer> mLastPositionTimer;
|
||||
RefPtr<nsITimer> mMLSFallbackTimer;
|
||||
RefPtr<MLSFallback> mMLSFallback;
|
||||
};
|
||||
|
||||
class GCLocWeakCallback final : public nsITimerCallback, public nsINamed {
|
||||
using Method = void (GCLocProviderPriv::*)();
|
||||
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSITIMERCALLBACK
|
||||
|
||||
explicit GCLocWeakCallback(GCLocProviderPriv* aParent, const char* aName,
|
||||
Method aMethod)
|
||||
: mParent(aParent), mName(aName), mMethod(aMethod) {}
|
||||
|
||||
NS_IMETHOD GetName(nsACString& aName) override {
|
||||
aName = mName;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
~GCLocWeakCallback() = default;
|
||||
WeakPtr<GCLocProviderPriv> mParent;
|
||||
const char* mName = nullptr;
|
||||
Method mMethod = nullptr;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(GCLocWeakCallback, nsITimerCallback, nsINamed)
|
||||
|
||||
NS_IMETHODIMP
|
||||
GCLocWeakCallback::Notify(nsITimer* aTimer) {
|
||||
if (RefPtr parent = mParent.get()) {
|
||||
(parent->*mMethod)();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//
|
||||
// GCLocProviderPriv
|
||||
//
|
||||
|
|
@ -310,7 +328,8 @@ void GCLocProviderPriv::Update(nsIDOMGeoPosition* aPosition) {
|
|||
|
||||
void GCLocProviderPriv::UpdateLastPosition() {
|
||||
MOZ_DIAGNOSTIC_ASSERT(mLastPosition, "No last position to update");
|
||||
StopLocationTimer();
|
||||
StopPositionTimer();
|
||||
StopMLSFallbackTimer();
|
||||
Update(mLastPosition);
|
||||
}
|
||||
|
||||
|
|
@ -381,9 +400,9 @@ void GCLocProviderPriv::GetClientResponse(GDBusProxy* aProxy,
|
|||
RefPtr<GVariant> variant = dont_AddRef(
|
||||
g_dbus_proxy_call_finish(aProxy, aResult, getter_Transfers(error)));
|
||||
if (!variant) {
|
||||
GCL_LOG(Error, "Failed to get client: %s\n", error->message);
|
||||
// if cancelled |self| might no longer be there
|
||||
if (!g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
|
||||
GCL_LOG(Error, "Failed to get client: %s\n", error->message);
|
||||
RefPtr self = static_cast<GCLocProviderPriv*>(aUserData);
|
||||
self->DBusProxyError(error.get(), true);
|
||||
}
|
||||
|
|
@ -602,6 +621,9 @@ void GCLocProviderPriv::StartClientResponse(GDBusProxy* aProxy,
|
|||
MOZ_DIAGNOSTIC_ASSERT(self->mClientState == ClientState::Starting,
|
||||
"Client in a wrong state");
|
||||
GCLP_SETSTATE(self, Started);
|
||||
// If we're started, and we don't get any location update in a reasonable
|
||||
// amount of time, we fallback to MLS.
|
||||
self->StartMLSFallbackTimerIfNeeded();
|
||||
self->MaybeRestartForAccuracy();
|
||||
}
|
||||
|
||||
|
|
@ -689,6 +711,9 @@ void GCLocProviderPriv::GCClientSignal(GDBusProxy* aProxy, gchar* aSenderName,
|
|||
gchar* aSignalName,
|
||||
GVariant* aParameters,
|
||||
gpointer aUserData) {
|
||||
GCL_LOG(Info, "%s: %s (%s)\n", __PRETTY_FUNCTION__, aSignalName,
|
||||
GUniquePtr<gchar>(g_variant_print(aParameters, TRUE)).get());
|
||||
|
||||
if (g_strcmp0(aSignalName, "LocationUpdated")) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -802,23 +827,63 @@ void GCLocProviderPriv::ConnectLocationResponse(GObject* aObject,
|
|||
self->UpdateLastPosition();
|
||||
}
|
||||
|
||||
void GCLocProviderPriv::SetLocationTimer() {
|
||||
void GCLocProviderPriv::StartLastPositionTimer() {
|
||||
MOZ_DIAGNOSTIC_ASSERT(mLastPosition, "no last position to report");
|
||||
|
||||
StopLocationTimer();
|
||||
StopPositionTimer();
|
||||
|
||||
RefPtr<LocationTimerCallback> timerCallback = new LocationTimerCallback(this);
|
||||
NS_NewTimerWithCallback(getter_AddRefs(mLocationTimer), timerCallback, 1000,
|
||||
nsITimer::TYPE_ONE_SHOT);
|
||||
RefPtr timerCallback = new GCLocWeakCallback(
|
||||
this, "UpdateLastPosition", &GCLocProviderPriv::UpdateLastPosition);
|
||||
NS_NewTimerWithCallback(getter_AddRefs(mLastPositionTimer), timerCallback,
|
||||
1000, nsITimer::TYPE_ONE_SHOT);
|
||||
}
|
||||
|
||||
void GCLocProviderPriv::StopLocationTimer() {
|
||||
if (!mLocationTimer) {
|
||||
void GCLocProviderPriv::StopPositionTimer() {
|
||||
if (!mLastPositionTimer) {
|
||||
return;
|
||||
}
|
||||
|
||||
mLocationTimer->Cancel();
|
||||
mLocationTimer = nullptr;
|
||||
mLastPositionTimer->Cancel();
|
||||
mLastPositionTimer = nullptr;
|
||||
}
|
||||
|
||||
void GCLocProviderPriv::StartMLSFallbackTimerIfNeeded() {
|
||||
StopMLSFallbackTimer();
|
||||
if (mLastPosition) {
|
||||
// If we already have a location we're good.
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t delay = StaticPrefs::geo_provider_geoclue_mls_fallback_timeout_ms();
|
||||
if (!delay) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr timerCallback = new GCLocWeakCallback(
|
||||
this, "MLSFallbackTimerFired", &GCLocProviderPriv::MLSFallbackTimerFired);
|
||||
NS_NewTimerWithCallback(getter_AddRefs(mMLSFallbackTimer), timerCallback,
|
||||
delay, nsITimer::TYPE_ONE_SHOT);
|
||||
}
|
||||
|
||||
void GCLocProviderPriv::StopMLSFallbackTimer() {
|
||||
if (!mMLSFallbackTimer) {
|
||||
return;
|
||||
}
|
||||
mMLSFallbackTimer->Cancel();
|
||||
mMLSFallbackTimer = nullptr;
|
||||
}
|
||||
|
||||
void GCLocProviderPriv::MLSFallbackTimerFired() {
|
||||
mMLSFallbackTimer = nullptr;
|
||||
|
||||
if (mMLSFallback || mLastPosition || mClientState != ClientState::Started) {
|
||||
return;
|
||||
}
|
||||
|
||||
GCL_LOG(Info,
|
||||
"Didn't get a location in a reasonable amount of time, trying to "
|
||||
"fall back to MLS");
|
||||
FallbackToMLS();
|
||||
}
|
||||
|
||||
// Did we made some D-Bus call and are still waiting for its response?
|
||||
|
|
@ -861,7 +926,8 @@ void GCLocProviderPriv::DoShutdown(bool aDeleteClient, bool aDeleteManager) {
|
|||
"deleting manager proxy requires deleting client one, too");
|
||||
|
||||
// Invalidate the cached last position
|
||||
StopLocationTimer();
|
||||
StopPositionTimer();
|
||||
StopMLSFallbackTimer();
|
||||
mLastPosition = nullptr;
|
||||
|
||||
/*
|
||||
|
|
@ -955,10 +1021,10 @@ void GCLocProviderPriv::WatchStart() {
|
|||
if (mClientState == ClientState::Idle) {
|
||||
StartClient();
|
||||
} else if (mClientState == ClientState::Started) {
|
||||
if (mLastPosition && !mLocationTimer) {
|
||||
if (mLastPosition && !mLastPositionTimer) {
|
||||
GCL_LOG(Verbose,
|
||||
"Will report the existing location if new one doesn't come up\n");
|
||||
SetLocationTimer();
|
||||
"Will report the existing position if new one doesn't come up\n");
|
||||
StartLastPositionTimer();
|
||||
}
|
||||
} else if (mClientState == ClientState::SettingAccuracy) {
|
||||
GCLP_SETSTATE(this, SettingAccuracyForStart);
|
||||
|
|
@ -1016,19 +1082,6 @@ GCLocProviderPriv::SetHighAccuracy(bool aHigh) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(GCLocProviderPriv::LocationTimerCallback, nsITimerCallback,
|
||||
nsINamed)
|
||||
|
||||
NS_IMETHODIMP
|
||||
GCLocProviderPriv::LocationTimerCallback::Notify(nsITimer* aTimer) {
|
||||
if (mParent) {
|
||||
RefPtr<GCLocProviderPriv> parent(mParent);
|
||||
parent->UpdateLastPosition();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
GeoclueLocationProvider::GeoclueLocationProvider() {
|
||||
mPriv = new GCLocProviderPriv;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,11 +41,6 @@ nsNumberControlFrame::nsNumberControlFrame(ComputedStyle* aStyle,
|
|||
nsPresContext* aPresContext)
|
||||
: nsTextControlFrame(aStyle, aPresContext, kClassID) {}
|
||||
|
||||
void nsNumberControlFrame::Destroy(DestroyContext& aContext) {
|
||||
aContext.AddAnonymousContent(mSpinBox.forget());
|
||||
nsTextControlFrame::Destroy(aContext);
|
||||
}
|
||||
|
||||
nsresult nsNumberControlFrame::CreateAnonymousContent(
|
||||
nsTArray<ContentInfo>& aElements) {
|
||||
// We create an anonymous tree for our input element that is structured as
|
||||
|
|
@ -75,15 +70,15 @@ nsresult nsNumberControlFrame::CreateAnonymousContent(
|
|||
}
|
||||
|
||||
// Create the ::-moz-number-spin-box pseudo-element:
|
||||
mSpinBox = MakeAnonElement(PseudoStyleType::mozNumberSpinBox);
|
||||
mButton = MakeAnonElement(PseudoStyleType::mozNumberSpinBox);
|
||||
|
||||
// Create the ::-moz-number-spin-up pseudo-element:
|
||||
mSpinUp = MakeAnonElement(PseudoStyleType::mozNumberSpinUp, mSpinBox);
|
||||
mSpinUp = MakeAnonElement(PseudoStyleType::mozNumberSpinUp, mButton);
|
||||
|
||||
// Create the ::-moz-number-spin-down pseudo-element:
|
||||
mSpinDown = MakeAnonElement(PseudoStyleType::mozNumberSpinDown, mSpinBox);
|
||||
mSpinDown = MakeAnonElement(PseudoStyleType::mozNumberSpinDown, mButton);
|
||||
|
||||
aElements.AppendElement(mSpinBox);
|
||||
aElements.AppendElement(mButton);
|
||||
|
||||
return NS_OK;
|
||||
#endif
|
||||
|
|
@ -113,7 +108,7 @@ int32_t nsNumberControlFrame::GetSpinButtonForPointerEvent(
|
|||
WidgetGUIEvent* aEvent) const {
|
||||
MOZ_ASSERT(aEvent->mClass == eMouseEventClass, "Unexpected event type");
|
||||
|
||||
if (!mSpinBox) {
|
||||
if (!mButton) {
|
||||
// we don't have a spinner
|
||||
return eSpinButtonNone;
|
||||
}
|
||||
|
|
@ -123,7 +118,7 @@ int32_t nsNumberControlFrame::GetSpinButtonForPointerEvent(
|
|||
if (aEvent->mOriginalTarget == mSpinDown) {
|
||||
return eSpinButtonDown;
|
||||
}
|
||||
if (aEvent->mOriginalTarget == mSpinBox) {
|
||||
if (aEvent->mOriginalTarget == mButton) {
|
||||
// In the case that the up/down buttons are hidden (display:none) we use
|
||||
// just the spin box element, spinning up if the pointer is over the top
|
||||
// half of the element, or down if it's over the bottom half. This is
|
||||
|
|
@ -131,9 +126,9 @@ int32_t nsNumberControlFrame::GetSpinButtonForPointerEvent(
|
|||
// default UA style sheet. See the comment in forms.css for why.
|
||||
LayoutDeviceIntPoint absPoint = aEvent->mRefPoint;
|
||||
nsPoint point = nsLayoutUtils::GetEventCoordinatesRelativeTo(
|
||||
aEvent, absPoint, RelativeTo{mSpinBox->GetPrimaryFrame()});
|
||||
aEvent, absPoint, RelativeTo{mButton->GetPrimaryFrame()});
|
||||
if (point != nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE)) {
|
||||
if (point.y < mSpinBox->GetPrimaryFrame()->GetSize().height / 2) {
|
||||
if (point.y < mButton->GetPrimaryFrame()->GetSize().height / 2) {
|
||||
return eSpinButtonUp;
|
||||
}
|
||||
return eSpinButtonDown;
|
||||
|
|
@ -167,14 +162,6 @@ bool nsNumberControlFrame::SpinnerDownButtonIsDepressed() const {
|
|||
->NumberSpinnerDownButtonIsDepressed();
|
||||
}
|
||||
|
||||
void nsNumberControlFrame::AppendAnonymousContentTo(
|
||||
nsTArray<nsIContent*>& aElements, uint32_t aFilter) {
|
||||
nsTextControlFrame::AppendAnonymousContentTo(aElements, aFilter);
|
||||
if (mSpinBox) {
|
||||
aElements.AppendElement(mSpinBox);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
a11y::AccType nsNumberControlFrame::AccessibleType() {
|
||||
return a11y::eHTMLSpinnerType;
|
||||
|
|
|
|||
|
|
@ -49,16 +49,12 @@ class nsNumberControlFrame final : public nsTextControlFrame {
|
|||
NS_DECL_QUERYFRAME
|
||||
NS_DECL_FRAMEARENA_HELPERS(nsNumberControlFrame)
|
||||
|
||||
void Destroy(DestroyContext&) override;
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
mozilla::a11y::AccType AccessibleType() override;
|
||||
#endif
|
||||
|
||||
// nsIAnonymousContentCreator
|
||||
nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) override;
|
||||
void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
|
||||
uint32_t aFilter) override;
|
||||
|
||||
#ifdef DEBUG_FRAME_DUMP
|
||||
nsresult GetFrameName(nsAString& aResult) const override {
|
||||
|
|
@ -97,7 +93,6 @@ class nsNumberControlFrame final : public nsTextControlFrame {
|
|||
private:
|
||||
// See nsNumberControlFrame::CreateAnonymousContent for a description of
|
||||
// these.
|
||||
nsCOMPtr<Element> mSpinBox;
|
||||
nsCOMPtr<Element> mSpinUp;
|
||||
nsCOMPtr<Element> mSpinDown;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -39,11 +39,6 @@ nsSearchControlFrame::nsSearchControlFrame(ComputedStyle* aStyle,
|
|||
nsPresContext* aPresContext)
|
||||
: nsTextControlFrame(aStyle, aPresContext, kClassID) {}
|
||||
|
||||
void nsSearchControlFrame::Destroy(DestroyContext& aContext) {
|
||||
aContext.AddAnonymousContent(mClearButton.forget());
|
||||
nsTextControlFrame::Destroy(aContext);
|
||||
}
|
||||
|
||||
nsresult nsSearchControlFrame::CreateAnonymousContent(
|
||||
nsTArray<ContentInfo>& aElements) {
|
||||
// We create an anonymous tree for our input element that is structured as
|
||||
|
|
@ -60,23 +55,11 @@ nsresult nsSearchControlFrame::CreateAnonymousContent(
|
|||
|
||||
nsTextControlFrame::CreateAnonymousContent(aElements);
|
||||
|
||||
// FIXME: We could use nsTextControlFrame making the show password buttton
|
||||
// code a bit more generic, or rename this frame and use it for password
|
||||
// inputs.
|
||||
//
|
||||
// Create the ::-moz-search-clear-button pseudo-element:
|
||||
mClearButton = MakeAnonElement(PseudoStyleType::mozSearchClearButton, nullptr,
|
||||
nsGkAtoms::button);
|
||||
mButton = MakeAnonElement(PseudoStyleType::mozSearchClearButton, nullptr,
|
||||
nsGkAtoms::button);
|
||||
|
||||
aElements.AppendElement(mClearButton);
|
||||
aElements.AppendElement(mButton);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsSearchControlFrame::AppendAnonymousContentTo(
|
||||
nsTArray<nsIContent*>& aElements, uint32_t aFilter) {
|
||||
nsTextControlFrame::AppendAnonymousContentTo(aElements, aFilter);
|
||||
if (mClearButton) {
|
||||
aElements.AppendElement(mClearButton);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,12 +40,8 @@ class nsSearchControlFrame final : public nsTextControlFrame {
|
|||
NS_DECL_QUERYFRAME
|
||||
NS_DECL_FRAMEARENA_HELPERS(nsSearchControlFrame)
|
||||
|
||||
void Destroy(DestroyContext&) override;
|
||||
|
||||
// nsIAnonymousContentCreator
|
||||
nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) override;
|
||||
void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
|
||||
uint32_t aFilter) override;
|
||||
|
||||
#ifdef DEBUG_FRAME_DUMP
|
||||
nsresult GetFrameName(nsAString& aResult) const override {
|
||||
|
|
@ -53,16 +49,10 @@ class nsSearchControlFrame final : public nsTextControlFrame {
|
|||
}
|
||||
#endif
|
||||
|
||||
Element* GetAnonClearButton() const { return mClearButton; }
|
||||
|
||||
/**
|
||||
* Update visbility of the clear button depending on the value
|
||||
*/
|
||||
void UpdateClearButtonState();
|
||||
|
||||
private:
|
||||
// See nsSearchControlFrame::CreateAnonymousContent of a description of these
|
||||
RefPtr<Element> mClearButton;
|
||||
};
|
||||
|
||||
#endif // nsSearchControlFrame_h__
|
||||
|
|
|
|||
|
|
@ -168,7 +168,7 @@ void nsTextControlFrame::Destroy(DestroyContext& aContext) {
|
|||
aContext.AddAnonymousContent(mRootNode.forget());
|
||||
aContext.AddAnonymousContent(mPlaceholderDiv.forget());
|
||||
aContext.AddAnonymousContent(mPreviewDiv.forget());
|
||||
aContext.AddAnonymousContent(mRevealButton.forget());
|
||||
aContext.AddAnonymousContent(mButton.forget());
|
||||
|
||||
nsContainerFrame::Destroy(aContext);
|
||||
}
|
||||
|
|
@ -188,7 +188,8 @@ LogicalSize nsTextControlFrame::CalcIntrinsicSize(gfxContext* aRenderingContext,
|
|||
const nscoord charMaxAdvance = fontMet->MaxAdvance();
|
||||
|
||||
// Initialize based on the width in characters.
|
||||
const int32_t cols = GetCols();
|
||||
const Maybe<int32_t> maybeCols = GetCols();
|
||||
const int32_t cols = maybeCols.valueOr(TextControlElement::DEFAULT_COLS);
|
||||
intrinsicSize.ISize(aWM) = cols * charWidth;
|
||||
|
||||
// If we do not have what appears to be a fixed-width font, add a "slop"
|
||||
|
|
@ -203,12 +204,11 @@ LogicalSize nsTextControlFrame::CalcIntrinsicSize(gfxContext* aRenderingContext,
|
|||
nsPresContext::CSSPixelsToAppUnits(4));
|
||||
internalPadding = RoundToMultiple(internalPadding, AppUnitsPerCSSPixel());
|
||||
intrinsicSize.ISize(aWM) += internalPadding;
|
||||
} else {
|
||||
} else if (PresContext()->CompatibilityMode() ==
|
||||
eCompatibility_FullStandards) {
|
||||
// This is to account for the anonymous <br> having a 1 twip width
|
||||
// in Full Standards mode, see BRFrame::Reflow and bug 228752.
|
||||
if (PresContext()->CompatibilityMode() == eCompatibility_FullStandards) {
|
||||
intrinsicSize.ISize(aWM) += 1;
|
||||
}
|
||||
intrinsicSize.ISize(aWM) += 1;
|
||||
}
|
||||
|
||||
// Increment width with cols * letter-spacing.
|
||||
|
|
@ -248,6 +248,14 @@ LogicalSize nsTextControlFrame::CalcIntrinsicSize(gfxContext* aRenderingContext,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add the inline size of the button if our char size is explicit, so as to
|
||||
// make sure to make enough space for it.
|
||||
if (maybeCols.isSome() && mButton && mButton->GetPrimaryFrame()) {
|
||||
intrinsicSize.ISize(aWM) +=
|
||||
mButton->GetPrimaryFrame()->GetMinISize(aRenderingContext);
|
||||
}
|
||||
|
||||
return intrinsicSize;
|
||||
}
|
||||
|
||||
|
|
@ -431,22 +439,21 @@ nsresult nsTextControlFrame::CreateAnonymousContent(
|
|||
// background on the placeholder doesn't obscure the caret.
|
||||
aElements.AppendElement(mRootNode);
|
||||
|
||||
rv = UpdateValueDisplay(false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if ((StaticPrefs::layout_forms_reveal_password_button_enabled() ||
|
||||
PresContext()->Document()->ChromeRulesEnabled()) &&
|
||||
IsPasswordTextControl() &&
|
||||
StyleDisplay()->EffectiveAppearance() != StyleAppearance::Textfield) {
|
||||
mRevealButton =
|
||||
mButton =
|
||||
MakeAnonElement(PseudoStyleType::mozReveal, nullptr, nsGkAtoms::button);
|
||||
mRevealButton->SetAttr(kNameSpaceID_None, nsGkAtoms::aria_hidden,
|
||||
u"true"_ns, false);
|
||||
mRevealButton->SetAttr(kNameSpaceID_None, nsGkAtoms::tabindex, u"-1"_ns,
|
||||
false);
|
||||
aElements.AppendElement(mRevealButton);
|
||||
mButton->SetAttr(kNameSpaceID_None, nsGkAtoms::aria_hidden, u"true"_ns,
|
||||
false);
|
||||
mButton->SetAttr(kNameSpaceID_None, nsGkAtoms::tabindex, u"-1"_ns, false);
|
||||
aElements.AppendElement(mButton);
|
||||
}
|
||||
|
||||
rv = UpdateValueDisplay(false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
InitializeEagerlyIfNeeded();
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
@ -561,8 +568,8 @@ void nsTextControlFrame::AppendAnonymousContentTo(
|
|||
aElements.AppendElement(mPreviewDiv);
|
||||
}
|
||||
|
||||
if (mRevealButton) {
|
||||
aElements.AppendElement(mRevealButton);
|
||||
if (mButton) {
|
||||
aElements.AppendElement(mButton);
|
||||
}
|
||||
|
||||
aElements.AppendElement(mRootNode);
|
||||
|
|
@ -599,13 +606,6 @@ Maybe<nscoord> nsTextControlFrame::ComputeBaseline(
|
|||
aReflowInput.ComputedLogicalBorderPadding(wm).BStart(wm));
|
||||
}
|
||||
|
||||
static bool IsButtonBox(const nsIFrame* aFrame) {
|
||||
auto pseudoType = aFrame->Style()->GetPseudoType();
|
||||
return pseudoType == PseudoStyleType::mozNumberSpinBox ||
|
||||
pseudoType == PseudoStyleType::mozSearchClearButton ||
|
||||
pseudoType == PseudoStyleType::mozReveal;
|
||||
}
|
||||
|
||||
void nsTextControlFrame::Reflow(nsPresContext* aPresContext,
|
||||
ReflowOutput& aDesiredSize,
|
||||
const ReflowInput& aReflowInput,
|
||||
|
|
|
|||
|
|
@ -190,7 +190,11 @@ class nsTextControlFrame : public nsContainerFrame,
|
|||
|
||||
Element* GetPlaceholderNode() const { return mPlaceholderDiv; }
|
||||
|
||||
Element* GetRevealButton() const { return mRevealButton; }
|
||||
Element* GetButton() const { return mButton; }
|
||||
|
||||
bool IsButtonBox(const nsIFrame* aFrame) const {
|
||||
return aFrame->GetContent() == GetButton();
|
||||
}
|
||||
|
||||
// called by the focus listener
|
||||
nsresult MaybeBeginSecureKeyboardInput();
|
||||
|
|
@ -207,7 +211,8 @@ class nsTextControlFrame : public nsContainerFrame,
|
|||
DEFINE_TEXTCTRL_CONST_FORWARDER(bool, IsSingleLineTextControl)
|
||||
DEFINE_TEXTCTRL_CONST_FORWARDER(bool, IsTextArea)
|
||||
DEFINE_TEXTCTRL_CONST_FORWARDER(bool, IsPasswordTextControl)
|
||||
DEFINE_TEXTCTRL_CONST_FORWARDER(int32_t, GetCols)
|
||||
DEFINE_TEXTCTRL_CONST_FORWARDER(Maybe<int32_t>, GetCols)
|
||||
DEFINE_TEXTCTRL_CONST_FORWARDER(int32_t, GetColsOrDefault)
|
||||
DEFINE_TEXTCTRL_CONST_FORWARDER(int32_t, GetRows)
|
||||
|
||||
#undef DEFINE_TEXTCTRL_CONST_FORWARDER
|
||||
|
|
@ -320,9 +325,9 @@ class nsTextControlFrame : public nsContainerFrame,
|
|||
RefPtr<Element> mRootNode;
|
||||
RefPtr<Element> mPlaceholderDiv;
|
||||
RefPtr<Element> mPreviewDiv;
|
||||
// The Reveal Password button. Only used for type=password, nullptr
|
||||
// otherwise.
|
||||
RefPtr<Element> mRevealButton;
|
||||
// If we have type=password, number, or search, then mButton is our
|
||||
// reveal-password, spinner, or search button box. Otherwise, it's nullptr.
|
||||
RefPtr<Element> mButton;
|
||||
RefPtr<nsAnonDivObserver> mMutationObserver;
|
||||
// Cache of the |.value| of <input> or <textarea> element without hard-wrap.
|
||||
// If its IsVoid() returns true, it doesn't cache |.value|.
|
||||
|
|
|
|||
|
|
@ -345,7 +345,8 @@ void nsFontInflationData::ScanTextIn(nsIFrame* aFrame) {
|
|||
// We don't want changes to the amount of text in a text input
|
||||
// to change what we count towards inflation.
|
||||
nscoord fontSize = kid->StyleFont()->mFont.size.ToAppUnits();
|
||||
int32_t charCount = static_cast<nsTextControlFrame*>(kid)->GetCols();
|
||||
int32_t charCount =
|
||||
static_cast<nsTextControlFrame*>(kid)->GetColsOrDefault();
|
||||
mTextAmount += charCount * fontSize;
|
||||
} else if (fType == LayoutFrameType::ComboboxControl) {
|
||||
// See textInputFrame above (with s/amount of text/selected option/).
|
||||
|
|
|
|||
|
|
@ -93,7 +93,10 @@ object Versions {
|
|||
const val messaging = "24.0.0"
|
||||
}
|
||||
|
||||
const val play_services = "18.4.0"
|
||||
object Google {
|
||||
const val play_review = "2.0.1"
|
||||
const val play_services = "18.4.0"
|
||||
}
|
||||
}
|
||||
|
||||
// Synchronized dependencies used by (some) modules
|
||||
|
|
@ -218,5 +221,7 @@ object ComponentsDependencies {
|
|||
|
||||
const val firebase_messaging = "com.google.firebase:firebase-messaging:${Versions.Firebase.messaging}"
|
||||
|
||||
const val play_services_base = "com.google.android.gms:play-services-base:${Versions.play_services}"
|
||||
const val play_review = "com.google.android.play:review:${Versions.Google.play_review}"
|
||||
const val play_review_ktx = "com.google.android.play:review-ktx:${Versions.Google.play_review}"
|
||||
const val play_services_base = "com.google.android.gms:play-services-base:${Versions.Google.play_services}"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -693,8 +693,8 @@ dependencies {
|
|||
implementation FenixDependencies.google_ads_id // Required for the Google Advertising ID
|
||||
|
||||
// Required for in-app reviews
|
||||
implementation FenixDependencies.google_play_review
|
||||
implementation FenixDependencies.google_play_review_ktx
|
||||
implementation ComponentsDependencies.play_review
|
||||
implementation ComponentsDependencies.play_review_ktx
|
||||
|
||||
implementation FenixDependencies.androidx_profileinstaller
|
||||
|
||||
|
|
|
|||
|
|
@ -212,6 +212,7 @@ events:
|
|||
expires: never
|
||||
marketing_notification_allowed:
|
||||
type: boolean
|
||||
lifetime: application
|
||||
description: |
|
||||
True if marketing notifications are allowed, otherwise false.
|
||||
bugs:
|
||||
|
|
@ -2708,6 +2709,7 @@ metrics:
|
|||
- Wallpapers
|
||||
notifications_allowed:
|
||||
type: boolean
|
||||
lifetime: application
|
||||
description: |
|
||||
True if notifications are allowed, otherwise false.
|
||||
send_in_pings:
|
||||
|
|
@ -2791,6 +2793,7 @@ metrics:
|
|||
customize_home:
|
||||
most_visited_sites:
|
||||
type: boolean
|
||||
lifetime: application
|
||||
description: |
|
||||
An indication of whether the most visited sites
|
||||
are enabled to be displayed
|
||||
|
|
@ -2810,6 +2813,7 @@ customize_home:
|
|||
expires: never
|
||||
jump_back_in:
|
||||
type: boolean
|
||||
lifetime: application
|
||||
description: |
|
||||
An indication of whether the Jump back
|
||||
in section is enabled to be displayed
|
||||
|
|
@ -2829,6 +2833,7 @@ customize_home:
|
|||
expires: never
|
||||
bookmarks:
|
||||
type: boolean
|
||||
lifetime: application
|
||||
description: |
|
||||
An indication of whether the recently
|
||||
saved section is enabled to be displayed. This was previously customize_home.recently_saved.
|
||||
|
|
@ -2848,6 +2853,7 @@ customize_home:
|
|||
expires: never
|
||||
recently_visited:
|
||||
type: boolean
|
||||
lifetime: application
|
||||
description: |
|
||||
An indication of whether the Recently
|
||||
visited section is enabled to be displayed
|
||||
|
|
@ -2867,6 +2873,7 @@ customize_home:
|
|||
expires: never
|
||||
pocket:
|
||||
type: boolean
|
||||
lifetime: application
|
||||
description: |
|
||||
An indication of whether Pocket is enabled to be displayed
|
||||
send_in_pings:
|
||||
|
|
@ -2888,6 +2895,7 @@ customize_home:
|
|||
- PocketIntegration
|
||||
sponsored_pocket:
|
||||
type: boolean
|
||||
lifetime: application
|
||||
description: |
|
||||
An indication of whether Pocket sponsored stories are enabled
|
||||
to be displayed
|
||||
|
|
@ -2909,6 +2917,7 @@ customize_home:
|
|||
- PocketIntegration
|
||||
contile:
|
||||
type: boolean
|
||||
lifetime: application
|
||||
description: |
|
||||
An indication of whether Contile is enabled to be displayed
|
||||
send_in_pings:
|
||||
|
|
@ -2956,6 +2965,7 @@ customize_home:
|
|||
expires: never
|
||||
opening_screen:
|
||||
type: string
|
||||
lifetime: application
|
||||
description: |
|
||||
What opening screen preference the user has selected
|
||||
under "Customize Home".
|
||||
|
|
@ -2976,6 +2986,7 @@ customize_home:
|
|||
preferences:
|
||||
studies_enabled:
|
||||
type: boolean
|
||||
lifetime: application
|
||||
description: >
|
||||
A metric indicating whether or not the user has studies enabled
|
||||
default: true
|
||||
|
|
@ -3009,6 +3020,7 @@ preferences:
|
|||
expires: never
|
||||
search_suggestions_enabled:
|
||||
type: boolean
|
||||
lifetime: application
|
||||
description: |
|
||||
Whether or not the user has search suggestions enabled
|
||||
default: true
|
||||
|
|
@ -3033,6 +3045,7 @@ preferences:
|
|||
- Settings
|
||||
remote_debugging_enabled:
|
||||
type: boolean
|
||||
lifetime: application
|
||||
description: |
|
||||
Whether or not the user has remote debugging enabled
|
||||
default: false
|
||||
|
|
@ -3058,6 +3071,7 @@ preferences:
|
|||
- Settings
|
||||
telemetry_enabled:
|
||||
type: boolean
|
||||
lifetime: application
|
||||
description: |
|
||||
Whether or not the user has telemetry enabled. Note we should
|
||||
never receive a "false" value for this since telemetry would
|
||||
|
|
@ -3084,6 +3098,7 @@ preferences:
|
|||
- Settings
|
||||
enhanced_tracking_protection:
|
||||
type: string
|
||||
lifetime: application
|
||||
description: |
|
||||
What type of enhanced tracking protection the user has enabled.
|
||||
"standard," "strict," "custom," or "" (if disabled)
|
||||
|
|
@ -3111,6 +3126,7 @@ preferences:
|
|||
- Settings
|
||||
etp_custom_cookies_selection:
|
||||
type: string
|
||||
lifetime: application
|
||||
description: |
|
||||
The option user has selected in the "Custom" mode of the
|
||||
Enhanced Tracking Protection settings.
|
||||
|
|
@ -3138,6 +3154,7 @@ preferences:
|
|||
- Settings
|
||||
bookmarks_suggestion:
|
||||
type: boolean
|
||||
lifetime: application
|
||||
description: |
|
||||
Whether or not the user has enabled bookmark search suggestions
|
||||
default: true
|
||||
|
|
@ -3163,6 +3180,7 @@ preferences:
|
|||
- Settings
|
||||
browsing_history_suggestion:
|
||||
type: boolean
|
||||
lifetime: application
|
||||
description: |
|
||||
Whether or not the user has enabled browsing history suggestions.
|
||||
default: true
|
||||
|
|
@ -3188,6 +3206,7 @@ preferences:
|
|||
- Settings
|
||||
clipboard_suggestions_enabled:
|
||||
type: boolean
|
||||
lifetime: application
|
||||
description: |
|
||||
Whether or not the user has enabled clipboard search suggestions.
|
||||
default: true
|
||||
|
|
@ -3213,6 +3232,7 @@ preferences:
|
|||
- Settings
|
||||
search_shortcuts_enabled:
|
||||
type: boolean
|
||||
lifetime: application
|
||||
description: |
|
||||
Whether or not the user has enabled search shortcuts.
|
||||
default: true
|
||||
|
|
@ -3237,6 +3257,7 @@ preferences:
|
|||
- Settings
|
||||
signed_in_sync:
|
||||
type: boolean
|
||||
lifetime: application
|
||||
description: |
|
||||
Whether or not the user is signed into FxA
|
||||
default: false
|
||||
|
|
@ -3263,6 +3284,7 @@ preferences:
|
|||
- Settings
|
||||
sync_items:
|
||||
type: string_list
|
||||
lifetime: application
|
||||
description: |
|
||||
The list of items the user has chosen to sync with FxA.
|
||||
default: "" if the user is signed out. Otherwise defaults to
|
||||
|
|
@ -3290,6 +3312,7 @@ preferences:
|
|||
- Settings
|
||||
voice_search_enabled:
|
||||
type: boolean
|
||||
lifetime: application
|
||||
description: |
|
||||
Whether or not the user has enabled the voice search button.
|
||||
default: true
|
||||
|
|
@ -3317,6 +3340,7 @@ preferences:
|
|||
- Settings
|
||||
toolbar_position_setting:
|
||||
type: string
|
||||
lifetime: application
|
||||
description: |
|
||||
The position of the toolbar
|
||||
default: bottom (defaults to top if the user has accessibility services)
|
||||
|
|
@ -3341,6 +3365,7 @@ preferences:
|
|||
- Settings
|
||||
accessibility_services:
|
||||
type: string_list
|
||||
lifetime: application
|
||||
description: |
|
||||
Whether or not the user has touch exploration or switch services enabled.
|
||||
These are built into the Android OS, not Fenix prefs.
|
||||
|
|
@ -3365,6 +3390,7 @@ preferences:
|
|||
- Settings
|
||||
open_links_in_app_enabled:
|
||||
type: string
|
||||
lifetime: application
|
||||
description: |
|
||||
The user has the open links in apps feature enabled.
|
||||
"ask_before_opening", "always" or "never".
|
||||
|
|
@ -3385,6 +3411,7 @@ preferences:
|
|||
- Settings
|
||||
user_theme:
|
||||
type: string
|
||||
lifetime: application
|
||||
description: |
|
||||
The theme the user has enabled. "light," "dark," "system," or "battery"
|
||||
default: "system" for API 28+, else "light"
|
||||
|
|
@ -3409,6 +3436,7 @@ preferences:
|
|||
- Settings
|
||||
inactive_tabs_enabled:
|
||||
type: boolean
|
||||
lifetime: application
|
||||
description: |
|
||||
Whether or not the user has the inactive tabs feature enabled.
|
||||
default: true
|
||||
|
|
@ -6681,6 +6709,7 @@ logins:
|
|||
- Logins
|
||||
saved_all:
|
||||
type: quantity
|
||||
lifetime: application
|
||||
description: |
|
||||
Counter of number of passwords currently saved by user.
|
||||
bugs:
|
||||
|
|
@ -7065,11 +7094,11 @@ top_sites:
|
|||
expires: never
|
||||
context_id:
|
||||
type: uuid
|
||||
lifetime: application
|
||||
description: |
|
||||
A UUID that is unjoinable with other browser metrics. This ID will not be
|
||||
shared with AdM, only for internal uses. This ID is shared across all
|
||||
contextual services features.
|
||||
lifetime: application
|
||||
send_in_pings:
|
||||
- topsites-impression
|
||||
bugs:
|
||||
|
|
@ -7626,6 +7655,7 @@ first_session:
|
|||
- Attribution
|
||||
distribution_id:
|
||||
type: string
|
||||
lifetime: application
|
||||
description: |
|
||||
A string containing the distribution identifier. This is currently used
|
||||
to identify installs from Mozilla Online.
|
||||
|
|
@ -8086,6 +8116,7 @@ addons:
|
|||
- WebExtensions
|
||||
has_installed_addons:
|
||||
type: boolean
|
||||
lifetime: application
|
||||
description: |
|
||||
Whether or not the user has installed add-ons on the device.
|
||||
send_in_pings:
|
||||
|
|
@ -8109,6 +8140,7 @@ addons:
|
|||
- WebExtensions
|
||||
has_enabled_addons:
|
||||
type: boolean
|
||||
lifetime: application
|
||||
description: |
|
||||
Whether or not the user has enabled add-ons on the device.
|
||||
send_in_pings:
|
||||
|
|
@ -9465,6 +9497,7 @@ awesomebar:
|
|||
android_autofill:
|
||||
supported:
|
||||
type: boolean
|
||||
lifetime: application
|
||||
description: |
|
||||
Whether or not Android Autofill is supported by the device and is
|
||||
supported for this user.
|
||||
|
|
@ -9482,6 +9515,7 @@ android_autofill:
|
|||
expires: never
|
||||
enabled:
|
||||
type: boolean
|
||||
lifetime: application
|
||||
description: |
|
||||
Whether or not Firefox is the Android Autofill provider for this user.
|
||||
provider.
|
||||
|
|
@ -9992,6 +10026,7 @@ recent_searches:
|
|||
credit_cards:
|
||||
saved:
|
||||
type: counter
|
||||
lifetime: application
|
||||
description: |
|
||||
A counter of the number of credit cards that have been saved
|
||||
manually by the user.
|
||||
|
|
@ -11343,6 +11378,7 @@ shopping:
|
|||
shopping.settings:
|
||||
component_opted_out:
|
||||
type: boolean
|
||||
lifetime: application
|
||||
description: |
|
||||
Whether or not the user opted out of review quality check feature.
|
||||
send_in_pings:
|
||||
|
|
@ -11362,6 +11398,7 @@ shopping.settings:
|
|||
- Shopping
|
||||
nimbus_disabled_shopping:
|
||||
type: boolean
|
||||
lifetime: application
|
||||
description: |
|
||||
Whether or not Nimbus has disabled the use of the shopping component.
|
||||
send_in_pings:
|
||||
|
|
@ -11381,6 +11418,7 @@ shopping.settings:
|
|||
- Shopping
|
||||
user_has_onboarded:
|
||||
type: boolean
|
||||
lifetime: application
|
||||
description: |
|
||||
Whether or the user has completed the review quality check onboarding.
|
||||
send_in_pings:
|
||||
|
|
@ -11400,6 +11438,7 @@ shopping.settings:
|
|||
- Shopping
|
||||
disabled_ads:
|
||||
type: boolean
|
||||
lifetime: application
|
||||
description: |
|
||||
Indicates if the user has disabled ads.
|
||||
send_in_pings:
|
||||
|
|
|
|||
|
|
@ -34,8 +34,6 @@ object FenixVersions {
|
|||
|
||||
const val google_ads_id_version = "16.0.0"
|
||||
|
||||
const val google_play_review_version = "2.0.1"
|
||||
|
||||
// keep in sync with the versions used in AS.
|
||||
const val protobuf = "3.21.10"
|
||||
const val protobuf_plugin = "0.9.4"
|
||||
|
|
@ -87,10 +85,6 @@ object FenixDependencies {
|
|||
|
||||
const val google_ads_id = "com.google.android.gms:play-services-ads-identifier:${FenixVersions.google_ads_id_version}"
|
||||
|
||||
// Required for in-app reviews
|
||||
const val google_play_review = "com.google.android.play:review:${FenixVersions.google_play_review_version}"
|
||||
const val google_play_review_ktx = "com.google.android.play:review-ktx:${FenixVersions.google_play_review_version}"
|
||||
|
||||
const val junitApi = "org.junit.jupiter:junit-jupiter-api:${FenixVersions.junit}"
|
||||
const val junitParams = "org.junit.jupiter:junit-jupiter-params:${FenixVersions.junit}"
|
||||
const val junitEngine = "org.junit.jupiter:junit-jupiter-engine:${FenixVersions.junit}"
|
||||
|
|
|
|||
|
|
@ -297,7 +297,9 @@ dependencies {
|
|||
implementation ComponentsDependencies.androidx_work_runtime
|
||||
implementation ComponentsDependencies.androidx_datastore_preferences
|
||||
|
||||
implementation FocusDependencies.google_play
|
||||
// Required for in-app reviews
|
||||
implementation ComponentsDependencies.play_review
|
||||
implementation ComponentsDependencies.play_review_ktx
|
||||
|
||||
implementation ComponentsDependencies.google_material
|
||||
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@ import android.content.Context
|
|||
import android.content.Intent
|
||||
import androidx.core.net.toUri
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.google.android.gms.tasks.Task
|
||||
import com.google.android.play.core.review.ReviewInfo
|
||||
import com.google.android.play.core.review.ReviewManagerFactory
|
||||
import com.google.android.play.core.tasks.Task
|
||||
import mozilla.components.browser.state.state.SessionState
|
||||
import org.mozilla.focus.R
|
||||
import org.mozilla.focus.ext.components
|
||||
|
|
@ -40,7 +40,7 @@ class AppReviewUtils {
|
|||
request.addOnCompleteListener { task: Task<ReviewInfo?> ->
|
||||
if (task.isSuccessful) {
|
||||
// We can get the ReviewInfo object
|
||||
val reviewInfo = task.result
|
||||
val reviewInfo = task.result ?: return@addOnCompleteListener
|
||||
val flow = manager.launchReviewFlow(activity, reviewInfo)
|
||||
flow.addOnCompleteListener {
|
||||
// The flow has finished. The API does not indicate whether the user
|
||||
|
|
|
|||
|
|
@ -24,10 +24,6 @@ object FocusVersions {
|
|||
const val transition = "1.5.0"
|
||||
}
|
||||
|
||||
object Google {
|
||||
const val play = "1.10.3"
|
||||
}
|
||||
|
||||
object Testing {
|
||||
const val androidx_espresso = "3.5.1"
|
||||
const val androidx_orchestrator = "1.4.2"
|
||||
|
|
@ -48,8 +44,6 @@ object FocusDependencies {
|
|||
const val androidx_splashscreen = "androidx.core:core-splashscreen:${FocusVersions.AndroidX.splashscreen}"
|
||||
const val androidx_transition = "androidx.transition:transition:${FocusVersions.AndroidX.transition}"
|
||||
|
||||
const val google_play = "com.google.android.play:core:${FocusVersions.Google.play}"
|
||||
|
||||
const val adjust = "com.adjust.sdk:adjust-android:${FocusVersions.Adjust.adjust}"
|
||||
const val install_referrer = "com.android.installreferrer:installreferrer:${FocusVersions.Adjust.install_referrer}"
|
||||
const val osslicenses_plugin = "com.google.android.gms:oss-licenses-plugin:${FocusVersions.ThirdParty.osslicenses_plugin}"
|
||||
|
|
|
|||
|
|
@ -5631,6 +5631,13 @@
|
|||
type: bool
|
||||
value: true
|
||||
mirror: always
|
||||
|
||||
# Time in milliseconds after which geoclue will try to fallback to MLS if no
|
||||
# location is received after successful start.
|
||||
- name: geo.provider.geoclue.mls_fallback_timeout_ms
|
||||
type: uint32_t
|
||||
value: 5000
|
||||
mirror: always
|
||||
#endif
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
|
||||
|
||||
import os
|
||||
from functools import lru_cache
|
||||
|
||||
import yaml
|
||||
from taskgraph.util.memoize import memoize
|
||||
|
||||
from android_taskgraph import ANDROID_COMPONENTS_DIR, FENIX_DIR, FOCUS_DIR
|
||||
|
||||
|
|
@ -47,7 +47,7 @@ def get_extensions(component):
|
|||
]
|
||||
|
||||
|
||||
@memoize
|
||||
@lru_cache(maxsize=None)
|
||||
def _read_build_config(root_dir):
|
||||
with open(os.path.join(root_dir, ".buildconfig.yml"), "rb") as f:
|
||||
return yaml.safe_load(f)
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
|
||||
from gecko_taskgraph.loader.transform import loader as base_loader
|
||||
from taskgraph.loader.transform import loader as base_loader
|
||||
from taskgraph.util.templates import merge
|
||||
|
||||
from ..build_config import get_apk_based_projects, get_components
|
||||
|
|
@ -14,7 +14,7 @@ def components_loader(kind, path, config, params, loaded_tasks):
|
|||
|
||||
Android-components are read from android-component/.buildconfig.yml
|
||||
"""
|
||||
config["jobs"] = _get_components_tasks(config)
|
||||
config["tasks"] = _get_components_tasks(config)
|
||||
return base_loader(kind, path, config, params, loaded_tasks)
|
||||
|
||||
|
||||
|
|
@ -24,12 +24,12 @@ def components_and_apks_loader(kind, path, config, params, loaded_tasks):
|
|||
For instance focus-android yields one task.
|
||||
Config is read from various .buildconfig.yml files.
|
||||
|
||||
Additional tasks can be provided in the kind.yml under the key `jobs`.
|
||||
Additional tasks can be provided in the kind.yml under the key `tasks`.
|
||||
"""
|
||||
|
||||
components_tasks = _get_components_tasks(config, for_build_type="regular")
|
||||
apks_tasks = _get_apks_tasks(config)
|
||||
config["jobs"] = merge(config["jobs"], components_tasks, apks_tasks)
|
||||
config["tasks"] = merge(config["tasks"], components_tasks, apks_tasks)
|
||||
return base_loader(kind, path, config, params, loaded_tasks)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -6,14 +6,14 @@ import itertools
|
|||
import os
|
||||
from copy import deepcopy
|
||||
from datetime import datetime
|
||||
from functools import lru_cache
|
||||
|
||||
import jsone
|
||||
from taskgraph.util.memoize import memoize
|
||||
from taskgraph.util.schema import resolve_keyed_by
|
||||
from taskgraph.util.taskcluster import get_artifact_prefix
|
||||
from taskgraph.util.yaml import load_yaml
|
||||
|
||||
cached_load_yaml = memoize(load_yaml)
|
||||
cached_load_yaml = lru_cache(maxsize=None)(load_yaml)
|
||||
|
||||
|
||||
def generate_beetmover_upstream_artifacts(
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ Each variant must conform to the
|
|||
to be applied. The ``task`` definition is passed in as context.
|
||||
* **replace** - A dictionary that will overwrite keys in the task definition.
|
||||
* **merge** - A dictionary that will be merged into the task definition using
|
||||
the :py:func:`~gecko_taskgraph.util.templates.merge` function.
|
||||
the :py:func:`~taskgraph.util.templates.merge` function.
|
||||
|
||||
.. note::
|
||||
|
||||
|
|
|
|||
|
|
@ -5,12 +5,10 @@
|
|||
|
||||
import logging
|
||||
|
||||
from taskgraph.loader.transform import loader as transform_loader
|
||||
from taskgraph.util.copy import deepcopy
|
||||
from taskgraph.util.yaml import load_yaml
|
||||
|
||||
from gecko_taskgraph.util.copy_task import copy_task
|
||||
|
||||
from .transform import loader as transform_loader
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
|
@ -43,7 +41,7 @@ def loader(kind, path, config, params, loaded_tasks):
|
|||
# generate all tests for all test platforms
|
||||
for test_platform_name, test_platform in test_platforms.items():
|
||||
for test_name in test_platform["test-names"]:
|
||||
test = copy_task(test_descriptions[test_name])
|
||||
test = deepcopy(test_descriptions[test_name])
|
||||
test["build-platform"] = test_platform["build-platform"]
|
||||
test["test-platform"] = test_platform_name
|
||||
test["build-label"] = test_platform["build-label"]
|
||||
|
|
|
|||
|
|
@ -1,59 +0,0 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
|
||||
import logging
|
||||
|
||||
from taskgraph.util.yaml import load_yaml
|
||||
|
||||
from ..util.templates import merge
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def loader(kind, path, config, params, loaded_tasks):
|
||||
"""
|
||||
Get the input elements that will be transformed into tasks in a generic
|
||||
way. The elements themselves are free-form, and become the input to the
|
||||
first transform.
|
||||
|
||||
By default, this reads jobs from the `jobs` key, or from yaml files
|
||||
named by `jobs-from`. The entities are read from mappings, and the
|
||||
keys to those mappings are added in the `name` key of each entity.
|
||||
|
||||
If there is a `job-defaults` config, then every job is merged with it.
|
||||
This provides a simple way to set default values for all jobs of a kind.
|
||||
The `job-defaults` key can also be specified in a yaml file pointed to by
|
||||
`jobs-from`. In this case it will only apply to tasks defined in the same
|
||||
file.
|
||||
|
||||
Other kind implementations can use a different loader function to
|
||||
produce inputs and hand them to `transform_inputs`.
|
||||
"""
|
||||
|
||||
def jobs():
|
||||
defaults = config.get("job-defaults")
|
||||
for name, job in config.get("jobs", {}).items():
|
||||
if defaults:
|
||||
job = merge(defaults, job)
|
||||
job["job-from"] = "kind.yml"
|
||||
yield name, job
|
||||
|
||||
for filename in config.get("jobs-from", []):
|
||||
tasks = load_yaml(path, filename)
|
||||
|
||||
file_defaults = tasks.pop("job-defaults", None)
|
||||
if defaults:
|
||||
file_defaults = merge(defaults, file_defaults or {})
|
||||
|
||||
for name, job in tasks.items():
|
||||
if file_defaults:
|
||||
job = merge(file_defaults, job)
|
||||
job["job-from"] = filename
|
||||
yield name, job
|
||||
|
||||
for name, job in jobs():
|
||||
job["name"] = name
|
||||
logger.debug(f"Generating tasks for {kind} {name}")
|
||||
yield job
|
||||
|
|
@ -63,7 +63,7 @@ def format_taskgraph_json(taskgraph):
|
|||
|
||||
|
||||
def format_taskgraph_yaml(taskgraph):
|
||||
from mozbuild.util import ReadOnlyDict
|
||||
from taskgraph.util.readonlydict import ReadOnlyDict
|
||||
|
||||
class TGDumper(yaml.SafeDumper):
|
||||
def ignore_aliases(self, data):
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@ from taskgraph.generator import Kind, TaskGraphGenerator
|
|||
from taskgraph.optimize import base as optimize_mod
|
||||
from taskgraph.optimize.base import OptimizationStrategy
|
||||
from taskgraph.parameters import Parameters
|
||||
from taskgraph.util.templates import merge
|
||||
|
||||
from gecko_taskgraph import GECKO
|
||||
from gecko_taskgraph.actions import render_actions_json
|
||||
from gecko_taskgraph.util.templates import merge
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
|
@ -74,8 +74,8 @@ def fake_loader(kind, path, config, parameters, loaded_tasks):
|
|||
},
|
||||
"dependencies": dependencies,
|
||||
}
|
||||
if "job-defaults" in config:
|
||||
task = merge(config["job-defaults"], task)
|
||||
if "task-defaults" in config:
|
||||
task = merge(config["task-defaults"], task)
|
||||
yield task
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -6,8 +6,7 @@
|
|||
import unittest
|
||||
|
||||
import mozunit
|
||||
|
||||
from gecko_taskgraph.util.templates import merge, merge_to
|
||||
from taskgraph.util.templates import merge, merge_to
|
||||
|
||||
|
||||
class MergeTest(unittest.TestCase):
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ balrog_description_schema = Schema(
|
|||
Optional("treeherder"): task_description_schema["treeherder"],
|
||||
Optional("attributes"): task_description_schema["attributes"],
|
||||
Optional("dependencies"): task_description_schema["dependencies"],
|
||||
Optional("job-from"): task_description_schema["job-from"],
|
||||
Optional("task-from"): task_description_schema["task-from"],
|
||||
# Shipping product / phase
|
||||
Optional("shipping-product"): task_description_schema["shipping-product"],
|
||||
Optional("shipping-phase"): task_description_schema["shipping-phase"],
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ beetmover_description_schema = Schema(
|
|||
Required("shipping-phase"): task_description_schema["shipping-phase"],
|
||||
Optional("shipping-product"): task_description_schema["shipping-product"],
|
||||
Optional("attributes"): task_description_schema["attributes"],
|
||||
Optional("job-from"): task_description_schema["job-from"],
|
||||
Optional("task-from"): task_description_schema["task-from"],
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ beetmover_checksums_description_schema = Schema(
|
|||
Optional("locale"): str,
|
||||
Optional("shipping-phase"): task_description_schema["shipping-phase"],
|
||||
Optional("shipping-product"): task_description_schema["shipping-product"],
|
||||
Optional("job-from"): task_description_schema["job-from"],
|
||||
Optional("task-from"): task_description_schema["task-from"],
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ beetmover_checksums_description_schema = Schema(
|
|||
Optional("extra"): object,
|
||||
Optional("shipping-phase"): task_description_schema["shipping-phase"],
|
||||
Optional("shipping-product"): task_description_schema["shipping-product"],
|
||||
Optional("job-from"): task_description_schema["job-from"],
|
||||
Optional("task-from"): task_description_schema["task-from"],
|
||||
Optional("attributes"): task_description_schema["attributes"],
|
||||
Optional("dependencies"): task_description_schema["dependencies"],
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ beetmover_description_schema = Schema(
|
|||
),
|
||||
Optional("shipping-product"): task_description_schema["shipping-product"],
|
||||
Optional("attributes"): task_description_schema["attributes"],
|
||||
Optional("job-from"): task_description_schema["job-from"],
|
||||
Optional("task-from"): task_description_schema["task-from"],
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ beetmover_checksums_description_schema = Schema(
|
|||
Optional("treeherder"): task_description_schema["treeherder"],
|
||||
Optional("locale"): str,
|
||||
Optional("dependencies"): task_description_schema["dependencies"],
|
||||
Optional("job-from"): task_description_schema["job-from"],
|
||||
Optional("task-from"): task_description_schema["task-from"],
|
||||
Optional("shipping-phase"): task_description_schema["shipping-phase"],
|
||||
Optional("shipping-product"): task_description_schema["shipping-product"],
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ beetmover_push_to_release_description_schema = Schema(
|
|||
Required("product"): str,
|
||||
Required("treeherder-platform"): str,
|
||||
Optional("attributes"): {str: object},
|
||||
Optional("job-from"): task_description_schema["job-from"],
|
||||
Optional("task-from"): task_description_schema["task-from"],
|
||||
Optional("run"): {str: object},
|
||||
Optional("run-on-projects"): task_description_schema["run-on-projects"],
|
||||
Optional("dependencies"): {str: taskref_or_string},
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ beetmover_description_schema = Schema(
|
|||
# locale is passed only for l10n beetmoving
|
||||
Optional("locale"): str,
|
||||
Required("shipping-phase"): task_description_schema["shipping-phase"],
|
||||
Optional("job-from"): task_description_schema["job-from"],
|
||||
Optional("task-from"): task_description_schema["task-from"],
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ beetmover_description_schema = Schema(
|
|||
Required("shipping-phase"): task_description_schema["shipping-phase"],
|
||||
Optional("shipping-product"): task_description_schema["shipping-product"],
|
||||
Optional("priority"): task_description_schema["priority"],
|
||||
Optional("job-from"): task_description_schema["job-from"],
|
||||
Optional("task-from"): task_description_schema["task-from"],
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ beetmover_checksums_description_schema = Schema(
|
|||
Optional("shipping-product"): task_description_schema["shipping-product"],
|
||||
Optional("attributes"): task_description_schema["attributes"],
|
||||
Optional("dependencies"): task_description_schema["dependencies"],
|
||||
Optional("job-from"): task_description_schema["job-from"],
|
||||
Optional("task-from"): task_description_schema["task-from"],
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ bootstrap_schema = Schema(
|
|||
# Initialization commands.
|
||||
Required("pre-commands"): [str],
|
||||
# relative path (from config.path) to the file task was defined in
|
||||
Optional("job-from"): str,
|
||||
Optional("task-from"): str,
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -7,12 +7,12 @@ the condprof/kind.yml file
|
|||
"""
|
||||
|
||||
from taskgraph.transforms.base import TransformSequence
|
||||
from taskgraph.util.copy import deepcopy
|
||||
from taskgraph.util.schema import Schema
|
||||
from voluptuous import Optional
|
||||
|
||||
from gecko_taskgraph.transforms.job import job_description_schema
|
||||
from gecko_taskgraph.transforms.task import task_description_schema
|
||||
from gecko_taskgraph.util.copy_task import copy_task
|
||||
|
||||
diff_description_schema = Schema(
|
||||
{
|
||||
|
|
@ -22,7 +22,7 @@ diff_description_schema = Schema(
|
|||
Optional("dependencies"): task_description_schema["dependencies"],
|
||||
Optional("fetches"): job_description_schema["fetches"],
|
||||
Optional("index"): task_description_schema["index"],
|
||||
Optional("job-from"): str,
|
||||
Optional("task-from"): str,
|
||||
Optional("name"): str,
|
||||
Optional("run"): job_description_schema["run"],
|
||||
Optional("run-on-projects"): task_description_schema["run-on-projects"],
|
||||
|
|
@ -67,21 +67,21 @@ def generate_scenarios(config, tasks):
|
|||
"kind": task["treeherder"]["kind"],
|
||||
"tier": task["treeherder"]["tier"],
|
||||
},
|
||||
"worker-type": copy_task(task["worker-type"]),
|
||||
"worker": copy_task(task["worker"]),
|
||||
"index": copy_task(index),
|
||||
"worker-type": deepcopy(task["worker-type"]),
|
||||
"worker": deepcopy(task["worker"]),
|
||||
"index": deepcopy(index),
|
||||
"run": {
|
||||
"using": "run-task",
|
||||
"cwd": task["run"]["cwd"],
|
||||
"checkout": task["run"]["checkout"],
|
||||
"tooltool-downloads": copy_task(task["run"]["tooltool-downloads"]),
|
||||
"tooltool-downloads": deepcopy(task["run"]["tooltool-downloads"]),
|
||||
"command": tcmd,
|
||||
"run-as-root": run_as_root,
|
||||
},
|
||||
"run-on-projects": copy_task(task["run-on-projects"]),
|
||||
"scopes": copy_task(task["scopes"]),
|
||||
"dependencies": copy_task(task["dependencies"]),
|
||||
"fetches": copy_task(task["fetches"]),
|
||||
"run-on-projects": deepcopy(task["run-on-projects"]),
|
||||
"scopes": deepcopy(task["scopes"]),
|
||||
"dependencies": deepcopy(task["dependencies"]),
|
||||
"fetches": deepcopy(task["fetches"]),
|
||||
}
|
||||
|
||||
use_taskcluster_python = task.get("use-python", "system")
|
||||
|
|
|
|||
|
|
@ -27,11 +27,11 @@ diff_description_schema = Schema(
|
|||
# Treeherder symbol.
|
||||
Required("symbol"): str,
|
||||
# relative path (from config.path) to the file the task was defined in.
|
||||
Optional("job-from"): str,
|
||||
Optional("task-from"): str,
|
||||
# Original and new builds to compare.
|
||||
Required("original"): index_or_string,
|
||||
Required("new"): index_or_string,
|
||||
# Arguments to pass to diffoscope, used for job-defaults in
|
||||
# Arguments to pass to diffoscope, used for task-defaults in
|
||||
# taskcluster/kinds/diffoscope/kind.yml
|
||||
Optional("args"): str,
|
||||
# Extra arguments to pass to diffoscope, that can be set per job.
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ docker_image_schema = Schema(
|
|||
Required("symbol"): str,
|
||||
# relative path (from config.path) to the file the docker image was defined
|
||||
# in.
|
||||
Optional("job-from"): str,
|
||||
Optional("task-from"): str,
|
||||
# Arguments to use for the Dockerfile.
|
||||
Optional("args"): {str: str},
|
||||
# Name of the docker image definition under taskcluster/docker, when
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ FETCH_SCHEMA = Schema(
|
|||
Required("name"): str,
|
||||
# Relative path (from config.path) to the file the task was defined
|
||||
# in.
|
||||
Optional("job-from"): str,
|
||||
Optional("task-from"): str,
|
||||
# Description of the task.
|
||||
Required("description"): str,
|
||||
Optional(
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ geckodriver_notarization_description_schema = Schema(
|
|||
Optional("shipping-phase"): task_description_schema["shipping-phase"],
|
||||
Optional("worker"): task_description_schema["worker"],
|
||||
Optional("worker-type"): task_description_schema["worker-type"],
|
||||
Optional("job-from"): task_description_schema["job-from"],
|
||||
Optional("task-from"): task_description_schema["task-from"],
|
||||
Optional("attributes"): task_description_schema["attributes"],
|
||||
Optional("dependencies"): task_description_schema["dependencies"],
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ repackage_signing_description_schema = Schema(
|
|||
Optional("dependencies"): task_description_schema["dependencies"],
|
||||
Optional("treeherder"): task_description_schema["treeherder"],
|
||||
Optional("shipping-phase"): task_description_schema["shipping-phase"],
|
||||
Optional("job-from"): task_description_schema["job-from"],
|
||||
Optional("task-from"): task_description_schema["task-from"],
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import logging
|
|||
import mozpack.path as mozpath
|
||||
from packaging.version import Version
|
||||
from taskgraph.transforms.base import TransformSequence
|
||||
from taskgraph.util.copy import deepcopy
|
||||
from taskgraph.util.python_path import import_sibling_modules
|
||||
from taskgraph.util.schema import Schema, validate_schema
|
||||
from taskgraph.util.taskcluster import get_artifact_prefix
|
||||
|
|
@ -23,7 +24,6 @@ from voluptuous import Any, Coerce, Exclusive, Extra, Optional, Required
|
|||
|
||||
from gecko_taskgraph.transforms.cached_tasks import order_tasks
|
||||
from gecko_taskgraph.transforms.task import task_description_schema
|
||||
from gecko_taskgraph.util.copy_task import copy_task
|
||||
from gecko_taskgraph.util.workertypes import worker_type_implementation
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
|
@ -41,7 +41,7 @@ job_description_schema = Schema(
|
|||
# taskcluster/gecko_taskgraph/transforms/task.py for the schema details.
|
||||
Required("description"): task_description_schema["description"],
|
||||
Optional("attributes"): task_description_schema["attributes"],
|
||||
Optional("job-from"): task_description_schema["job-from"],
|
||||
Optional("task-from"): task_description_schema["task-from"],
|
||||
Optional("dependencies"): task_description_schema["dependencies"],
|
||||
Optional("if-dependencies"): task_description_schema["if-dependencies"],
|
||||
Optional("soft-dependencies"): task_description_schema["soft-dependencies"],
|
||||
|
|
@ -213,7 +213,7 @@ def make_task_description(config, jobs):
|
|||
if job["worker"]["implementation"] == "docker-worker":
|
||||
job["run"].setdefault("workdir", "/builds/worker")
|
||||
|
||||
taskdesc = copy_task(job)
|
||||
taskdesc = deepcopy(job)
|
||||
|
||||
# fill in some empty defaults to make run implementations easier
|
||||
taskdesc.setdefault("attributes", {})
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import json
|
|||
|
||||
from mozbuild.chunkify import chunkify
|
||||
from taskgraph.transforms.base import TransformSequence
|
||||
from taskgraph.util.copy import deepcopy
|
||||
from taskgraph.util.dependencies import get_dependencies, get_primary_dependency
|
||||
from taskgraph.util.schema import (
|
||||
Schema,
|
||||
|
|
@ -28,7 +29,6 @@ from gecko_taskgraph.util.attributes import (
|
|||
sorted_unique_list,
|
||||
task_name,
|
||||
)
|
||||
from gecko_taskgraph.util.copy_task import copy_task
|
||||
|
||||
|
||||
def _by_platform(arg):
|
||||
|
|
@ -119,7 +119,7 @@ l10n_description_schema = Schema(
|
|||
# Shipping product and phase
|
||||
Optional("shipping-product"): task_description_schema["shipping-product"],
|
||||
Optional("shipping-phase"): task_description_schema["shipping-phase"],
|
||||
Optional("job-from"): task_description_schema["job-from"],
|
||||
Optional("task-from"): task_description_schema["task-from"],
|
||||
}
|
||||
)
|
||||
|
||||
|
|
@ -233,7 +233,7 @@ def handle_keyed_by(config, jobs):
|
|||
"when.files-changed",
|
||||
]
|
||||
for job in jobs:
|
||||
job = copy_task(job) # don't overwrite dict values here
|
||||
job = deepcopy(job) # don't overwrite dict values here
|
||||
for field in fields:
|
||||
resolve_keyed_by(item=job, field=field, item_name=job["name"])
|
||||
yield job
|
||||
|
|
@ -285,7 +285,7 @@ def chunk_locales(config, jobs):
|
|||
if remainder:
|
||||
chunks = int(chunks + 1)
|
||||
for this_chunk in range(1, chunks + 1):
|
||||
chunked = copy_task(job)
|
||||
chunked = deepcopy(job)
|
||||
chunked["name"] = chunked["name"].replace("/", f"-{this_chunk}/", 1)
|
||||
chunked["mozharness"]["options"] = chunked["mozharness"].get(
|
||||
"options", []
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ signing_description_schema = Schema(
|
|||
Optional("shipping-phase"): task_description_schema["shipping-phase"],
|
||||
Optional("attributes"): task_description_schema["attributes"],
|
||||
Optional("dependencies"): task_description_schema["dependencies"],
|
||||
Optional("job-from"): task_description_schema["job-from"],
|
||||
Optional("task-from"): task_description_schema["task-from"],
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ from gecko_taskgraph.util.scriptworker import (
|
|||
beetmover_description_schema = Schema(
|
||||
{
|
||||
# from the loader:
|
||||
Optional("job-from"): str,
|
||||
Optional("task-from"): str,
|
||||
Optional("name"): str,
|
||||
# from the from_deps transforms:
|
||||
Optional("attributes"): task_description_schema["attributes"],
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ beetmover_description_schema = Schema(
|
|||
# locale is passed only for l10n beetmoving
|
||||
Optional("locale"): str,
|
||||
Optional("shipping-phase"): task_description_schema["shipping-phase"],
|
||||
Optional("job-from"): task_description_schema["job-from"],
|
||||
Optional("task-from"): task_description_schema["task-from"],
|
||||
Optional("dependencies"): task_description_schema["dependencies"],
|
||||
}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ from gecko_taskgraph.util.scriptworker import add_scope_prefix
|
|||
push_flatpak_description_schema = Schema(
|
||||
{
|
||||
Required("name"): str,
|
||||
Required("job-from"): task_description_schema["job-from"],
|
||||
Required("task-from"): task_description_schema["task-from"],
|
||||
Required("dependencies"): task_description_schema["dependencies"],
|
||||
Required("description"): task_description_schema["description"],
|
||||
Required("treeherder"): task_description_schema["treeherder"],
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ release_generate_checksums_beetmover_schema = Schema(
|
|||
Optional("shipping-phase"): task_description_schema["shipping-phase"],
|
||||
Optional("shipping-product"): task_description_schema["shipping-product"],
|
||||
Optional("attributes"): task_description_schema["attributes"],
|
||||
Optional("job-from"): task_description_schema["job-from"],
|
||||
Optional("task-from"): task_description_schema["task-from"],
|
||||
Optional("dependencies"): task_description_schema["dependencies"],
|
||||
}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ release_generate_checksums_signing_schema = Schema(
|
|||
Optional("treeherder"): task_description_schema["treeherder"],
|
||||
Optional("shipping-product"): task_description_schema["shipping-product"],
|
||||
Optional("shipping-phase"): task_description_schema["shipping-phase"],
|
||||
Optional("job-from"): task_description_schema["job-from"],
|
||||
Optional("task-from"): task_description_schema["task-from"],
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ from gecko_taskgraph.util.scriptworker import add_scope_prefix
|
|||
push_msix_description_schema = Schema(
|
||||
{
|
||||
Required("name"): str,
|
||||
Required("job-from"): task_description_schema["job-from"],
|
||||
Required("task-from"): task_description_schema["task-from"],
|
||||
Required("dependencies"): task_description_schema["dependencies"],
|
||||
Required("description"): task_description_schema["description"],
|
||||
Required("treeherder"): task_description_schema["treeherder"],
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ langpack_sign_push_description_schema = Schema(
|
|||
Required("run-on-projects"): [],
|
||||
Required("scopes"): optionally_keyed_by("release-level", [str]),
|
||||
Required("shipping-phase"): task_description_schema["shipping-phase"],
|
||||
Optional("job-from"): task_description_schema["job-from"],
|
||||
Optional("task-from"): task_description_schema["task-from"],
|
||||
Optional("attributes"): task_description_schema["attributes"],
|
||||
Optional("dependencies"): task_description_schema["dependencies"],
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ Transform the repackage task into an actual task description.
|
|||
"""
|
||||
|
||||
from taskgraph.transforms.base import TransformSequence
|
||||
from taskgraph.util.copy import deepcopy
|
||||
from taskgraph.util.dependencies import get_primary_dependency
|
||||
from taskgraph.util.schema import Schema, optionally_keyed_by, resolve_keyed_by
|
||||
from taskgraph.util.taskcluster import get_artifact_prefix
|
||||
|
|
@ -13,7 +14,6 @@ from voluptuous import Extra, Optional, Required
|
|||
|
||||
from gecko_taskgraph.transforms.job import job_description_schema
|
||||
from gecko_taskgraph.util.attributes import copy_attributes_from_dependent_job
|
||||
from gecko_taskgraph.util.copy_task import copy_task
|
||||
from gecko_taskgraph.util.platforms import architecture, archive_format
|
||||
from gecko_taskgraph.util.workertypes import worker_type_implementation
|
||||
|
||||
|
|
@ -93,7 +93,7 @@ packaging_description_schema = Schema(
|
|||
Optional("run-as-root"): bool,
|
||||
Optional("use-caches"): bool,
|
||||
},
|
||||
Optional("job-from"): job_description_schema["job-from"],
|
||||
Optional("task-from"): job_description_schema["task-from"],
|
||||
}
|
||||
)
|
||||
|
||||
|
|
@ -338,7 +338,7 @@ def handle_keyed_by(config, jobs):
|
|||
"worker.max-run-time",
|
||||
]
|
||||
for job in jobs:
|
||||
job = copy_task(job) # don't overwrite dict values here
|
||||
job = deepcopy(job) # don't overwrite dict values here
|
||||
for field in fields:
|
||||
resolve_keyed_by(
|
||||
item=job,
|
||||
|
|
@ -489,7 +489,7 @@ def make_job_description(config, jobs):
|
|||
# if repackage_signing_task doesn't exists, generate the stub installer
|
||||
package_formats += ["installer-stub"]
|
||||
for format in package_formats:
|
||||
command = copy_task(PACKAGE_FORMATS[format])
|
||||
command = deepcopy(PACKAGE_FORMATS[format])
|
||||
substs = {
|
||||
"archive_format": archive_format(build_platform),
|
||||
"_locale": _fetch_subst_locale,
|
||||
|
|
@ -506,7 +506,7 @@ def make_job_description(config, jobs):
|
|||
|
||||
# We need to resolve `msix.*` values keyed by `package-format` for each format, not
|
||||
# just once, so we update a temporary copy just for extracting these values.
|
||||
temp_job = copy_task(job)
|
||||
temp_job = deepcopy(job)
|
||||
for msix_key in (
|
||||
"channel",
|
||||
"identity-name",
|
||||
|
|
|
|||
|
|
@ -7,10 +7,9 @@ Transform the repackage task into an actual task description.
|
|||
|
||||
|
||||
from taskgraph.transforms.base import TransformSequence
|
||||
from taskgraph.util.copy import deepcopy
|
||||
from taskgraph.util.dependencies import get_primary_dependency
|
||||
|
||||
from gecko_taskgraph.util.copy_task import copy_task
|
||||
|
||||
transforms = TransformSequence()
|
||||
|
||||
|
||||
|
|
@ -21,7 +20,7 @@ def split_locales(config, jobs):
|
|||
assert dep_job
|
||||
|
||||
for locale in dep_job.attributes.get("chunk_locales", []):
|
||||
locale_job = copy_task(job) # don't overwrite dict values here
|
||||
locale_job = deepcopy(job) # don't overwrite dict values here
|
||||
treeherder = locale_job.setdefault("treeherder", {})
|
||||
treeherder_group = locale_job.pop("treeherder-group")
|
||||
treeherder["symbol"] = f"{treeherder_group}({locale})"
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ packaging_description_schema = Schema(
|
|||
},
|
||||
# Override the default priority for the project
|
||||
Optional("priority"): task_description_schema["priority"],
|
||||
Optional("job-from"): task_description_schema["job-from"],
|
||||
Optional("task-from"): task_description_schema["task-from"],
|
||||
Optional("attributes"): task_description_schema["attributes"],
|
||||
Optional("dependencies"): task_description_schema["dependencies"],
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ repackage_signing_description_schema = Schema(
|
|||
Optional("label"): str,
|
||||
Optional("attributes"): task_description_schema["attributes"],
|
||||
Optional("dependencies"): task_description_schema["dependencies"],
|
||||
Optional("job-from"): task_description_schema["job-from"],
|
||||
Optional("task-from"): task_description_schema["task-from"],
|
||||
Optional("treeherder"): task_description_schema["treeherder"],
|
||||
Optional("shipping-product"): task_description_schema["shipping-product"],
|
||||
Optional("shipping-phase"): task_description_schema["shipping-phase"],
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ repackage_signing_description_schema = Schema(
|
|||
Optional("shipping-product"): task_description_schema["shipping-product"],
|
||||
Optional("shipping-phase"): task_description_schema["shipping-phase"],
|
||||
Optional("priority"): task_description_schema["priority"],
|
||||
Optional("job-from"): task_description_schema["job-from"],
|
||||
Optional("task-from"): task_description_schema["task-from"],
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -6,17 +6,17 @@ Adjust dependencies to not exceed MAX_DEPENDENCIES
|
|||
"""
|
||||
|
||||
from taskgraph.transforms.base import TransformSequence
|
||||
from taskgraph.util.copy import deepcopy
|
||||
from taskgraph.util.treeherder import add_suffix
|
||||
|
||||
from gecko_taskgraph import MAX_DEPENDENCIES
|
||||
from gecko_taskgraph.transforms import release_deps
|
||||
from gecko_taskgraph.util.copy_task import copy_task
|
||||
|
||||
transforms = TransformSequence()
|
||||
|
||||
|
||||
def yield_job(orig_job, deps, count):
|
||||
job = copy_task(orig_job)
|
||||
job = deepcopy(orig_job)
|
||||
job["dependencies"] = deps
|
||||
job["name"] = "{}-{}".format(orig_job["name"], count)
|
||||
if "treeherder" in job:
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ signing_description_schema = Schema(
|
|||
Optional("repacks-per-chunk"): int,
|
||||
# Override the default priority for the project
|
||||
Optional("priority"): task_description_schema["priority"],
|
||||
Optional("job-from"): task_description_schema["job-from"],
|
||||
Optional("task-from"): task_description_schema["task-from"],
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ checksums_signing_description_schema = Schema(
|
|||
Optional("treeherder"): task_description_schema["treeherder"],
|
||||
Optional("shipping-product"): task_description_schema["shipping-product"],
|
||||
Optional("shipping-phase"): task_description_schema["shipping-phase"],
|
||||
Optional("job-from"): task_description_schema["job-from"],
|
||||
Optional("task-from"): task_description_schema["task-from"],
|
||||
Optional("attributes"): task_description_schema["attributes"],
|
||||
Optional("dependencies"): task_description_schema["dependencies"],
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,8 +63,8 @@ transforms.add_validate(source_test_description_schema)
|
|||
@transforms.add
|
||||
def set_job_name(config, jobs):
|
||||
for job in jobs:
|
||||
if "job-from" in job and job["job-from"] != "kind.yml":
|
||||
from_name = os.path.splitext(job["job-from"])[0]
|
||||
if "task-from" in job and job["task-from"] != "kind.yml":
|
||||
from_name = os.path.splitext(job["task-from"])[0]
|
||||
job["name"] = "{}-{}".format(from_name, job["name"])
|
||||
yield job
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import attr
|
|||
from mozbuild.util import memoize
|
||||
from taskcluster.utils import fromNow
|
||||
from taskgraph.transforms.base import TransformSequence
|
||||
from taskgraph.util.copy import deepcopy
|
||||
from taskgraph.util.keyed_by import evaluate_keyed_by
|
||||
from taskgraph.util.schema import (
|
||||
Schema,
|
||||
|
|
@ -35,7 +36,6 @@ from gecko_taskgraph.optimize.schema import OptimizationSchema
|
|||
from gecko_taskgraph.transforms.job.common import get_expiration
|
||||
from gecko_taskgraph.util import docker as dockerutil
|
||||
from gecko_taskgraph.util.attributes import TRUNK_PROJECTS, is_try, release_level
|
||||
from gecko_taskgraph.util.copy_task import copy_task
|
||||
from gecko_taskgraph.util.hash import hash_path
|
||||
from gecko_taskgraph.util.partners import get_partners_to_be_published
|
||||
from gecko_taskgraph.util.scriptworker import BALROG_ACTIONS, get_release_config
|
||||
|
|
@ -71,7 +71,7 @@ task_description_schema = Schema(
|
|||
# attributes for this task
|
||||
Optional("attributes"): {str: object},
|
||||
# relative path (from config.path) to the file task was defined in
|
||||
Optional("job-from"): str,
|
||||
Optional("task-from"): str,
|
||||
# dependencies of this task, keyed by name; these are passed through
|
||||
# verbatim and subject to the interpretation of the Task's get_dependencies
|
||||
# method.
|
||||
|
|
@ -772,7 +772,7 @@ def build_generic_worker_payload(config, task, task_def):
|
|||
# * 'cache-name' -> 'cacheName'
|
||||
# * 'task-id' -> 'taskId'
|
||||
# All other key names are already suitable, and don't need renaming.
|
||||
mounts = copy_task(worker.get("mounts", []))
|
||||
mounts = deepcopy(worker.get("mounts", []))
|
||||
for mount in mounts:
|
||||
if "cache-name" in mount:
|
||||
mount["cacheName"] = "{trust_domain}-level-{level}-{name}".format(
|
||||
|
|
@ -2006,7 +2006,7 @@ def build_task(config, tasks):
|
|||
if groupSymbol != "?":
|
||||
treeherder["groupSymbol"] = groupSymbol
|
||||
if groupSymbol not in group_names:
|
||||
path = os.path.join(config.path, task.get("job-from", ""))
|
||||
path = os.path.join(config.path, task.get("task-from", ""))
|
||||
raise Exception(UNKNOWN_GROUP_NAME.format(groupSymbol, path))
|
||||
treeherder["groupName"] = group_names[groupSymbol]
|
||||
treeherder["symbol"] = symbol
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ test_description_schema = Schema(
|
|||
# common attributes)
|
||||
Optional("attributes"): {str: object},
|
||||
# relative path (from config.path) to the file task was defined in
|
||||
Optional("job-from"): str,
|
||||
Optional("task-from"): str,
|
||||
# The `run_on_projects` attribute, defaulting to "all". This dictates the
|
||||
# projects on which this task should be included in the target task set.
|
||||
# See the attributes documentation for details.
|
||||
|
|
@ -485,7 +485,7 @@ def make_job_description(config, tasks):
|
|||
jobdesc["description"] = task["description"]
|
||||
jobdesc["attributes"] = attributes
|
||||
jobdesc["dependencies"] = {"build": build_label}
|
||||
jobdesc["job-from"] = task["job-from"]
|
||||
jobdesc["task-from"] = task["task-from"]
|
||||
|
||||
if task.get("fetches"):
|
||||
jobdesc["fetches"] = task["fetches"]
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import json
|
|||
import taskgraph
|
||||
from taskgraph.transforms.base import TransformSequence
|
||||
from taskgraph.util.attributes import keymatch
|
||||
from taskgraph.util.copy import deepcopy
|
||||
from taskgraph.util.treeherder import join_symbol, split_symbol
|
||||
|
||||
from gecko_taskgraph.util.attributes import is_try
|
||||
|
|
@ -18,7 +19,6 @@ from gecko_taskgraph.util.chunking import (
|
|||
get_runtimes,
|
||||
guess_mozinfo_from_task,
|
||||
)
|
||||
from gecko_taskgraph.util.copy_task import copy_task
|
||||
from gecko_taskgraph.util.perfile import perfile_number_of_chunks
|
||||
|
||||
DYNAMIC_CHUNK_DURATION = 20 * 60 # seconds
|
||||
|
|
@ -265,7 +265,7 @@ def split_chunks(config, tasks):
|
|||
this_chunk = i + 1
|
||||
|
||||
# copy the test and update with the chunk number
|
||||
chunked = copy_task(task)
|
||||
chunked = deepcopy(task)
|
||||
chunked["this-chunk"] = this_chunk
|
||||
|
||||
if chunked_manifests is not None:
|
||||
|
|
|
|||
|
|
@ -3,10 +3,9 @@
|
|||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
from taskgraph.transforms.base import TransformSequence
|
||||
from taskgraph.util.copy import deepcopy
|
||||
from taskgraph.util.treeherder import join_symbol, split_symbol
|
||||
|
||||
from gecko_taskgraph.util.copy_task import copy_task
|
||||
|
||||
transforms = TransformSequence()
|
||||
|
||||
|
||||
|
|
@ -31,7 +30,7 @@ def test_confirm_failure_tasks(config, tasks):
|
|||
env = config.params.get("try_task_config", {}) or {}
|
||||
env = env.get("templates", {}).get("env", {})
|
||||
|
||||
cftask = copy_task(task)
|
||||
cftask = deepcopy(task)
|
||||
|
||||
# when scheduled other settings will be made
|
||||
cftask["tier"] = 2
|
||||
|
|
|
|||
|
|
@ -8,22 +8,22 @@ import json
|
|||
import re
|
||||
|
||||
from mozbuild.schedules import INCLUSIVE_COMPONENTS
|
||||
from mozbuild.util import ReadOnlyDict
|
||||
from taskgraph.transforms.base import TransformSequence
|
||||
from taskgraph.util.attributes import keymatch
|
||||
from taskgraph.util.keyed_by import evaluate_keyed_by
|
||||
from taskgraph.util.readonlydict import ReadOnlyDict
|
||||
from taskgraph.util.schema import Schema, resolve_keyed_by
|
||||
from taskgraph.util.taskcluster import (
|
||||
get_artifact_path,
|
||||
get_artifact_url,
|
||||
get_index_url,
|
||||
)
|
||||
from taskgraph.util.templates import merge
|
||||
from voluptuous import Any, Optional, Required
|
||||
|
||||
from gecko_taskgraph.transforms.test.variant import TEST_VARIANTS
|
||||
from gecko_taskgraph.util.perftest import is_external_browser
|
||||
from gecko_taskgraph.util.platforms import platform_family
|
||||
from gecko_taskgraph.util.templates import merge
|
||||
|
||||
transforms = TransformSequence()
|
||||
|
||||
|
|
|
|||
|
|
@ -4,12 +4,12 @@
|
|||
|
||||
|
||||
from taskgraph.transforms.base import TransformSequence
|
||||
from taskgraph.util.copy import deepcopy
|
||||
from taskgraph.util.schema import Schema, optionally_keyed_by, resolve_keyed_by
|
||||
from taskgraph.util.treeherder import join_symbol, split_symbol
|
||||
from voluptuous import Extra, Optional, Required
|
||||
|
||||
from gecko_taskgraph.transforms.test import test_description_schema
|
||||
from gecko_taskgraph.util.copy_task import copy_task
|
||||
from gecko_taskgraph.util.perftest import is_external_browser
|
||||
|
||||
transforms = TransformSequence()
|
||||
|
|
@ -104,7 +104,7 @@ def split_apps(config, tests):
|
|||
] and test["attributes"].get("unittest_variant"):
|
||||
continue
|
||||
|
||||
atest = copy_task(test)
|
||||
atest = deepcopy(test)
|
||||
suffix = f"-{app}"
|
||||
atest["app"] = app
|
||||
atest["description"] += f" on {app.capitalize()}"
|
||||
|
|
@ -146,7 +146,7 @@ def split_raptor_subtests(config, tests):
|
|||
|
||||
for chunk_number, subtest in enumerate(subtests):
|
||||
# Create new test job
|
||||
chunked = copy_task(test)
|
||||
chunked = deepcopy(test)
|
||||
chunked["chunk-number"] = 1 + chunk_number
|
||||
chunked["subtest"] = subtest
|
||||
chunked["subtest-symbol"] = subtest
|
||||
|
|
|
|||
|
|
@ -5,13 +5,13 @@ import datetime
|
|||
|
||||
import jsone
|
||||
from taskgraph.transforms.base import TransformSequence
|
||||
from taskgraph.util.copy import deepcopy
|
||||
from taskgraph.util.schema import Schema, validate_schema
|
||||
from taskgraph.util.templates import merge
|
||||
from taskgraph.util.treeherder import join_symbol, split_symbol
|
||||
from voluptuous import Any, Optional, Required
|
||||
|
||||
from gecko_taskgraph.util.chunking import TEST_VARIANTS
|
||||
from gecko_taskgraph.util.copy_task import copy_task
|
||||
from gecko_taskgraph.util.templates import merge
|
||||
|
||||
transforms = TransformSequence()
|
||||
|
||||
|
|
@ -113,12 +113,12 @@ def split_variants(config, tasks):
|
|||
variants = remove_expired(variants, expired_variants)
|
||||
|
||||
if task.pop("run-without-variant"):
|
||||
yield copy_task(task)
|
||||
yield deepcopy(task)
|
||||
|
||||
for name in variants:
|
||||
# Apply composite variants (joined by '+') in order.
|
||||
parts = name.split("+")
|
||||
taskv = copy_task(task)
|
||||
taskv = deepcopy(task)
|
||||
for part in parts:
|
||||
variant = TEST_VARIANTS[part]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,40 +0,0 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
from mozbuild.util import ReadOnlyDict
|
||||
from taskgraph.task import Task
|
||||
|
||||
immutable_types = {int, float, bool, str, type(None), ReadOnlyDict}
|
||||
|
||||
|
||||
def copy_task(obj):
|
||||
"""
|
||||
Perform a deep copy of a task that has a tree-like structure.
|
||||
|
||||
Unlike copy.deepcopy, this does *not* support copying graph-like structure,
|
||||
but it does it more efficiently than deepcopy.
|
||||
"""
|
||||
ty = type(obj)
|
||||
if ty in immutable_types:
|
||||
return obj
|
||||
if ty is dict:
|
||||
return {k: copy_task(v) for k, v in obj.items()}
|
||||
if ty is list:
|
||||
return [copy_task(elt) for elt in obj]
|
||||
if ty is Task:
|
||||
task = Task(
|
||||
kind=copy_task(obj.kind),
|
||||
label=copy_task(obj.label),
|
||||
attributes=copy_task(obj.attributes),
|
||||
task=copy_task(obj.task),
|
||||
description=copy_task(obj.description),
|
||||
optimization=copy_task(obj.optimization),
|
||||
dependencies=copy_task(obj.dependencies),
|
||||
soft_dependencies=copy_task(obj.soft_dependencies),
|
||||
if_dependencies=copy_task(obj.if_dependencies),
|
||||
)
|
||||
if obj.task_id:
|
||||
task.task_id = obj.task_id
|
||||
return task
|
||||
raise NotImplementedError(f"copying '{ty}' from '{obj}'")
|
||||
|
|
@ -272,7 +272,7 @@ class ImagePathsMap(Mapping):
|
|||
|
||||
def __init__(self, config_path, image_dir=IMAGE_DIR):
|
||||
config = load_yaml(GECKO, config_path)
|
||||
self.__update_image_paths(config["jobs"], image_dir)
|
||||
self.__update_image_paths(config["tasks"], image_dir)
|
||||
|
||||
def __getitem__(self, key):
|
||||
return self.__dict__[key]
|
||||
|
|
|
|||
|
|
@ -12,10 +12,10 @@ from urllib.parse import urlencode
|
|||
import requests
|
||||
import yaml
|
||||
from redo import retry
|
||||
from taskgraph.util.copy import deepcopy
|
||||
from taskgraph.util.schema import resolve_keyed_by
|
||||
|
||||
from gecko_taskgraph.util.attributes import release_level
|
||||
from gecko_taskgraph.util.copy_task import copy_task
|
||||
|
||||
# Suppress chatty requests logging
|
||||
logging.getLogger("requests").setLevel(logging.WARNING)
|
||||
|
|
@ -391,7 +391,7 @@ def get_partner_config_by_kind(config, kind):
|
|||
elif kind.startswith("release-partner-attribution") and isinstance(
|
||||
kind_config, dict
|
||||
):
|
||||
all_configs = copy_task(kind_config.get("configs", []))
|
||||
all_configs = deepcopy(kind_config.get("configs", []))
|
||||
kind_config["configs"] = []
|
||||
for this_config in all_configs:
|
||||
if this_config["campaign"] in partner_subset:
|
||||
|
|
@ -400,7 +400,7 @@ def get_partner_config_by_kind(config, kind):
|
|||
|
||||
|
||||
def _fix_subpartner_locales(orig_config, all_locales):
|
||||
subpartner_config = copy_task(orig_config)
|
||||
subpartner_config = deepcopy(orig_config)
|
||||
# Get an ordered list of subpartner locales that is a subset of all_locales
|
||||
subpartner_config["locales"] = sorted(
|
||||
list(set(orig_config["locales"]) & set(all_locales))
|
||||
|
|
@ -465,7 +465,7 @@ def locales_per_build_platform(build_platform, locales):
|
|||
|
||||
|
||||
def get_partner_url_config(parameters, graph_config):
|
||||
partner_url_config = copy_task(graph_config["partner-urls"])
|
||||
partner_url_config = deepcopy(graph_config["partner-urls"])
|
||||
substitutions = {
|
||||
"release-product": parameters["release_product"],
|
||||
"release-level": release_level(parameters["project"]),
|
||||
|
|
|
|||
|
|
@ -23,12 +23,11 @@ from datetime import datetime
|
|||
|
||||
import jsone
|
||||
from mozbuild.util import memoize
|
||||
from taskgraph.util.copy import deepcopy
|
||||
from taskgraph.util.schema import resolve_keyed_by
|
||||
from taskgraph.util.taskcluster import get_artifact_prefix
|
||||
from taskgraph.util.yaml import load_yaml
|
||||
|
||||
from gecko_taskgraph.util.copy_task import copy_task
|
||||
|
||||
# constants {{{1
|
||||
"""Map signing scope aliases to sets of projects.
|
||||
|
||||
|
|
@ -453,7 +452,7 @@ def generate_beetmover_upstream_artifacts(
|
|||
"platform": platform,
|
||||
},
|
||||
)
|
||||
map_config = copy_task(cached_load_yaml(job["attributes"]["artifact_map"]))
|
||||
map_config = deepcopy(cached_load_yaml(job["attributes"]["artifact_map"]))
|
||||
upstream_artifacts = list()
|
||||
|
||||
if not locale:
|
||||
|
|
@ -497,7 +496,7 @@ def generate_beetmover_upstream_artifacts(
|
|||
if "partials_only" in map_config["mapping"][filename]:
|
||||
continue
|
||||
# The next time we look at this file it might be a different locale.
|
||||
file_config = copy_task(map_config["mapping"][filename])
|
||||
file_config = deepcopy(map_config["mapping"][filename])
|
||||
resolve_keyed_by(
|
||||
file_config,
|
||||
"source_path_modifier",
|
||||
|
|
@ -589,7 +588,7 @@ def generate_beetmover_artifact_map(config, job, **kwargs):
|
|||
"platform": platform,
|
||||
},
|
||||
)
|
||||
map_config = copy_task(cached_load_yaml(job["attributes"]["artifact_map"]))
|
||||
map_config = deepcopy(cached_load_yaml(job["attributes"]["artifact_map"]))
|
||||
base_artifact_prefix = map_config.get(
|
||||
"base_artifact_prefix", get_artifact_prefix(job)
|
||||
)
|
||||
|
|
@ -637,8 +636,8 @@ def generate_beetmover_artifact_map(config, job, **kwargs):
|
|||
if "partials_only" in map_config["mapping"][filename]:
|
||||
continue
|
||||
|
||||
# copy_task because the next time we look at this file the locale will differ.
|
||||
file_config = copy_task(map_config["mapping"][filename])
|
||||
# deepcopy because the next time we look at this file the locale will differ.
|
||||
file_config = deepcopy(map_config["mapping"][filename])
|
||||
|
||||
for field in [
|
||||
"destinations",
|
||||
|
|
@ -691,7 +690,7 @@ def generate_beetmover_artifact_map(config, job, **kwargs):
|
|||
continue
|
||||
|
||||
# Render all variables for the artifact map
|
||||
platforms = copy_task(map_config.get("platform_names", {}))
|
||||
platforms = deepcopy(map_config.get("platform_names", {}))
|
||||
if platform:
|
||||
for key in platforms.keys():
|
||||
resolve_keyed_by(platforms, key, job["label"], platform=platform)
|
||||
|
|
@ -750,7 +749,7 @@ def generate_beetmover_partials_artifact_map(config, job, partials_info, **kwarg
|
|||
"platform": platform,
|
||||
},
|
||||
)
|
||||
map_config = copy_task(cached_load_yaml(job["attributes"]["artifact_map"]))
|
||||
map_config = deepcopy(cached_load_yaml(job["attributes"]["artifact_map"]))
|
||||
base_artifact_prefix = map_config.get(
|
||||
"base_artifact_prefix", get_artifact_prefix(job)
|
||||
)
|
||||
|
|
@ -767,7 +766,7 @@ def generate_beetmover_partials_artifact_map(config, job, partials_info, **kwarg
|
|||
map_config, "s3_bucket_paths", "s3_bucket_paths", platform=platform
|
||||
)
|
||||
|
||||
platforms = copy_task(map_config.get("platform_names", {}))
|
||||
platforms = deepcopy(map_config.get("platform_names", {}))
|
||||
if platform:
|
||||
for key in platforms.keys():
|
||||
resolve_keyed_by(platforms, key, key, platform=platform)
|
||||
|
|
@ -785,8 +784,8 @@ def generate_beetmover_partials_artifact_map(config, job, partials_info, **kwarg
|
|||
continue
|
||||
if "partials_only" not in map_config["mapping"][filename]:
|
||||
continue
|
||||
# copy_task because the next time we look at this file the locale will differ.
|
||||
file_config = copy_task(map_config["mapping"][filename])
|
||||
# deepcopy because the next time we look at this file the locale will differ.
|
||||
file_config = deepcopy(map_config["mapping"][filename])
|
||||
|
||||
for field in [
|
||||
"destinations",
|
||||
|
|
|
|||
|
|
@ -1,59 +0,0 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
|
||||
from gecko_taskgraph.util.copy_task import copy_task
|
||||
|
||||
|
||||
def merge_to(source, dest):
|
||||
"""
|
||||
Merge dict and arrays (override scalar values)
|
||||
|
||||
Keys from source override keys from dest, and elements from lists in source
|
||||
are appended to lists in dest.
|
||||
|
||||
:param dict source: to copy from
|
||||
:param dict dest: to copy to (modified in place)
|
||||
"""
|
||||
|
||||
for key, value in source.items():
|
||||
if (
|
||||
isinstance(value, dict)
|
||||
and len(value) == 1
|
||||
and list(value)[0].startswith("by-")
|
||||
):
|
||||
# Do not merge by-* values as this is likely to confuse someone
|
||||
dest[key] = value
|
||||
continue
|
||||
|
||||
# Override mismatching or empty types
|
||||
if type(value) != type(dest.get(key)): # noqa
|
||||
dest[key] = value
|
||||
continue
|
||||
|
||||
# Merge dict
|
||||
if isinstance(value, dict):
|
||||
merge_to(value, dest[key])
|
||||
continue
|
||||
|
||||
if isinstance(value, list):
|
||||
dest[key] = dest[key] + value
|
||||
continue
|
||||
|
||||
dest[key] = value
|
||||
|
||||
return dest
|
||||
|
||||
|
||||
def merge(*objects):
|
||||
"""
|
||||
Merge the given objects, using the semantics described for merge_to, with
|
||||
objects later in the list taking precedence. From an inheritance
|
||||
perspective, "parents" should be listed before "children".
|
||||
|
||||
Returns the result without modifying any arguments.
|
||||
"""
|
||||
if len(objects) == 1:
|
||||
return copy_task(objects[0])
|
||||
return merge_to(objects[-1], merge(*objects[:-1]))
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
---
|
||||
loader: gecko_taskgraph.loader.transform:loader
|
||||
loader: taskgraph.loader.transform:loader
|
||||
|
||||
kind-dependencies:
|
||||
# non-system python
|
||||
|
|
@ -12,10 +12,10 @@ transforms:
|
|||
- gecko_taskgraph.transforms.job:transforms
|
||||
- gecko_taskgraph.transforms.task:transforms
|
||||
|
||||
job-defaults:
|
||||
task-defaults:
|
||||
use-python: default
|
||||
|
||||
jobs:
|
||||
tasks:
|
||||
tps-xpi:
|
||||
description: Build the TPS add-on
|
||||
index:
|
||||
|
|
|
|||
|
|
@ -2,12 +2,12 @@
|
|||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
---
|
||||
loader: gecko_taskgraph.loader.transform:loader
|
||||
loader: taskgraph.loader.transform:loader
|
||||
|
||||
transforms:
|
||||
- gecko_taskgraph.transforms.task:transforms
|
||||
|
||||
job-defaults:
|
||||
task-defaults:
|
||||
run-on-projects: []
|
||||
treeherder:
|
||||
kind: build
|
||||
|
|
@ -21,7 +21,7 @@ job-defaults:
|
|||
dontbuild: false
|
||||
push: true
|
||||
|
||||
jobs:
|
||||
tasks:
|
||||
import:
|
||||
name: android_l10n_import
|
||||
description: Import strings from android-l10n repo
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
---
|
||||
loader: gecko_taskgraph.loader.transform:loader
|
||||
loader: taskgraph.loader.transform:loader
|
||||
|
||||
transforms:
|
||||
- gecko_taskgraph.transforms.job:transforms
|
||||
|
|
@ -11,7 +11,7 @@ transforms:
|
|||
kind-dependencies:
|
||||
- signing-apk
|
||||
|
||||
job-defaults:
|
||||
task-defaults:
|
||||
description: Runs UI tests for sanity checking startup on Nightly
|
||||
treeherder:
|
||||
kind: test
|
||||
|
|
@ -33,7 +33,7 @@ job-defaults:
|
|||
use-caches: false
|
||||
run-on-projects: []
|
||||
|
||||
jobs:
|
||||
tasks:
|
||||
fenix-arm64-v8a-nightly-robo-opt:
|
||||
attributes:
|
||||
build-type: fenix-nightly
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
---
|
||||
loader: gecko_taskgraph.loader.transform:loader
|
||||
loader: taskgraph.loader.transform:loader
|
||||
|
||||
kind-dependencies:
|
||||
- fetch
|
||||
|
|
@ -16,7 +16,7 @@ transforms:
|
|||
- gecko_taskgraph.transforms.artifact:transforms
|
||||
- gecko_taskgraph.transforms.task:transforms
|
||||
|
||||
job-defaults:
|
||||
task-defaults:
|
||||
index:
|
||||
product: firefox
|
||||
treeherder:
|
||||
|
|
@ -42,7 +42,7 @@ job-defaults:
|
|||
keep-artifacts: false
|
||||
use-python: default
|
||||
|
||||
jobs:
|
||||
tasks:
|
||||
linux64-artifact/opt:
|
||||
description: "Linux64 Opt Artifact Build"
|
||||
index:
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
---
|
||||
loader: gecko_taskgraph.loader.transform:loader
|
||||
loader: taskgraph.loader.transform:loader
|
||||
|
||||
transforms:
|
||||
- gecko_taskgraph.transforms.attribution:resolve_keyed_by_transforms
|
||||
|
|
@ -19,7 +19,7 @@ kind-dependencies:
|
|||
# Mac
|
||||
- repackage-l10n
|
||||
|
||||
job-defaults:
|
||||
task-defaults:
|
||||
description: Attribute release builds
|
||||
shipping-phase: promote
|
||||
# never run as part of CI
|
||||
|
|
@ -101,7 +101,7 @@ job-defaults:
|
|||
- __MOZCUSTOM__dlsource%3D{attribution_code[json][dlsource]}
|
||||
use-python: default
|
||||
|
||||
jobs:
|
||||
tasks:
|
||||
win32-devedition/opt:
|
||||
label: attribution-win32-{locale}-devedition/opt
|
||||
shipping-product: devedition
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
---
|
||||
loader: gecko_taskgraph.loader.transform:loader
|
||||
loader: taskgraph.loader.transform:loader
|
||||
|
||||
transforms:
|
||||
- gecko_taskgraph.transforms.attribution:resolve_keyed_by_transforms
|
||||
|
|
@ -18,7 +18,7 @@ kind-dependencies:
|
|||
# Mac
|
||||
- repackage
|
||||
|
||||
job-defaults:
|
||||
task-defaults:
|
||||
description: Attribute release builds
|
||||
shipping-phase: promote
|
||||
# never run as part of CI
|
||||
|
|
@ -86,7 +86,7 @@ job-defaults:
|
|||
- __MOZCUSTOM__dlsource%3D{attribution_code[json][dlsource]}
|
||||
use-python: default
|
||||
|
||||
jobs:
|
||||
tasks:
|
||||
win32-devedition/opt:
|
||||
label: attribution-win32-devedition/opt
|
||||
shipping-product: devedition
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
---
|
||||
loader: gecko_taskgraph.loader.transform:loader
|
||||
loader: taskgraph.loader.transform:loader
|
||||
|
||||
transforms:
|
||||
- taskgraph.transforms.from_deps
|
||||
|
|
@ -26,7 +26,7 @@ not-for-build-platforms:
|
|||
- android-x86-shippable/opt
|
||||
- android-aarch64-shippable/opt
|
||||
|
||||
jobs:
|
||||
tasks:
|
||||
balrog:
|
||||
from-deps:
|
||||
group-by: single-with-filters
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
# license, v. 2.0. if a copy of the mpl was not distributed with this
|
||||
# file, you can obtain one at http://mozilla.org/mpl/2.0/.
|
||||
---
|
||||
loader: gecko_taskgraph.loader.transform:loader
|
||||
loader: taskgraph.loader.transform:loader
|
||||
|
||||
transforms:
|
||||
- taskgraph.transforms.from_deps
|
||||
|
|
@ -15,7 +15,7 @@ kind-dependencies:
|
|||
- signing-apk
|
||||
- signing-bundle
|
||||
|
||||
jobs:
|
||||
tasks:
|
||||
beetmover:
|
||||
from-deps:
|
||||
with-attributes:
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
---
|
||||
loader: gecko_taskgraph.loader.transform:loader
|
||||
loader: taskgraph.loader.transform:loader
|
||||
|
||||
transforms:
|
||||
- taskgraph.transforms.from_deps
|
||||
|
|
@ -20,7 +20,7 @@ only-for-build-platforms:
|
|||
- linux-devedition/opt
|
||||
- linux64-devedition/opt
|
||||
|
||||
jobs:
|
||||
tasks:
|
||||
beetmover-apt:
|
||||
from-deps:
|
||||
group-by: single-with-filters
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
---
|
||||
loader: gecko_taskgraph.loader.transform:loader
|
||||
loader: taskgraph.loader.transform:loader
|
||||
|
||||
transforms:
|
||||
- taskgraph.transforms.from_deps
|
||||
|
|
@ -17,7 +17,7 @@ only-for-attributes:
|
|||
- nightly
|
||||
- shippable
|
||||
|
||||
jobs:
|
||||
tasks:
|
||||
beetmover-checksums:
|
||||
from-deps:
|
||||
group-by: single-with-filters
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
---
|
||||
loader: gecko_taskgraph.loader.transform:loader
|
||||
loader: taskgraph.loader.transform:loader
|
||||
|
||||
transforms:
|
||||
- taskgraph.transforms.from_deps
|
||||
|
|
@ -16,7 +16,7 @@ kind-dependencies:
|
|||
- build-components
|
||||
- post-signing-dummy
|
||||
|
||||
jobs:
|
||||
tasks:
|
||||
push-to-maven:
|
||||
description: Publish component
|
||||
from-deps:
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
---
|
||||
loader: gecko_taskgraph.loader.transform:loader
|
||||
loader: taskgraph.loader.transform:loader
|
||||
|
||||
transforms:
|
||||
- taskgraph.transforms.from_deps
|
||||
|
|
@ -37,7 +37,7 @@ not-for-build-platforms:
|
|||
- linux64-asan-reporter-shippable/opt
|
||||
- win64-asan-reporter-shippable/opt
|
||||
|
||||
jobs:
|
||||
tasks:
|
||||
beetmover-geckoview:
|
||||
from-deps:
|
||||
group-by: single-with-filters
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
---
|
||||
loader: gecko_taskgraph.loader.transform:loader
|
||||
loader: taskgraph.loader.transform:loader
|
||||
|
||||
transforms:
|
||||
- taskgraph.transforms.from_deps
|
||||
|
|
@ -54,7 +54,7 @@ only-for-build-platforms:
|
|||
- linux64-asan-reporter-shippable/opt
|
||||
- win64-asan-reporter-shippable/opt
|
||||
|
||||
jobs:
|
||||
tasks:
|
||||
beetmover-repackage:
|
||||
from-deps:
|
||||
group-by: single-locale
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
---
|
||||
loader: gecko_taskgraph.loader.transform:loader
|
||||
loader: taskgraph.loader.transform:loader
|
||||
|
||||
transforms:
|
||||
- taskgraph.transforms.from_deps
|
||||
|
|
@ -14,7 +14,7 @@ transforms:
|
|||
kind-dependencies:
|
||||
- release-source-signing
|
||||
|
||||
jobs:
|
||||
tasks:
|
||||
beetmover-source:
|
||||
from-deps:
|
||||
group-by: single-with-filters
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue