Class: Portage::Cli::Find

Inherits:
Object
  • Object
show all
Defined in:
lib/portage/cli/find.rb

Overview

portage find --query "..." — the "I don't have a URL" half of the CLI.

Ask a search backend which stores might sell the thing, keep only the ones that answer /.well-known/ucp, ask each of those what it actually stocks, and return the merged offers. Buy then takes over from a store the caller picked.

The split matters: Find never buys. Handing the merchant choice to a search ranker and the purchase decision to --yes in one breath is how you end up owning a counterfeit from a shop you've never heard of, so picking a store stays an explicit act (see Cli.run_buy's --store gate).

Constant Summary collapse

CART_CAP =
"dev.ucp.shopping.cart".freeze
CHECKOUT_CAP =
"dev.ucp.shopping.checkout".freeze
MAX_PROBES =
12
PER_STORE_RESULTS =
5
THROTTLE =
0.1

Instance Method Summary collapse

Constructor Details

#initialize(query:, limit: MAX_PROBES, max_price: nil, backends: nil, cache: nil, throttle: THROTTLE) ⇒ Find

Returns a new instance of Find.

Parameters:

  • max_price (Integer, nil) (defaults to: nil)

    minor units, matching the protocol's own money representation — the CLI converts from major units.



30
31
32
33
34
35
36
37
# File 'lib/portage/cli/find.rb', line 30

def initialize(query:, limit: MAX_PROBES, max_price: nil, backends: nil, cache: nil, throttle: THROTTLE)
  @query = query.to_s
  @limit = [limit, MAX_PROBES].min
  @max_price = max_price
  @backends = backends || SearchBackends.default
  @cache = cache || ProbeCache.new
  @throttle = throttle
end

Instance Method Details

#callObject



39
40
41
42
43
44
45
46
47
48
49
# File 'lib/portage/cli/find.rb', line 39

def call
  return report(message: "Nothing to search for — pass --query.") if @query.strip.empty?

  candidates = candidate_origins
  return report(candidates: candidates, message: no_candidates_message) if candidates.empty?

  stores = probe(candidates)
  offers = rank(stores.flat_map { |store| offers_for(store) })
  report(candidates: candidates, stores: stores.map { |s| s.slice(:origin, :source, :checkout) },
         offers: offers, message: summary(candidates, stores, offers))
end