-
# frozen_string_literal: true
-
-
1
require "zeitwerk"
-
-
1
Zeitwerk::Loader.new.then do |loader|
-
1
loader.inflector.inflect "cli" => "CLI",
-
"http_status" => "HTTPStatus",
-
"http_statuses" => "HTTPStatuses",
-
"htmx" => "HTMX"
-
1
loader.tag = File.basename __FILE__, ".rb"
-
1
loader.push_dir __dir__
-
1
loader.setup
-
end
-
-
# Main namespace.
-
1
module Pennyworth
-
1
def self.loader registry = Zeitwerk::Registry
-
4
@loader ||= registry.loaders.each.find { |loader| loader.tag == File.basename(__FILE__, ".rb") }
-
end
-
end
-
# frozen_string_literal: true
-
-
1
Gem::Specification.new do |spec|
-
1
spec.name = "pennyworth"
-
1
spec.version = "18.8.0"
-
1
spec.authors = ["Brooke Kuhlmann"]
-
1
spec.email = ["brooke@alchemists.io"]
-
1
spec.homepage = "https://alchemists.io/projects/pennyworth"
-
1
spec.summary = "A command line interface for augmented Alfred workflows."
-
1
spec.license = "Hippocratic-2.1"
-
-
1
spec.metadata = {
-
"bug_tracker_uri" => "https://github.com/bkuhlmann/pennyworth/issues",
-
"changelog_uri" => "https://alchemists.io/projects/pennyworth/versions",
-
"homepage_uri" => "https://alchemists.io/projects/pennyworth",
-
"funding_uri" => "https://github.com/sponsors/bkuhlmann",
-
"label" => "Pennyworth",
-
"rubygems_mfa_required" => "true",
-
"source_code_uri" => "https://github.com/bkuhlmann/pennyworth"
-
}
-
-
1
spec.signing_key = Gem.default_key_path
-
1
spec.cert_chain = [Gem.default_cert_path]
-
-
1
spec.required_ruby_version = ">= 3.4"
-
1
spec.add_dependency "cogger", "~> 1.0"
-
1
spec.add_dependency "containable", "~> 1.1"
-
1
spec.add_dependency "core", "~> 2.5"
-
1
spec.add_dependency "etcher", "~> 3.0"
-
1
spec.add_dependency "ghub", "~> 0.22"
-
1
spec.add_dependency "http", "~> 5.2"
-
1
spec.add_dependency "infusible", "~> 4.0"
-
1
spec.add_dependency "ox", "~> 2.14"
-
1
spec.add_dependency "rack", "~> 3.1"
-
1
spec.add_dependency "refinements", "~> 13.6"
-
1
spec.add_dependency "runcom", "~> 12.0"
-
1
spec.add_dependency "sod", "~> 1.5"
-
1
spec.add_dependency "spek", "~> 4.0"
-
1
spec.add_dependency "zeitwerk", "~> 2.7"
-
-
1
spec.bindir = "exe"
-
1
spec.executables << "pennyworth"
-
1
spec.extra_rdoc_files = Dir["README*", "LICENSE*"]
-
1
spec.files = Dir["*.gemspec", "lib/**/*"]
-
end
-
# frozen_string_literal: true
-
-
1
require "sod"
-
-
1
module Pennyworth
-
1
module CLI
-
1
module Actions
-
# Handles the encoding action.
-
1
class Encoding < Sod::Action
-
1
include Dependencies[:io, processor: "processors.encoding"]
-
-
1
description "Render Alfred encodings script filter."
-
-
1
on "--encodings"
-
-
1
def call(*) = io.puts processor.call.to_json
-
end
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
require "sod"
-
-
1
module Pennyworth
-
1
module CLI
-
1
module Actions
-
# Handles the RubyGem action.
-
1
class Gem < Sod::Action
-
1
include Dependencies[:io, processor: "processors.gem"]
-
-
1
description "Render Alfred RubyGems script filter."
-
-
1
on "--gems", argument: "[HANDLE]"
-
-
24
default { Container[:settings].ruby_gems_owner }
-
-
1
def call(handle = default) = io.puts processor.call("owners/#{handle}/gems.json").to_json
-
end
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
require "sod"
-
-
1
module Pennyworth
-
1
module CLI
-
1
module Actions
-
1
module GitHub
-
# Handles the GitHub user action.
-
1
class Organization < Sod::Action
-
1
include Dependencies[:io, processor: "processors.project"]
-
-
1
description "Specify organization."
-
-
1
on %w[-o --organization], argument: "[HANDLE]"
-
-
24
default { Container[:settings].git_hub_organization }
-
-
1
def call(handle = default) = io.puts processor.call("orgs/#{handle}").to_json
-
end
-
end
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
require "sod"
-
-
1
module Pennyworth
-
1
module CLI
-
1
module Actions
-
1
module GitHub
-
# Handles the GitHub user action.
-
1
class User < Sod::Action
-
1
include Dependencies[:io, processor: "processors.project"]
-
-
1
description "Specify user."
-
-
1
on %w[-u --user], argument: "[HANDLE]"
-
-
24
default { Container[:settings].git_hub_user }
-
-
1
def call(handle = default) = io.puts processor.call("users/#{handle}").to_json
-
end
-
end
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
require "sod"
-
-
1
module Pennyworth
-
1
module CLI
-
1
module Actions
-
1
module HTMX
-
# Handles examples documentation action.
-
1
class Example < Sod::Action
-
1
include Dependencies[:settings, :io, processor: "processors.htmx"]
-
-
1
description "Render Alfred examples script filter."
-
-
1
on "--examples"
-
-
1
def call(*) = io.puts processor.call(settings.htmx_examples_uri).to_json
-
end
-
end
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
require "sod"
-
-
1
module Pennyworth
-
1
module CLI
-
1
module Actions
-
1
module HTMX
-
# Handles extension documentation action.
-
1
class Extension < Sod::Action
-
1
include Dependencies[:settings, :io, processor: "processors.htmx"]
-
-
1
description "Render Alfred extensions script filter."
-
-
1
on "--extensions"
-
-
1
def call(*) = io.puts processor.call(settings.htmx_extensions_uri).to_json
-
end
-
end
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
require "sod"
-
-
1
module Pennyworth
-
1
module CLI
-
1
module Actions
-
1
module HTMX
-
# Handles references documentation action.
-
1
class Reference < Sod::Action
-
1
include Dependencies[:settings, :io, processor: "processors.htmx"]
-
-
1
description "Render Alfred references script filter."
-
-
1
on "--references"
-
-
1
def call(*) = io.puts processor.call(settings.htmx_references_uri).to_json
-
end
-
end
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
require "sod"
-
-
1
module Pennyworth
-
1
module CLI
-
1
module Actions
-
# Handles the HTTP status action.
-
1
class HTTPStatus < Sod::Action
-
1
include Dependencies[:io, processor: "processors.http_status"]
-
-
1
description "Render Alfred HTTP statuses script filter."
-
-
1
on "--http_statuses"
-
-
1
def call(*) = io.puts processor.call.to_json
-
end
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
require "sod"
-
-
1
module Pennyworth
-
1
module CLI
-
1
module Actions
-
# Handles Rodauth feature action.
-
1
class Rodauth < Sod::Action
-
1
include Dependencies[:settings, :io, processor: "processors.rodauth"]
-
-
1
description "Render Alfred Rodauth script filter."
-
-
1
on "--rodauth"
-
-
1
def call(*) = io.puts processor.call(settings.rodauth_documentation_uri).to_json
-
end
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
require "sod"
-
-
1
module Pennyworth
-
1
module CLI
-
1
module Actions
-
# Handles the system error action.
-
1
class StandardError < Sod::Action
-
1
include Dependencies[:io, processor: "processors.standard_error"]
-
-
1
description "Render Alfred standard errors script filter."
-
-
1
on "--standard_errors"
-
-
1
def call(*) = io.puts processor.call.to_json
-
end
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
require "sod"
-
-
1
module Pennyworth
-
1
module CLI
-
1
module Actions
-
# Handles the Standard Gem action.
-
1
class StandardGem < Sod::Action
-
1
include Dependencies[:io, processor: "processors.standard_gem"]
-
-
1
ENDPOINTS = {
-
"all" => "stdgems.json",
-
"default" => "default_gems.json",
-
"bundled" => "bundled_gems.json"
-
}.freeze
-
-
1
description "Render Alfred Standard Gems script filter."
-
-
1
on "--standard_gems", argument: "[KIND]", allow: %w[all default bundled], default: "all"
-
-
1
def initialize(endpoints: ENDPOINTS, **)
-
26
super(**)
-
26
@endpoints = endpoints
-
end
-
-
1
def call(kind = default) = io.puts processor.call(endpoints.fetch(kind)).to_json
-
-
1
private
-
-
1
attr_reader :endpoints
-
end
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
require "sod"
-
-
1
module Pennyworth
-
1
module CLI
-
1
module Actions
-
1
module System
-
# Handles the system error action.
-
1
class Error < Sod::Action
-
1
include Dependencies[:io, processor: "processors.system_error"]
-
-
1
description "Render Alfred system errors script filter."
-
-
1
on "--system_errors"
-
-
1
def call(*) = io.puts processor.call.to_json
-
end
-
end
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
require "sod"
-
-
1
module Pennyworth
-
1
module CLI
-
1
module Actions
-
1
module System
-
# Handles the system signal action.
-
1
class Signal < Sod::Action
-
1
include Dependencies[:io, processor: "processors.system_signal"]
-
-
1
description "Render Alfred system signals script filter."
-
-
1
on "--system_signals"
-
-
1
def call(*) = io.puts processor.call.to_json
-
end
-
end
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
require "sod"
-
-
1
module Pennyworth
-
1
module CLI
-
1
module Actions
-
# Handles the text action.
-
1
class Text < Sod::Action
-
1
include Dependencies[:io, processor: "processors.text"]
-
-
1
description "Render Alfred text script filter."
-
-
1
on "--text", argument: "CONTENT"
-
-
1
def call(content) = io.puts processor.call(content).to_json
-
end
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
require "sod"
-
-
1
module Pennyworth
-
1
module CLI
-
# The main Command Line Interface (CLI) object.
-
1
class Shell
-
1
include Dependencies[:defaults_path, :xdg_config, :specification]
-
-
1
def initialize(context: Sod::Context, dsl: Sod, **)
-
20
super(**)
-
20
@context = context
-
20
@dsl = dsl
-
end
-
-
1
def call(...) = cli.call(...)
-
-
1
private
-
-
1
attr_reader :context, :dsl
-
-
1
def cli
-
20
context = build_context
-
-
20
dsl.new :pennyworth, banner: specification.banner do
-
20
on(Sod::Prefabs::Commands::Config, context:)
-
-
20
on "git_hub", "Render Alfred GitHub repositories script filter." do
-
20
on Actions::GitHub::Organization
-
20
on Actions::GitHub::User
-
end
-
-
20
on "htmx", "Render htmx script filters" do
-
20
on Actions::HTMX::Example
-
20
on Actions::HTMX::Extension
-
20
on Actions::HTMX::Reference
-
end
-
-
20
on Actions::Encoding
-
20
on Actions::HTTPStatus
-
20
on Actions::Gem
-
20
on Actions::Rodauth
-
20
on Actions::StandardGem
-
20
on Actions::StandardError
-
20
on Actions::System::Error
-
20
on Actions::System::Signal
-
20
on Actions::Text
-
20
on(Sod::Prefabs::Actions::Version, context:)
-
20
on Sod::Prefabs::Actions::Help, self
-
end
-
end
-
-
1
def build_context
-
20
context[defaults_path:, xdg_config:, version_label: specification.labeled_version]
-
end
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
require "dry/schema"
-
-
1
Dry::Schema.load_extensions :monads
-
-
1
module Pennyworth
-
1
module Configuration
-
1
Contract = Dry::Schema.Params do
-
1
optional(:alfred_preferences).filled :string
-
1
required(:inflections).array :hash
-
1
required(:git_hub_api_uri).filled :string
-
1
optional(:git_hub_organization).filled :string
-
1
optional(:git_hub_user).filled :string
-
1
required(:http_statuses_uri).filled :string
-
1
required(:htmx_examples_uri).filled :string
-
1
required(:htmx_extensions_uri).filled :string
-
1
required(:htmx_references_uri).filled :string
-
1
required(:htmx_site_uri).filled :string
-
1
required(:rodauth_site_uri).filled :string
-
1
required(:rodauth_documentation_uri).filled :string
-
1
required(:ruby_gems_api_uri).filled :string
-
1
optional(:ruby_gems_owner).filled :string
-
1
required(:standard_gems_api_uri).filled :string
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
module Pennyworth
-
1
module Configuration
-
# Defines configuration content as the primary source of truth for use throughout the gem.
-
1
Model = Struct.new :alfred_preferences,
-
:inflections,
-
:git_hub_api_uri,
-
:git_hub_organization,
-
:git_hub_user,
-
:http_statuses_uri,
-
:htmx_examples_uri,
-
:htmx_extensions_uri,
-
:htmx_references_uri,
-
:htmx_site_uri,
-
:rodauth_site_uri,
-
:rodauth_documentation_uri,
-
:ruby_gems_api_uri,
-
:ruby_gems_owner,
-
:standard_gems_api_uri
-
end
-
end
-
# frozen_string_literal: true
-
-
1
require "cogger"
-
1
require "containable"
-
1
require "etcher"
-
1
require "http"
-
1
require "ox"
-
1
require "runcom"
-
1
require "spek"
-
-
1
module Pennyworth
-
# Provides a global gem container for injection into other objects.
-
1
module Container
-
1
extend Containable
-
-
1
register :registry, as: :fresh do
-
58
Etcher::Registry.new(contract: Configuration::Contract, model: Configuration::Model)
-
.add_loader(:yaml, self[:defaults_path])
-
.add_loader(:yaml, self[:xdg_config].active)
-
.add_transformer(:format, :htmx_examples_uri)
-
.add_transformer(:format, :htmx_extensions_uri)
-
.add_transformer(:format, :htmx_references_uri)
-
.add_transformer(:format, :rodauth_documentation_uri)
-
end
-
-
1
namespace :processors do
-
1
register :encoding do
-
21
Processor.new loader: Loaders::Encoding.new,
-
presenter: Presenters::Encoding,
-
serializer: Serializers::Encoding
-
end
-
-
1
register :gem do
-
20
Processor.new loader: Loaders::Gem.new,
-
presenter: Presenters::Gem,
-
serializer: Serializers::Project
-
end
-
-
1
register :htmx do
-
26
Processor.new loader: Loaders::HTMX.new,
-
presenter: Presenters::HTMX,
-
serializer: Serializers::HTMX
-
end
-
-
1
register :http_status do
-
21
Processor.new loader: Loaders::HTTPStatus.new,
-
presenter: Presenters::HTTPStatus,
-
serializer: Serializers::HTTPStatus
-
end
-
-
1
register :project do
-
20
Processor.new loader: Loaders::GitHub.new,
-
presenter: Presenters::Repository,
-
serializer: Serializers::Project
-
end
-
-
1
register :rodauth do
-
22
Processor.new loader: Loaders::Rodauth.new,
-
presenter: Presenters::Rodauth,
-
serializer: Serializers::Rodauth
-
end
-
-
1
register :standard_gem do
-
20
Processor.new loader: Loaders::StandardGem.new,
-
presenter: Presenters::StandardGem,
-
serializer: Serializers::Project
-
end
-
-
1
register :standard_error do
-
21
Processor.new loader: Loaders::StandardError.new,
-
presenter: Presenters::StandardError,
-
serializer: Serializers::StandardError
-
end
-
-
1
register :system_error do
-
21
Processor.new loader: Loaders::System::Error.new,
-
presenter: Presenters::System::Error,
-
serializer: Serializers::System::Error
-
end
-
-
1
register :system_signal do
-
21
Processor.new loader: Loaders::System::Signal.new,
-
presenter: Presenters::System::Signal,
-
serializer: Serializers::System::Signal
-
end
-
-
1
register :text do
-
1
Processor.new loader: Loaders::Text.new,
-
presenter: Presenters::Text,
-
serializer: Serializers::Text
-
end
-
end
-
-
1
register :ox do
-
68
Ox.tap { |ox| ox.default_options = {mode: :generic, effort: :tolerant, smart: true} }
-
end
-
-
2
register(:settings) { Etcher.call(self[:registry]).dup }
-
21
register(:specification) { Spek::Loader.call "#{__dir__}/../../pennyworth.gemspec" }
-
2
register(:defaults_path) { Pathname(__dir__).join("configuration/defaults.yml") }
-
2
register(:xdg_config) { Runcom::Config.new "pennyworth/configuration.yml" }
-
34
register(:http) { HTTP.timeout 3 }
-
1
register(:logger) { Cogger.new id: :pennyworth }
-
1
register :io, STDOUT
-
end
-
end
-
# frozen_string_literal: true
-
-
1
require "infusible"
-
-
1
module Pennyworth
-
1
Dependencies = Infusible[Container]
-
end
-
# frozen_string_literal: true
-
-
1
module Pennyworth
-
# Overrides any string to desired form if matched, otherwise answers the original string.
-
1
class Inflector
-
1
DEFAULTS = Array(Container[:settings].inflections).reduce({}, :merge)
-
-
1
def initialize overrides = DEFAULTS
-
329
@overrides = overrides
-
end
-
-
400
def call(key) = overrides.fetch(key) { |fallback| fallback }
-
-
1
private
-
-
1
attr_reader :overrides
-
end
-
end
-
# frozen_string_literal: true
-
-
1
require "refinements/array"
-
-
1
module Pennyworth
-
1
module Loaders
-
# Loads an array of encoding records.
-
1
class Encoding
-
1
using Refinements::Array
-
-
1
def initialize encoding: ::Encoding, model: Models::Encoding
-
22
@encoding = encoding
-
22
@model = model
-
end
-
-
1
def call(*)
-
3
encoding.aliases
-
213
.map { |_second, first| first }
-
.uniq
-
.sort
-
.map do |first|
-
183
model[name: first, aliases: encoding.find(first).names.sort.excluding(first)]
-
end
-
end
-
-
1
private
-
-
1
attr_reader :encoding, :model
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
require "core"
-
-
1
module Pennyworth
-
1
module Loaders
-
# Loads an array gems from the RubyGems API.
-
1
class Gem
-
1
include Dependencies[:settings, :http]
-
-
1
def call endpoint
-
4
http.get("#{settings.ruby_gems_api_uri}/#{endpoint}")
-
.then do |response|
-
4
then: 2
else: 2
return JSON response.body.to_s, symbolize_names: true if response.status.success?
-
-
2
Core::EMPTY_HASH
-
end
-
end
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
require "core"
-
1
require "ghub"
-
-
1
module Pennyworth
-
1
module Loaders
-
# Loads an array projects from the GitHub API.
-
1
class GitHub
-
1
def initialize endpoint: Ghub::Endpoints::Repositories::Root.new
-
22
@endpoint = endpoint
-
end
-
-
1
def call(path) = endpoint.index(*path.split("/")).value_or(Core::EMPTY_ARRAY).map(&:to_h)
-
-
1
private
-
-
1
attr_reader :endpoint
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
require "core"
-
1
require "refinements/string"
-
-
1
module Pennyworth
-
1
module Loaders
-
# Loads htmx documentation by scraping web page.
-
1
class HTMX
-
1
include Dependencies[:http, :settings, parser: :ox]
-
-
1
using Refinements::String
-
-
1
def self.text_for element
-
683
parts = element.each.with_object [] do |item, content|
-
1338
then: 349
text = if item.is_a? Ox::Element
-
349
"`#{item.text}`"
-
else: 989
else
-
989
item.encode ::Encoding::UTF_8, replace: Core::EMPTY_STRING
-
end
-
-
1338
content.append text
-
end
-
-
683
parts.join.up.delete_suffix "."
-
end
-
-
1
def initialize(model: Models::HTMX, **)
-
30
@model = model
-
30
super(**)
-
end
-
-
1
def call uri
-
13
read(uri).each.with_object [] do |row, entries|
-
723
else: 681
then: 42
next unless row.locate("td") in Ox::Element => item, Ox::Element => description
-
-
681
entries.append record_for(item, description, uri)
-
end
-
end
-
-
1
private
-
-
1
attr_reader :model
-
-
1
def read uri
-
13
http.follow.get(uri).then do |response|
-
13
then: 12
else: 1
[200, 301].include?(response.status) ? parse_rows(response.body.to_s) : Core::EMPTY_ARRAY
-
end
-
end
-
-
1
def parse_rows(document) = parser.parse(document).locate "*/tr"
-
-
1
def record_for item, description, uri
-
681
model[
-
681
label: (item.locate("*/code").first || item.locate("a").first).text,
-
description: "#{self.class.text_for description}.",
-
681
uri: (item.locate("*/@href").first || uri).sub(%r(\A(?=/)), settings.htmx_site_uri)
-
]
-
end
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
require "rack"
-
-
1
module Pennyworth
-
1
module Loaders
-
# Loads an array of HTTP status records.
-
1
class HTTPStatus
-
1
include Dependencies[:settings]
-
-
1
def initialize(codes: Rack::Utils::HTTP_STATUS_CODES, model: Models::HTTPStatus, **)
-
22
super(**)
-
22
@codes = codes
-
22
@model = model
-
end
-
-
1
def call(*)
-
183
codes.map { |(code, label)| model[code:, label:, url: "#{url}/#{code}"] }
-
end
-
-
1
private
-
-
1
attr_reader :codes, :model
-
-
1
def url = settings.http_statuses_uri
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
require "core"
-
1
require "refinements/pathname"
-
1
require "refinements/string"
-
-
1
module Pennyworth
-
1
module Loaders
-
# Loads Rodauth documentation by scraping the web page.
-
1
class Rodauth
-
1
include Dependencies[:http, :settings, parser: :ox]
-
-
1
using Refinements::String
-
1
using Refinements::Pathname
-
-
1
def initialize(model: Models::Rodauth, **)
-
24
@model = model
-
24
super(**)
-
end
-
-
1
def call uri
-
158
read(uri).each.with_object([]) { |item, entries| entries.append record_for(item) }
-
end
-
-
1
private
-
-
1
attr_reader :model
-
-
1
def read uri
-
5
http.get(uri).then do |response|
-
5
then: 4
else: 1
[200, 301].include?(response.status) ? parse_items(response.body.to_s) : Core::EMPTY_ARRAY
-
end
-
end
-
-
1
def parse_items document
-
4
parser.parse(document).root.body.div.ul.nodes
-
rescue NoMethodError
-
1
Core::EMPTY_ARRAY
-
end
-
-
1
def record_for item
-
153
link = item.a
-
153
uri = "#{settings.rodauth_site_uri}/#{link.href}"
-
-
153
model[
-
name: Pathname(uri).name.to_s.delete_suffix("_rdoc"),
-
label: link.text,
-
description: item.text.delete_prefix(": "),
-
uri:
-
]
-
end
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
module Pennyworth
-
1
module Loaders
-
# Loads an array of standard error records.
-
1
class StandardError
-
1
def initialize root: ::StandardError, model: Models::StandardError
-
22
@root = root
-
22
@model = model
-
end
-
-
1
def call(*)
-
3
ObjectSpace.each_object(Class)
-
10129
.select { |klass| klass < root }
-
.sort_by(&:name)
-
.map do |error|
-
1468
file_path, line_number = Object.const_source_location error.name
-
1468
model[name: error, file_path:, line_number:]
-
end
-
end
-
-
1
private
-
-
1
attr_reader :root, :model
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
require "core"
-
-
1
module Pennyworth
-
1
module Loaders
-
# Loads an array gems from the Standard Gems API.
-
1
class StandardGem
-
1
include Dependencies[:settings, :http]
-
-
1
def call endpoint
-
6
http.get("#{settings.standard_gems_api_uri}/#{endpoint}")
-
.then do |response|
-
6
then: 4
else: 2
response.status.success? ? records(response.body.to_s) : Core::EMPTY_HASH
-
end
-
end
-
-
1
private
-
-
1
def records(body) = JSON(body, symbolize_names: true).fetch :gems, Core::EMPTY_ARRAY
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
module Pennyworth
-
1
module Loaders
-
1
module System
-
# Loads an array of system error records.
-
1
class Error
-
1
def initialize errno: Errno, model: Models::System::Error
-
22
@errno = errno
-
22
@model = model
-
end
-
-
1
def call(*)
-
3
errno.constants
-
474
.map { |name| errno.const_get name }
-
.uniq
-
396
.sort_by { |error| error::Errno }
-
.map do |error|
-
396
model[id: error::Errno, name: error.name, description: error.exception.message]
-
end
-
end
-
-
1
private
-
-
1
attr_reader :errno, :model
-
end
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
module Pennyworth
-
1
module Loaders
-
1
module System
-
# Loads an array of signal records.
-
1
class Signal
-
1
def initialize list: ::Signal.list, model: Models::System::Signal
-
22
@list = list
-
22
@model = model
-
end
-
-
103
def call(*) = list.map { |name, number| model[number:, name:] }
-
-
1
private
-
-
1
attr_reader :list, :model
-
end
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
require "refinements/string"
-
-
1
module Pennyworth
-
1
module Loaders
-
# Loads an array of text records.
-
1
class Text
-
1
using Refinements::String
-
-
1
TRANSFORMS = %w[camelcase capitalize downcase size snakecase titleize upcase].freeze
-
-
1
def initialize transforms: TRANSFORMS, model: Models::Text
-
2
@transforms = transforms
-
2
@model = model
-
end
-
-
1
def call content
-
32
transforms.map { |kind| model[id: kind, content: content.public_send(kind)] }
-
end
-
-
1
private
-
-
1
attr_reader :transforms, :model
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
module Pennyworth
-
1
module Models
-
# Defines an encoding.
-
1
Encoding = Data.define :name, :aliases
-
end
-
end
-
# frozen_string_literal: true
-
-
1
module Pennyworth
-
1
module Models
-
# Represents a htmx link.
-
1
HTMX = Data.define :label, :description, :uri
-
end
-
end
-
# frozen_string_literal: true
-
-
1
module Pennyworth
-
1
module Models
-
# Defines HTTP status details.
-
1
HTTPStatus = Data.define :code, :label, :url do
-
1
def initialize code: nil, label: nil, url: nil
-
196
super
-
end
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
module Pennyworth
-
1
module Models
-
# Represents a Rodauth list item.
-
1
Rodauth = Data.define :name, :label, :description, :uri
-
end
-
end
-
# frozen_string_literal: true
-
-
1
module Pennyworth
-
1
module Models
-
# Defines a standard error.
-
1
StandardError = Data.define :name, :file_path, :line_number do
-
1
def initialize name: nil, file_path: nil, line_number: nil
-
1478
super
-
end
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
module Pennyworth
-
1
module Models
-
1
module System
-
# Defines a system error.
-
1
Error = Data.define :id, :name, :description
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
module Pennyworth
-
1
module Models
-
1
module System
-
# Defines a low-level operating system signal.
-
1
Signal = Data.define :number, :name
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
module Pennyworth
-
1
module Models
-
# Defines basic text.
-
1
Text = Data.define :id, :content
-
end
-
end
-
# frozen_string_literal: true
-
-
1
module Pennyworth
-
1
module Presenters
-
# Shapes an encoding record for serialization.
-
1
class Encoding
-
1
def initialize record
-
127
@record = record
-
end
-
-
1
def id = record.name
-
-
1
def label = record.name
-
-
1
def aliases = record.aliases
-
-
1
private
-
-
1
attr_reader :record
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
require "refinements/string"
-
-
1
module Pennyworth
-
1
module Presenters
-
# Shapes a RubyGems record for serialization.
-
1
class Gem
-
1
using Refinements::Array
-
1
using Refinements::String
-
-
1
def initialize record, inflector: Inflector.new
-
58
@record = record
-
58
@inflector = inflector
-
end
-
-
1
def id = record.fetch(:name)
-
-
1
def label = "#{inflector.call id.titleize} #{version}"
-
-
1
def subtitle = "Downloads: #{downloads}. Licenses: #{licenses}. Updated: #{updated_at[..9]}."
-
-
1
def version = record.fetch(__method__)
-
-
1
def licenses = Array(record.fetch(__method__)).to_sentence
-
-
1
def downloads = record.fetch(__method__)
-
-
1
def site_uri = record.fetch(:homepage_uri)
-
-
1
def source_uri = record.fetch(:source_code_uri)
-
-
1
def issues_uri = record.fetch(:bug_tracker_uri)
-
-
1
def versions_uri = record.fetch(:changelog_uri)
-
-
1
def updated_at = record.fetch(:version_created_at)
-
-
1
private
-
-
1
attr_reader :record, :inflector
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
require "forwardable"
-
-
1
module Pennyworth
-
1
module Presenters
-
# Shapes a htmx record for serialization.
-
1
class HTMX
-
1
extend Forwardable
-
-
1
delegate %i[label description uri] => :record
-
-
1
def initialize record
-
459
@record = record
-
end
-
-
1
alias id label
-
-
1
private
-
-
1
attr_reader :record
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
require "forwardable"
-
1
require "refinements/string"
-
-
1
module Pennyworth
-
1
module Presenters
-
# Shapes a HTTP status record for serialization.
-
1
class HTTPStatus
-
1
extend Forwardable
-
-
1
using Refinements::String
-
-
1
delegate %i[code label url] => :record
-
-
1
def initialize record, inflector: Inflector.new
-
132
@record = record
-
132
@inflector = inflector
-
end
-
-
1
def id = record.code
-
-
1
def subtitle = "#{id} #{label}"
-
-
1
def symbol = ":#{inflector.call name}"
-
-
1
private
-
-
1
attr_reader :record, :inflector
-
-
1
def name
-
127
label.snakecase
-
.tr("/", "_")
-
.gsub(/(\(|\))/, "")
-
.sub("h_t_t_p_version_not_supported", "http_version_not_supported")
-
.sub("i_m_used", "im_used")
-
.sub("u_r_i_too_long", "uri_too_long")
-
end
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
require "refinements/string"
-
-
1
module Pennyworth
-
1
module Presenters
-
# Shapes a repository record for serialization.
-
1
class Repository
-
1
using Refinements::String
-
-
1
def initialize record, inflector: Inflector.new
-
67
@record = record
-
67
@inflector = inflector
-
end
-
-
1
def id = record.fetch(:name)
-
-
1
def label = inflector.call(id.titleize)
-
-
1
def subtitle = record.fetch(:description)
-
-
1
def site_uri = record.fetch(:homepage)
-
-
1
def source_uri = record.fetch(:html_url)
-
-
1
def issues_uri = "#{source_uri}/issues"
-
-
1
def versions_uri = "#{site_uri}/versions"
-
-
1
private
-
-
1
attr_reader :record, :inflector
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
require "forwardable"
-
-
1
module Pennyworth
-
1
module Presenters
-
# Shapes a Rodauth record for serialization.
-
1
class Rodauth
-
1
extend Forwardable
-
-
1
delegate %i[name label description uri] => :record
-
-
1
def initialize record
-
107
@record = record
-
end
-
-
1
alias id name
-
-
1
private
-
-
1
attr_reader :record
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
require "refinements/array"
-
-
1
module Pennyworth
-
1
module Presenters
-
# Shapes a standard error record for serialization.
-
1
class StandardError
-
1
using Refinements::Array
-
-
1
def initialize record
-
986
@record = record
-
end
-
-
1
def id = label
-
-
1
def label = record.name.to_s
-
-
985
then: 354
else: 630
def path = file_path.empty? ? "" : [file_path, record.line_number].compress.join(":")
-
-
1
private
-
-
1
attr_reader :record
-
-
1
def file_path = record.file_path.to_s
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
require "core"
-
1
require "refinements/string"
-
-
1
module Pennyworth
-
1
module Presenters
-
# Shapes a standard gem record for serialization.
-
1
class StandardGem
-
1
using Refinements::Array
-
1
using Refinements::String
-
-
1
def initialize record, inflector: Inflector.new
-
44
@record = record
-
44
@inflector = inflector
-
end
-
-
1
def id = record.fetch :gem
-
-
1
def label = "#{inflector.call id.titleize} #{version}"
-
-
1
def subtitle = record.fetch :description
-
-
1
def version
-
68
versions = record.fetch :versions, Core::EMPTY_HASH
-
68
bundled, defaults = versions.values_at :bundled, :default
-
-
68
(bundled || defaults || versions).values.first
-
end
-
-
1
def site_uri = record.fetch(:sourceRepository, Core::EMPTY_STRING)
-
-
1
def source_uri = record.fetch(:sourceRepository, Core::EMPTY_STRING)
-
-
1
def issues_uri = "https://github.com/ruby/#{id}/issues"
-
-
1
def versions_uri = "https://github.com/ruby/#{id}/tags"
-
-
1
private
-
-
1
attr_reader :record, :inflector
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
require "forwardable"
-
-
1
module Pennyworth
-
1
module Presenters
-
1
module System
-
# Shapes a system error record for serialization.
-
1
class Error
-
1
extend Forwardable
-
-
1
delegate %i[id description] => :record
-
-
1
def initialize record
-
269
@record = record
-
end
-
-
1
def label = record.name
-
-
1
def subtitle = "#{label}: #{description}."
-
-
1
private
-
-
1
attr_reader :record
-
end
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
module Pennyworth
-
1
module Presenters
-
1
module System
-
# Shapes a system signal record for serialization.
-
1
class Signal
-
1
def initialize record
-
71
@record = record
-
end
-
-
1
def id = record.number
-
-
1
def label = record.name
-
-
1
private
-
-
1
attr_reader :record
-
end
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
require "forwardable"
-
-
1
module Pennyworth
-
1
module Presenters
-
# Shapes a text record for serialization.
-
1
class Text
-
1
extend Forwardable
-
-
1
delegate %i[id content] => :record
-
-
1
def initialize record, inflector: Inflector.new
-
26
@record = record
-
26
@inflector = inflector
-
end
-
-
1
def label = inflector.call(record.content.to_s)
-
-
1
private
-
-
1
attr_reader :record, :inflector
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
module Pennyworth
-
# Processes all steps required to render an Alfred Script Filter response.
-
1
class Processor
-
1
def initialize steps
-
214
@steps = steps
-
214
freeze
-
end
-
-
1
def call content = nil
-
32
loader.call(content)
-
2266
.map { |record| presenter.new record }
-
.sort_by(&:label)
-
2266
.map { |record| serializer.new record }
-
32
.then { |records| {items: records.map(&:to_h)} }
-
end
-
-
1
private
-
-
1
attr_reader :steps
-
-
1
def loader = steps.fetch(__method__)
-
-
1
def presenter = steps.fetch(__method__)
-
-
1
def serializer = steps.fetch(__method__)
-
end
-
end
-
# frozen_string_literal: true
-
-
1
module Pennyworth
-
1
module Serializers
-
# Serializes an encoding presenter for parsing by Alfred script filters.
-
1
class Encoding
-
1
using Refinements::Array
-
-
1
def initialize presenter
-
124
@presenter = presenter
-
end
-
-
1
def to_h
-
{
-
124
uid: presenter.id,
-
title: label,
-
subtitle: %(Aliases: #{aliases.to_sentence}.),
-
arg: label,
-
mods: {
-
alt: {subtitle: "Copy aliases.", arg: aliases.join(", ")}
-
},
-
text: {copy: label, largetype: label}
-
}
-
end
-
-
1
private
-
-
1
attr_reader :presenter
-
-
1
def label = presenter.label
-
-
1
def aliases = presenter.aliases
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
module Pennyworth
-
1
module Serializers
-
# Serializes a htmx presenter for parsing by Alfred script filters.
-
1
class HTMX
-
1
def initialize presenter
-
455
@presenter = presenter
-
end
-
-
1
def to_h
-
{
-
455
uid: presenter.id,
-
title: presenter.label,
-
subtitle: presenter.description,
-
arg: site_uri,
-
quicklookurl: site_uri,
-
mods: modifications,
-
text:
-
}
-
end
-
-
1
private
-
-
1
attr_reader :presenter
-
-
1
def modifications
-
{
-
455
alt: modification(presenter.label, "Copy label."),
-
cmd: modification(presenter.description, "Copy description.")
-
}
-
end
-
-
1
def modification argument, subtitle
-
{
-
910
subtitle:,
-
arg: argument
-
}
-
end
-
-
1
def text
-
{
-
455
copy: site_uri,
-
largetype: site_uri
-
}
-
end
-
-
1
def site_uri = presenter.uri
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
module Pennyworth
-
1
module Serializers
-
# Serializes a HTTP status presenter for parsing by Alfred script filters.
-
1
class HTTPStatus
-
1
def initialize presenter
-
121
@presenter = presenter
-
end
-
-
1
def to_h
-
{
-
121
uid: id,
-
title: code,
-
subtitle: label,
-
arg: presenter.symbol,
-
mods: modifications,
-
text: {copy: "#{code} #{label}", largetype: "#{code} #{label}"}
-
}
-
end
-
-
1
private
-
-
1
attr_reader :presenter
-
-
1
def id = presenter.id
-
-
1
def code = presenter.code
-
-
1
def label = presenter.label
-
-
1
def modifications
-
{
-
121
control: {subtitle: "Copy code.", arg: id},
-
alt: {subtitle: "Copy label.", arg: label},
-
cmd: {subtitle: "View documentation.", arg: presenter.url}
-
}
-
end
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
module Pennyworth
-
1
module Serializers
-
# Serializes a project presenter for parsing by Alfred script filters.
-
1
class Project
-
1
def initialize presenter
-
137
@presenter = presenter
-
end
-
-
1
def to_h
-
{
-
137
uid: presenter.id,
-
title: presenter.label,
-
subtitle: presenter.subtitle,
-
arg: site_uri,
-
quicklookurl: site_uri,
-
mods: modifications,
-
text:
-
}
-
end
-
-
1
private
-
-
1
attr_reader :presenter
-
-
1
def modifications
-
{
-
137
alt: modification(presenter.source_uri, "View source."),
-
cmd: modification(presenter.issues_uri, "View issues."),
-
control: modification(presenter.versions_uri, "View versions.")
-
}
-
end
-
-
1
def modification argument, subtitle
-
{
-
411
subtitle:,
-
arg: argument
-
}
-
end
-
-
1
def text
-
{
-
137
copy: site_uri,
-
largetype: site_uri
-
}
-
end
-
-
1
def site_uri = presenter.site_uri
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
module Pennyworth
-
1
module Serializers
-
# Serializes a Rodauth presenter for parsing by Alfred script filters.
-
1
class Rodauth
-
1
def initialize presenter
-
103
@presenter = presenter
-
end
-
-
1
def to_h
-
{
-
103
uid: presenter.id,
-
title: presenter.label,
-
subtitle: presenter.description,
-
arg: site_uri,
-
quicklookurl: site_uri,
-
mods: modifications,
-
text:
-
}
-
end
-
-
1
private
-
-
1
attr_reader :presenter
-
-
1
def modifications
-
{
-
103
alt: modification(presenter.label, "Copy label."),
-
cmd: modification(presenter.description, "Copy description."),
-
control: modification(presenter.name, "Copy name.")
-
}
-
end
-
-
1
def modification argument, subtitle
-
{
-
309
subtitle:,
-
arg: argument
-
}
-
end
-
-
1
def text
-
{
-
103
copy: site_uri,
-
largetype: site_uri
-
}
-
end
-
-
1
def site_uri = presenter.uri
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
module Pennyworth
-
1
module Serializers
-
# Serializes a standard error presenter for parsing by Alfred script filters.
-
1
class StandardError
-
1
def initialize presenter
-
980
@presenter = presenter
-
end
-
-
1
def to_h
-
{
-
980
uid: id,
-
title: id,
-
arg: label,
-
mods: modifications,
-
text: {copy: label, largetype: label}
-
}
-
end
-
-
1
private
-
-
1
attr_reader :presenter
-
-
1
def id = presenter.id
-
-
1
def label = presenter.label
-
-
1
def description = presenter.description
-
-
1
def modifications
-
{
-
980
control: {subtitle: "Copy label.", arg: label},
-
alt: {subtitle: "Copy path.", arg: path}
-
}
-
end
-
-
1
def path = presenter.path
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
module Pennyworth
-
1
module Serializers
-
1
module System
-
# Serializes a system error presenter for parsing by Alfred script filters.
-
1
class Error
-
1
def initialize presenter
-
265
@presenter = presenter
-
end
-
-
1
def to_h
-
{
-
265
uid: id,
-
title: id,
-
subtitle: presenter.subtitle,
-
arg: label,
-
mods: modifications,
-
text: {copy: label, largetype: label}
-
}
-
end
-
-
1
private
-
-
1
attr_reader :presenter
-
-
1
def id = presenter.id
-
-
1
def label = presenter.label
-
-
1
def description = presenter.description
-
-
1
def modifications
-
{
-
265
control: {subtitle: "Copy ID.", arg: id},
-
alt: {subtitle: "Copy description.", arg: description},
-
cmd: {
-
subtitle: "Copy ID, name, and description.",
-
arg: "#{id}, #{label}, #{description}"
-
}
-
}
-
end
-
end
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
module Pennyworth
-
1
module Serializers
-
1
module System
-
# Serializes a system signal presenter for parsing by Alfred script filters.
-
1
class Signal
-
1
def initialize presenter
-
69
@presenter = presenter
-
end
-
-
1
def to_h
-
{
-
69
uid: id,
-
title: label,
-
subtitle: id,
-
arg: label,
-
mods: modifications,
-
text: {copy: label, largetype: label}
-
}
-
end
-
-
1
private
-
-
1
attr_reader :presenter
-
-
1
def id = presenter.id
-
-
1
def label = presenter.label
-
-
1
def modifications
-
{
-
69
alt: {subtitle: "Copy ID.", arg: id},
-
cmd: {subtitle: "Copy ID and name.", arg: "#{id}, #{label}"}
-
}
-
end
-
end
-
end
-
end
-
end
-
# frozen_string_literal: true
-
-
1
module Pennyworth
-
1
module Serializers
-
# Serializes a text presenter for parsing by Alfred script filters.
-
1
class Text
-
1
def initialize presenter
-
22
@presenter = presenter
-
end
-
-
1
def to_h
-
{
-
22
uid: id,
-
title: presenter.label,
-
subtitle: id.capitalize,
-
arg: content,
-
icon: {path: "text/#{id}.png"},
-
text: {copy: content, largetype: content}
-
}
-
end
-
-
1
private
-
-
1
attr_reader :presenter
-
-
1
def id = presenter.id
-
-
1
def content = presenter.content
-
end
-
end
-
end