mirror of
https://github.com/Homebrew/brew.git
synced 2026-10-28 09:34:42 +08:00
Sample only user-set env config in analytics
- The formulae.brew.sh env-config table was hard to interpret: unset and explicitly-set-to-default runs were merged as "default events", nothing showed what a variable's default was and variables brew exports itself (`HOMEBREW_UPDATE_TO_TAG` in `cmd/update.sh`, `HOMEBREW_EDITOR`/`HOMEBREW_DISPLAY` etc. copied from the user environment in `bin/brew`) dominated the chart as fake user configuration. - Record `HOMEBREW_USER_SET_VARS` at `bin/brew` startup, after `brew.env` files load but before any exports, so sampling and `brew config` can tell deliberate configuration apart; sub-brews inherit the list. - Replace the `env_config_non_default` tag with a single `env_config_state` tag (`unset`/`default`/`non_default`) computed from user-set values only. - Compute previously `default_text`-only defaults so explicitly-set default values are ignored everywhere: `HOMEBREW_AUTO_UPDATE_SECS` (mirroring `brew.sh`), `HOMEBREW_FORBID_PACKAGES_FROM_PATHS` (now `boolean: :set`, matching its accessor), `HOMEBREW_PIP_INDEX_URL` and `HOMEBREW_SSH_CONFIG_PATH`; generated accessors and `non_default_variable?` call callable defaults and treat blank booleans as unset like their accessors. - `brew config` now only prints user-set non-default variables and `Resource#determine_url_mirrors` only rewrites PyPI URLs for non-default `$HOMEBREW_PIP_INDEX_URL` values. - Sanitise `formula-analytics` results: only current variables and valid states are accepted and the query requires the new tag, which drops the contaminated data already collected. - Stop excluding CI events from `command_run_options`: CI users are normal users so CI-only usage should stay visible. - Output `non_default_count`, `set_default_count`, `unset_count` and `default_value` per variable in JSON, using the human `default_text` summary for varying defaults via `EnvConfig.default_description`, now shared with the manpage.
This commit is contained in:
12 files changed
+212
-42
No files matched your search
@@ -345,6 +345,8 @@ auto-update() {
|
||||
[[ -n "${HOMEBREW_AUTO_UPDATE_SKIP_OUTDATED}" ]] && export HOMEBREW_AUTO_UPDATE_SKIP_OUTDATED
|
||||
fi
|
||||
|
||||
# Keep in sync with the HOMEBREW_AUTO_UPDATE_SECS default in
|
||||
# Library/Homebrew/env_config.rb.
|
||||
if [[ -z "${HOMEBREW_AUTO_UPDATE_SECS}" ]]
|
||||
then
|
||||
if [[ -n "${HOMEBREW_NO_INSTALL_FROM_API}" || -n "${HOMEBREW_AUTO_UPDATE_TAP}" ]]
|
||||
|
||||
@@ -172,8 +172,10 @@ module Homebrew
|
||||
groups = [:devcmdrun, :developer]
|
||||
when :homebrew_env_config
|
||||
dimension_key = "env_config"
|
||||
groups = [:env_config, :env_config_non_default]
|
||||
additional_where += " AND env_config IS NOT NULL"
|
||||
groups = [:env_config, :env_config_state]
|
||||
# Events predating the user-set-aware `env_config_state` tag
|
||||
# counted brew's own exports as configuration, so drop them.
|
||||
additional_where += " AND env_config_state IS NOT NULL"
|
||||
when :homebrew_os_arch_ci
|
||||
dimension_key = "os_arch_ci"
|
||||
groups = [:os, :arch, :ci]
|
||||
@@ -193,7 +195,6 @@ module Homebrew
|
||||
when :command_run_options
|
||||
dimension_key = "command_run_options"
|
||||
groups = [:command, :options, :devcmdrun, :developer]
|
||||
additional_where += " AND ci = 'false'"
|
||||
when :test_bot_test
|
||||
dimension_key = "test_bot_test"
|
||||
groups = [:command, :passed, :arch, :os]
|
||||
@@ -231,15 +232,22 @@ module Homebrew
|
||||
batches.each do |batch|
|
||||
batch.to_pylist.each do |record|
|
||||
if category == :homebrew_env_config
|
||||
state = record["env_config_state"]
|
||||
env_config_name = record["env_config"].to_s
|
||||
# Drop malformed events from non-standard clients and events
|
||||
# for variables Homebrew no longer supports.
|
||||
next if %w[unset default non_default].exclude?(state)
|
||||
next unless Homebrew::EnvConfig::ENVS.key?(env_config_name.to_sym)
|
||||
|
||||
count = record["count"]
|
||||
non_default = record["env_config_non_default"] == "true"
|
||||
json[:total_count] += count
|
||||
json[:items] << {
|
||||
number: nil,
|
||||
dimension_key => record["env_config"],
|
||||
dimension_key => env_config_name,
|
||||
count:,
|
||||
non_default_count: non_default ? count : 0,
|
||||
default_count: non_default ? 0 : count,
|
||||
non_default_count: (state == "non_default") ? count : 0,
|
||||
set_default_count: (state == "default") ? count : 0,
|
||||
unset_count: (state == "unset") ? count : 0,
|
||||
}
|
||||
next
|
||||
end
|
||||
@@ -326,7 +334,8 @@ module Homebrew
|
||||
deduped_items[key][:count] += item[:count]
|
||||
if category == :homebrew_env_config
|
||||
deduped_items[key][:non_default_count] += item[:non_default_count]
|
||||
deduped_items[key][:default_count] += item[:default_count]
|
||||
deduped_items[key][:set_default_count] += item[:set_default_count]
|
||||
deduped_items[key][:unset_count] += item[:unset_count]
|
||||
end
|
||||
else
|
||||
deduped_items[key] = item
|
||||
@@ -376,10 +385,12 @@ module Homebrew
|
||||
end
|
||||
item[:percent] = format_percent(percent)
|
||||
item[:count] = format_count(item[:count])
|
||||
if category == :homebrew_env_config
|
||||
item[:non_default_count] = format_count(item[:non_default_count])
|
||||
item[:default_count] = format_count(item[:default_count])
|
||||
end
|
||||
next if category != :homebrew_env_config
|
||||
|
||||
item[:non_default_count] = format_count(item[:non_default_count])
|
||||
item[:set_default_count] = format_count(item[:set_default_count])
|
||||
item[:unset_count] = format_count(item[:unset_count])
|
||||
item[:default_value] = Homebrew::EnvConfig.default_description(item[dimension_key].to_sym)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -102,6 +102,16 @@ module Homebrew
|
||||
"disable auto-update entirely with `$HOMEBREW_NO_AUTO_UPDATE`.",
|
||||
default_text: "`86400` (24 hours), `3600` (1 hour) if a developer command has been run " \
|
||||
"or `300` (5 minutes) if `$HOMEBREW_NO_INSTALL_FROM_API` is set.",
|
||||
# Keep in sync with the auto-update defaults in Library/Homebrew/brew.sh.
|
||||
default: lambda {
|
||||
if ENV["HOMEBREW_NO_INSTALL_FROM_API"].present? || ENV["HOMEBREW_AUTO_UPDATE_TAP"].present?
|
||||
300
|
||||
elsif ENV["HOMEBREW_DEV_CMD_RUN"].present?
|
||||
3600
|
||||
else
|
||||
86400
|
||||
end
|
||||
},
|
||||
},
|
||||
HOMEBREW_AVOID_NESTED_SANDBOXING: {
|
||||
description: "If set, skip Homebrew's sandbox when it is itself running inside another " \
|
||||
@@ -374,8 +384,10 @@ module Homebrew
|
||||
HOMEBREW_FORBID_PACKAGES_FROM_PATHS: {
|
||||
description: "If set, Homebrew will refuse to read formulae or casks provided from file paths, " \
|
||||
"e.g. `brew install ./package.rb`.",
|
||||
boolean: true,
|
||||
boolean: :set,
|
||||
default_text: "true unless `$HOMEBREW_DEVELOPER` is set.",
|
||||
# Keep in sync with forbid_packages_from_paths? below.
|
||||
default: -> { ENV["HOMEBREW_TESTS"].blank? && ENV["HOMEBREW_DEVELOPER"].blank? },
|
||||
},
|
||||
HOMEBREW_FORCE_API_AUTO_UPDATE: {
|
||||
description: "If set, update the Homebrew API formula or cask data even if " \
|
||||
@@ -627,6 +639,7 @@ module Homebrew
|
||||
HOMEBREW_PIP_INDEX_URL: {
|
||||
description: "If set, `brew install` <formula> will use this URL to download PyPI package resources.",
|
||||
default_text: "`https://pypi.org/simple`.",
|
||||
default: "https://pypi.org/simple",
|
||||
},
|
||||
HOMEBREW_PRY: {
|
||||
description: "If set, use Pry for the `brew irb` command.",
|
||||
@@ -680,6 +693,7 @@ module Homebrew
|
||||
description: "If set, Homebrew will use the given config file instead of `~/.ssh/config` when " \
|
||||
"fetching Git repositories over SSH.",
|
||||
default_text: "`~/.ssh/config`",
|
||||
default: -> { "#{Dir.home}/.ssh/config" },
|
||||
},
|
||||
HOMEBREW_SUDO_THROUGH_SUDO_USER: {
|
||||
description: "If set, Homebrew will use the `$SUDO_USER` environment variable to define the user to " \
|
||||
@@ -786,6 +800,20 @@ module Homebrew
|
||||
!!(hash[:hidden] || hash[:odeprecated] || hash[:odisabled])
|
||||
end
|
||||
|
||||
# The default value as human text, e.g. for the manpage or analytics:
|
||||
# `default_text` summarises defaults that vary by platform or machine.
|
||||
sig { params(env: Symbol).returns(T.nilable(String)) }
|
||||
def default_description(env)
|
||||
hash = ENVS[env]
|
||||
return if hash.nil?
|
||||
|
||||
default_text = hash[:default_text]
|
||||
return default_text if default_text
|
||||
|
||||
default = hash[:default]
|
||||
"`#{default}`." if default
|
||||
end
|
||||
|
||||
# Defaults and parsing that cannot be expressed by the generated helpers.
|
||||
CUSTOM_IMPLEMENTATIONS = T.let(Set.new([
|
||||
:HOMEBREW_BUNDLE_JOBS,
|
||||
@@ -808,26 +836,36 @@ module Homebrew
|
||||
sig { params(env: Symbol).returns(T::Boolean) }
|
||||
def non_default_variable?(env)
|
||||
value = ENV.fetch(env.to_s, nil)
|
||||
return false unless value
|
||||
# Blank values behave like unset in the generated accessors.
|
||||
return false if value.blank?
|
||||
|
||||
config = ENVS.fetch(env)
|
||||
default = config.fetch(:default, config[:boolean] ? false : nil)
|
||||
default = default.call if default.respond_to?(:call)
|
||||
if config[:boolean]
|
||||
enabled = value.present? && (config[:boolean] == :set || FALSY_VALUES.exclude?(value.downcase))
|
||||
enabled != config.fetch(:default, false)
|
||||
enabled = config[:boolean] == :set || FALSY_VALUES.exclude?(value.downcase)
|
||||
enabled != default
|
||||
else
|
||||
return false if value.blank?
|
||||
|
||||
default = config[:default]
|
||||
default = default.call if default.respond_to?(:call)
|
||||
value != default.to_s
|
||||
end
|
||||
end
|
||||
|
||||
# Whether the user set this variable rather than Homebrew exporting
|
||||
# it itself, e.g. `HOMEBREW_EDITOR` from `EDITOR`. The matching Bash
|
||||
# records `HOMEBREW_USER_SET_VARS` in `bin/brew` before any exports.
|
||||
sig { params(env: Symbol).returns(T::Boolean) }
|
||||
def user_set_variable?(env)
|
||||
return false if ENV.fetch(env.to_s, nil).blank?
|
||||
return true unless env.to_s.start_with?("HOMEBREW_")
|
||||
|
||||
ENV.fetch("HOMEBREW_USER_SET_VARS", "").split.include?(env.to_s)
|
||||
end
|
||||
|
||||
sig { returns(T::Array[String]) }
|
||||
def non_default_variables
|
||||
ENV.filter_map do |env, _value|
|
||||
env_symbol = env.to_sym
|
||||
env if ENVS.key?(env_symbol) && non_default_variable?(env_symbol)
|
||||
env if ENVS.key?(env_symbol) && user_set_variable?(env_symbol) && non_default_variable?(env_symbol)
|
||||
end.sort
|
||||
end
|
||||
|
||||
@@ -852,7 +890,12 @@ module Homebrew
|
||||
end
|
||||
elsif hash[:default].present?
|
||||
define_method(method_name) do
|
||||
env_value(env, hash).presence || hash.fetch(:default).to_s
|
||||
value = env_value(env, hash).presence
|
||||
next value if value
|
||||
|
||||
default = hash.fetch(:default)
|
||||
default = default.call if default.respond_to?(:call)
|
||||
default.to_s
|
||||
end
|
||||
else
|
||||
define_method(method_name) do
|
||||
@@ -977,6 +1020,7 @@ module Homebrew
|
||||
|
||||
# Provide an opt-out for tests and developers.
|
||||
# Our testing framework installs formulae from file paths all over the place.
|
||||
# Keep in sync with the HOMEBREW_FORBID_PACKAGES_FROM_PATHS default above.
|
||||
ENV["HOMEBREW_TESTS"].blank? && ENV["HOMEBREW_DEVELOPER"].blank?
|
||||
end
|
||||
|
||||
|
||||
@@ -196,8 +196,7 @@ module Homebrew
|
||||
next if Homebrew::EnvConfig.hidden?(hash)
|
||||
|
||||
entry = "`#{env}`\n\n: #{hash[:description]}\n"
|
||||
default = hash[:default_text]
|
||||
default ||= "`#{hash[:default]}`." if hash[:default]
|
||||
default = Homebrew::EnvConfig.default_description(env)
|
||||
entry += "\n\n *Default:* #{default}\n" if default
|
||||
|
||||
entry
|
||||
|
||||
@@ -322,7 +322,8 @@ class Resource
|
||||
end
|
||||
|
||||
# PyPI packages: PEP 503 – Simple Repository API <https://peps.python.org/pep-0503>
|
||||
if (pip_index_url = Homebrew::EnvConfig.pip_index_url.presence)
|
||||
if Homebrew::EnvConfig.non_default_variable?(:HOMEBREW_PIP_INDEX_URL) &&
|
||||
(pip_index_url = Homebrew::EnvConfig.pip_index_url.presence)
|
||||
pip_index_base_url = pip_index_url.chomp("/").chomp("/simple")
|
||||
%w[https://files.pythonhosted.org https://pypi.org].each do |base_url|
|
||||
extra_urls << url.sub(base_url, pip_index_base_url) if url.start_with?("#{base_url}/packages")
|
||||
|
||||
@@ -23,6 +23,7 @@ RSpec.describe Homebrew::Cmd::Config do
|
||||
|
||||
it "prints HOMEBREW_CASK_OPTS_REQUIRE_SHA in env config output when set" do
|
||||
Homebrew.raise_deprecation_exceptions = false
|
||||
ENV["HOMEBREW_USER_SET_VARS"] = "HOMEBREW_CASK_OPTS_REQUIRE_SHA"
|
||||
ENV["HOMEBREW_CASK_OPTS_REQUIRE_SHA"] = "1"
|
||||
output = StringIO.new
|
||||
|
||||
@@ -35,10 +36,13 @@ RSpec.describe Homebrew::Cmd::Config do
|
||||
|
||||
it "prints only environment variables with non-default values" do
|
||||
Homebrew::EnvConfig::ENVS.each_key { |env| ENV.delete(env.to_s) }
|
||||
ENV["HOMEBREW_USER_SET_VARS"] = "HOMEBREW_API_AUTO_UPDATE_SECS HOMEBREW_BUNDLE_DESCRIBE " \
|
||||
"HOMEBREW_CURL_RETRIES HOMEBREW_REQUIRE_TAP_TRUST"
|
||||
ENV["HOMEBREW_API_AUTO_UPDATE_SECS"] = "450"
|
||||
ENV["HOMEBREW_BUNDLE_DESCRIBE"] = "false"
|
||||
ENV["HOMEBREW_CURL_RETRIES"] = "4"
|
||||
ENV["HOMEBREW_REQUIRE_TAP_TRUST"] = "1"
|
||||
ENV["HOMEBREW_EDITOR"] = "vim"
|
||||
output = StringIO.new
|
||||
|
||||
SystemConfig.homebrew_env_config(output)
|
||||
|
||||
@@ -22,10 +22,14 @@ RSpec.describe Homebrew::DevCmd::FormulaAnalytics do
|
||||
ENV.delete("HOMEBREW_NO_ANALYTICS")
|
||||
ENV["HOMEBREW_INFLUXDB_TOKEN"] = "token"
|
||||
batch = double(to_pylist: [
|
||||
{ "env_config" => "HOMEBREW_BAT", "env_config_non_default" => "true", "count" => 2 },
|
||||
{ "env_config" => "HOMEBREW_BAT", "env_config_non_default" => "false", "count" => 8 },
|
||||
{ "env_config" => "HOMEBREW_NO_AUTO_UPDATE", "env_config_non_default" => "true", "count" => 1 },
|
||||
{ "env_config" => "HOMEBREW_NO_AUTO_UPDATE", "env_config_non_default" => "false", "count" => 1 },
|
||||
{ "env_config" => "HOMEBREW_BAT", "env_config_state" => "non_default", "count" => 2 },
|
||||
{ "env_config" => "HOMEBREW_BAT", "env_config_state" => "default", "count" => 3 },
|
||||
{ "env_config" => "HOMEBREW_BAT", "env_config_state" => "unset", "count" => 5 },
|
||||
{ "env_config" => "HOMEBREW_NO_AUTO_UPDATE", "env_config_state" => "non_default", "count" => 1 },
|
||||
{ "env_config" => "HOMEBREW_NO_AUTO_UPDATE", "env_config_state" => "unset", "count" => 1 },
|
||||
{ "env_config" => "HOMEBREW_MAKE_JOBS", "env_config_state" => "default", "count" => 4 },
|
||||
{ "env_config" => "HOMEBREW_TOTALLY_MADE_UP", "env_config_state" => "non_default", "count" => 100 },
|
||||
{ "env_config" => "HOMEBREW_BAT", "env_config_state" => "borked", "count" => 50 },
|
||||
])
|
||||
query_result = double(to_batches: [batch])
|
||||
queries = []
|
||||
@@ -40,18 +44,23 @@ RSpec.describe Homebrew::DevCmd::FormulaAnalytics do
|
||||
command = described_class.new(["--homebrew-env-config", "--json"])
|
||||
expected = {
|
||||
category: :homebrew_env_config,
|
||||
total_items: 2,
|
||||
total_items: 3,
|
||||
start_date: Date.today - 30,
|
||||
end_date: Date.today,
|
||||
total_count: 12,
|
||||
total_count: 16,
|
||||
items: [
|
||||
{
|
||||
number: 1, env_config: "HOMEBREW_NO_AUTO_UPDATE", count: "2", non_default_count: "1",
|
||||
default_count: "1", percent: "50"
|
||||
set_default_count: "0", unset_count: "1", percent: "50", default_value: nil
|
||||
},
|
||||
{
|
||||
number: 2, env_config: "HOMEBREW_BAT", count: "10", non_default_count: "2",
|
||||
default_count: "8", percent: "20"
|
||||
set_default_count: "3", unset_count: "5", percent: "20", default_value: nil
|
||||
},
|
||||
{
|
||||
number: 3, env_config: "HOMEBREW_MAKE_JOBS", count: "4", non_default_count: "0",
|
||||
set_default_count: "4", unset_count: "0", percent: "0",
|
||||
default_value: "The number of available CPU cores."
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -59,8 +68,8 @@ RSpec.describe Homebrew::DevCmd::FormulaAnalytics do
|
||||
expect { command.influx_analytics(command.args) }
|
||||
.to output("#{JSON.pretty_generate(expected)}\n").to_stdout
|
||||
expect(queries).to contain_exactly(
|
||||
query: match(
|
||||
/FROM "command_run".*env_config IS NOT NULL.*GROUP BY "env_config","env_config_non_default"/,
|
||||
query: match(/FROM "command_run".*env_config_state IS NOT NULL GROUP BY/).and(
|
||||
include('GROUP BY "env_config","env_config_state"'),
|
||||
),
|
||||
language: "sql",
|
||||
)
|
||||
|
||||
@@ -87,6 +87,63 @@ RSpec.describe Homebrew::EnvConfig do
|
||||
|
||||
expect(env_config.non_default_variable?(:HOMEBREW_MAKE_JOBS)).to be(false)
|
||||
end
|
||||
|
||||
it "treats blank boolean values as default like their accessors" do
|
||||
ENV["HOMEBREW_SBOM"] = ""
|
||||
|
||||
expect(env_config.non_default_variable?(:HOMEBREW_SBOM)).to be(false)
|
||||
end
|
||||
|
||||
it "treats values matching computed defaults as default" do
|
||||
ENV["HOMEBREW_PIP_INDEX_URL"] = "https://pypi.org/simple"
|
||||
ENV["HOMEBREW_SSH_CONFIG_PATH"] = "#{Dir.home}/.ssh/config"
|
||||
ENV["HOMEBREW_AUTO_UPDATE_SECS"] = "300"
|
||||
ENV["HOMEBREW_NO_INSTALL_FROM_API"] = "1"
|
||||
ENV.delete("HOMEBREW_AUTO_UPDATE_TAP")
|
||||
ENV.delete("HOMEBREW_DEV_CMD_RUN")
|
||||
|
||||
expect([
|
||||
env_config.non_default_variable?(:HOMEBREW_PIP_INDEX_URL),
|
||||
env_config.non_default_variable?(:HOMEBREW_SSH_CONFIG_PATH),
|
||||
env_config.non_default_variable?(:HOMEBREW_AUTO_UPDATE_SECS),
|
||||
]).to eq([false, false, false])
|
||||
end
|
||||
|
||||
it "compares boolean defaults computed at runtime" do
|
||||
ENV["HOMEBREW_FORBID_PACKAGES_FROM_PATHS"] = "1"
|
||||
ENV.delete("HOMEBREW_TESTS")
|
||||
ENV.delete("HOMEBREW_DEVELOPER")
|
||||
|
||||
expect(env_config.non_default_variable?(:HOMEBREW_FORBID_PACKAGES_FROM_PATHS)).to be(false)
|
||||
end
|
||||
end
|
||||
|
||||
describe ".user_set_variable?" do
|
||||
it "only counts HOMEBREW_* variables recorded by bin/brew as user-set" do
|
||||
ENV["HOMEBREW_USER_SET_VARS"] = "HOMEBREW_CURL_RETRIES HOMEBREW_BAT"
|
||||
ENV["HOMEBREW_CURL_RETRIES"] = "4"
|
||||
ENV["HOMEBREW_EDITOR"] = "vim"
|
||||
ENV["SUDO_ASKPASS"] = "/usr/bin/ssh-askpass"
|
||||
ENV.delete("HOMEBREW_BAT")
|
||||
|
||||
expect([
|
||||
env_config.user_set_variable?(:HOMEBREW_CURL_RETRIES),
|
||||
env_config.user_set_variable?(:HOMEBREW_EDITOR),
|
||||
env_config.user_set_variable?(:SUDO_ASKPASS),
|
||||
env_config.user_set_variable?(:HOMEBREW_BAT),
|
||||
]).to eq([true, false, true, false])
|
||||
end
|
||||
end
|
||||
|
||||
describe ".default_description" do
|
||||
it "prefers human default text over literal defaults" do
|
||||
expect([
|
||||
env_config.default_description(:HOMEBREW_MAKE_JOBS),
|
||||
env_config.default_description(:HOMEBREW_API_AUTO_UPDATE_SECS),
|
||||
env_config.default_description(:HOMEBREW_BAT),
|
||||
env_config.default_description(:HOMEBREW_REMOVED_VARIABLE),
|
||||
]).to eq(["The number of available CPU cores.", "`450`.", nil, nil])
|
||||
end
|
||||
end
|
||||
|
||||
describe "ANALYTICS_VARIABLES" do
|
||||
@@ -98,13 +155,16 @@ RSpec.describe Homebrew::EnvConfig do
|
||||
end
|
||||
|
||||
describe ".non_default_variables" do
|
||||
it "returns names of variables with non-default values" do
|
||||
it "returns names of user-set variables with non-default values" do
|
||||
Homebrew::EnvConfig::ENVS.each_key { |env| ENV.delete(env.to_s) }
|
||||
ENV["HOMEBREW_USER_SET_VARS"] = "HOMEBREW_CURL_RETRIES HOMEBREW_GITHUB_API_TOKEN " \
|
||||
"HOMEBREW_NO_AUTO_UPDATE HOMEBREW_BAT HOMEBREW_REQUIRE_TAP_TRUST"
|
||||
ENV["HOMEBREW_CURL_RETRIES"] = "4"
|
||||
ENV["HOMEBREW_GITHUB_API_TOKEN"] = "secret"
|
||||
ENV["HOMEBREW_NO_AUTO_UPDATE"] = "1"
|
||||
ENV["HOMEBREW_BAT"] = "false"
|
||||
ENV["HOMEBREW_REQUIRE_TAP_TRUST"] = "1"
|
||||
ENV["HOMEBREW_EDITOR"] = "vim"
|
||||
|
||||
expect(env_config.non_default_variables).to eq(
|
||||
%w[HOMEBREW_CURL_RETRIES HOMEBREW_GITHUB_API_TOKEN HOMEBREW_NO_AUTO_UPDATE],
|
||||
|
||||
@@ -256,19 +256,39 @@ RSpec.describe Utils::Analytics do
|
||||
ENV.delete("HOMEBREW_NO_ANALYTICS")
|
||||
ENV["HOMEBREW_ANALYTICS_DEBUG"] = "true"
|
||||
allow(command_instance.class).to receive(:command_name).and_return("update")
|
||||
expect(Homebrew::EnvConfig).to receive(:non_default_variable?).with(kind_of(Symbol)).and_return(true)
|
||||
stub_const("Homebrew::EnvConfig::ANALYTICS_VARIABLES", [:HOMEBREW_ALLOWED_TAPS])
|
||||
ENV["HOMEBREW_ALLOWED_TAPS"] = "homebrew/core"
|
||||
ENV["HOMEBREW_USER_SET_VARS"] = "HOMEBREW_ALLOWED_TAPS"
|
||||
expect(Homebrew::EnvConfig).to receive(:non_default_variable?).with(:HOMEBREW_ALLOWED_TAPS).and_return(true)
|
||||
|
||||
expect(described_class).to receive(:report_influx).with(
|
||||
:command_run,
|
||||
hash_including(
|
||||
command: "update",
|
||||
env_config: kind_of(String),
|
||||
env_config_non_default: true,
|
||||
command: "update",
|
||||
env_config: "HOMEBREW_ALLOWED_TAPS",
|
||||
env_config_state: "non_default",
|
||||
),
|
||||
hash_including(options:),
|
||||
).once
|
||||
described_class.report_command_run(command_instance)
|
||||
end
|
||||
|
||||
it "samples variables exported by brew itself as unset" do
|
||||
ENV.delete("HOMEBREW_NO_ANALYTICS_THIS_RUN")
|
||||
ENV.delete("HOMEBREW_NO_ANALYTICS")
|
||||
ENV["HOMEBREW_ANALYTICS_DEBUG"] = "true"
|
||||
allow(command_instance.class).to receive(:command_name).and_return("update")
|
||||
stub_const("Homebrew::EnvConfig::ANALYTICS_VARIABLES", [:HOMEBREW_ALLOWED_TAPS])
|
||||
ENV["HOMEBREW_ALLOWED_TAPS"] = "homebrew/core"
|
||||
ENV["HOMEBREW_USER_SET_VARS"] = ""
|
||||
|
||||
expect(described_class).to receive(:report_influx).with(
|
||||
:command_run,
|
||||
hash_including(env_config: "HOMEBREW_ALLOWED_TAPS", env_config_state: "unset"),
|
||||
hash_including(options:),
|
||||
).once
|
||||
described_class.report_command_run(command_instance)
|
||||
end
|
||||
end
|
||||
|
||||
describe "::report_test_bot_test" do
|
||||
|
||||
@@ -133,7 +133,11 @@ module Utils
|
||||
variables = Homebrew::EnvConfig::ANALYTICS_VARIABLES
|
||||
env_config = variables.fetch(Random.rand(variables.length))
|
||||
tags[:env_config] = env_config.to_s
|
||||
tags[:env_config_non_default] = Homebrew::EnvConfig.non_default_variable?(env_config)
|
||||
tags[:env_config_state] = if Homebrew::EnvConfig.user_set_variable?(env_config)
|
||||
Homebrew::EnvConfig.non_default_variable?(env_config) ? "non_default" : "default"
|
||||
else
|
||||
"unset"
|
||||
end
|
||||
end
|
||||
|
||||
# Fields can have high cardinality.
|
||||
|
||||
@@ -187,6 +187,22 @@ then
|
||||
HOMEBREW_BREW_FILE="${HOMEBREW_FORCE_BREW_WRAPPER}"
|
||||
fi
|
||||
|
||||
# Record which HOMEBREW_* variables the user set (including via brew.env
|
||||
# above) before brew exports more itself, e.g. HOMEBREW_EDITOR from
|
||||
# EDITOR/VISUAL below or HOMEBREW_UPDATE_TO_TAG in cmd/update.sh, so
|
||||
# analytics only samples user configuration. Sub-brews inherit the list.
|
||||
# The matching Ruby is Homebrew::EnvConfig.user_set_variable? in
|
||||
# Library/Homebrew/env_config.rb.
|
||||
if [[ -z "${HOMEBREW_USER_SET_VARS+set}" ]]
|
||||
then
|
||||
for VAR in "${!HOMEBREW_@}"
|
||||
do
|
||||
HOMEBREW_USER_SET_VARS="${HOMEBREW_USER_SET_VARS:-} ${VAR}"
|
||||
done
|
||||
export HOMEBREW_USER_SET_VARS="${HOMEBREW_USER_SET_VARS:-}"
|
||||
unset VAR
|
||||
fi
|
||||
|
||||
# Copy and export all HOMEBREW_* variables previously mentioned in
|
||||
# manpage or used elsewhere by Homebrew.
|
||||
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ Formula, cask and build-error events can include:
|
||||
- whether Homebrew uses its default prefix, with every other prefix reported only as `custom-prefix`
|
||||
|
||||
Command events include the command and option names after option values have been removed.
|
||||
For selected common commands, Homebrew randomly samples one supported configuration variable and records its name and whether it differs from the default.
|
||||
For selected common commands, Homebrew randomly samples one supported configuration variable and records its name and whether the user left it unset, set it to its default or set it to a non-default value; variables Homebrew exports itself (e.g. `HOMEBREW_EDITOR` from `EDITOR`) count as unset.
|
||||
It does not record the variable's value.
|
||||
|
||||
BrewTestBot can send CI-only test-step results when its analytics setting is enabled.
|
||||
|
||||
Reference in new issue
Block a user