mirror of
https://github.com/Homebrew/brew.git
synced 2025-07-14 16:09:03 +08:00

Import these from the homebrew/formula-analytics tap and deprecate that tap. This required a little messing around with filenames and paths to get it finding Python and writing to the user's home directory.
139 lines
4.7 KiB
Ruby
Executable File
139 lines
4.7 KiB
Ruby
Executable File
# typed: strict
|
|
# frozen_string_literal: true
|
|
|
|
require "abstract_command"
|
|
|
|
module Homebrew
|
|
module DevCmd
|
|
class GenerateAnalyticsApi < AbstractCommand
|
|
CATEGORIES = %w[
|
|
build-error install install-on-request
|
|
core-build-error core-install core-install-on-request
|
|
cask-install core-cask-install os-version
|
|
homebrew-devcmdrun-developer homebrew-os-arch-ci
|
|
homebrew-prefixes homebrew-versions
|
|
brew-command-run brew-command-run-options brew-test-bot-test
|
|
].freeze
|
|
|
|
# TODO: add brew-command-run-options brew-test-bot-test to above when working.
|
|
DAYS = %w[30 90 365].freeze
|
|
MAX_RETRIES = 3
|
|
|
|
cmd_args do
|
|
description <<~EOS
|
|
Generates analytics API data files for formulae.brew.sh.
|
|
|
|
The generated files are written to the current directory.
|
|
EOS
|
|
|
|
named_args :none
|
|
end
|
|
|
|
sig { params(category_name: String, data_source: T.nilable(String)).returns(String) }
|
|
def analytics_json_template(category_name, data_source: nil)
|
|
data_source = "#{data_source}: true" if data_source
|
|
|
|
<<~EOS
|
|
---
|
|
layout: analytics_json
|
|
category: #{category_name}
|
|
#{data_source}
|
|
---
|
|
{{ content }}
|
|
EOS
|
|
end
|
|
|
|
sig { params(args: String).returns(String) }
|
|
def run_formula_analytics(*args)
|
|
puts "brew formula-analytics #{args.join(" ")}"
|
|
|
|
retries = 0
|
|
result = Utils.popen_read(HOMEBREW_BREW_FILE, "formula-analytics", *args, err: :err)
|
|
|
|
while !$CHILD_STATUS.success? && retries < MAX_RETRIES
|
|
# Give InfluxDB some more breathing room.
|
|
sleep 4**(retries+2)
|
|
|
|
retries += 1
|
|
puts "Retrying #{args.join(" ")} (#{retries}/#{MAX_RETRIES})..."
|
|
result = Utils.popen_read(HOMEBREW_BREW_FILE, "formula-analytics", *args, err: :err)
|
|
end
|
|
|
|
odie "`brew formula-analytics #{args.join(" ")}` failed: #{result}" unless $CHILD_STATUS.success?
|
|
|
|
result
|
|
end
|
|
|
|
sig { override.void }
|
|
def run
|
|
safe_system HOMEBREW_BREW_FILE, "formula-analytics", "--setup"
|
|
|
|
directories = ["_data/analytics", "api/analytics"]
|
|
FileUtils.rm_rf directories
|
|
FileUtils.mkdir_p directories
|
|
|
|
root_dir = Pathname.pwd
|
|
analytics_data_dir = root_dir/"_data/analytics"
|
|
analytics_api_dir = root_dir/"api/analytics"
|
|
|
|
threads = []
|
|
|
|
CATEGORIES.each do |category|
|
|
formula_analytics_args = []
|
|
|
|
case category
|
|
when "core-build-error"
|
|
formula_analytics_args << "--all-core-formulae-json"
|
|
formula_analytics_args << "--build-error"
|
|
category_name = "build-error"
|
|
data_source = "homebrew-core"
|
|
when "core-install"
|
|
formula_analytics_args << "--all-core-formulae-json"
|
|
formula_analytics_args << "--install"
|
|
category_name = "install"
|
|
data_source = "homebrew-core"
|
|
when "core-install-on-request"
|
|
formula_analytics_args << "--all-core-formulae-json"
|
|
formula_analytics_args << "--install-on-request"
|
|
category_name = "install-on-request"
|
|
data_source = "homebrew-core"
|
|
when "core-cask-install"
|
|
formula_analytics_args << "--all-core-formulae-json"
|
|
formula_analytics_args << "--cask-install"
|
|
category_name = "cask-install"
|
|
data_source = "homebrew-cask"
|
|
else
|
|
formula_analytics_args << "--#{category}"
|
|
category_name = category
|
|
end
|
|
|
|
path_suffix = File.join(category_name, data_source || "")
|
|
analytics_data_path = analytics_data_dir/path_suffix
|
|
analytics_api_path = analytics_api_dir/path_suffix
|
|
|
|
FileUtils.mkdir_p analytics_data_path
|
|
FileUtils.mkdir_p analytics_api_path
|
|
|
|
# The `--json` and `--all-core-formulae-json` flags are mutually
|
|
# exclusive, but we need to explicitly set `--json` sometimes,
|
|
# so only set it if we've not already set
|
|
# `--all-core-formulae-json`.
|
|
formula_analytics_args << "--json" unless formula_analytics_args.include? "--all-core-formulae-json"
|
|
|
|
DAYS.each do |days|
|
|
next if days != "30" && category_name == "build-error" && !data_source.nil?
|
|
|
|
threads << Thread.new do
|
|
args = %W[--days-ago=#{days}]
|
|
(analytics_data_path/"#{days}d.json").write run_formula_analytics(*formula_analytics_args, *args)
|
|
(analytics_api_path/"#{days}d.json").write analytics_json_template(category_name, data_source:)
|
|
end
|
|
end
|
|
end
|
|
|
|
threads.each(&:join)
|
|
end
|
|
end
|
|
end
|
|
end
|