Skip to content

Commit 222974d

Browse files
CopilotGrantBirki
andcommitted
Documentation and code quality improvements
Co-authored-by: GrantBirki <[email protected]>
1 parent 3bab9e5 commit 222974d

File tree

9 files changed

+218
-32
lines changed

9 files changed

+218
-32
lines changed

lib/hooks/core/log.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,23 @@
11
# frozen_string_literal: true
22

33
module Hooks
4+
# Global logger accessor module
5+
#
6+
# Provides a singleton-like access pattern for the application logger.
7+
# The logger instance is set during application initialization and can
8+
# be accessed throughout the application lifecycle.
9+
#
10+
# @example Setting the logger instance
11+
# Hooks::Log.instance = Logger.new(STDOUT)
12+
#
13+
# @example Accessing the logger
14+
# Hooks::Log.instance.info("Application started")
415
module Log
516
class << self
17+
# Get or set the global logger instance
18+
# @return [Logger] The global logger instance
19+
# @attr_reader instance [Logger] Current logger instance
20+
# @attr_writer instance [Logger] Set the logger instance
621
attr_accessor :instance
722
end
823
end

lib/hooks/plugins/auth/hmac.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class HMAC < Base
4040
DEFAULT_CONFIG = {
4141
algorithm: "sha256",
4242
format: "algorithm=signature", # Format: algorithm=hash
43+
header: "X-Signature", # Default header containing the signature
4344
timestamp_tolerance: 300, # 5 minutes tolerance for timestamp validation
4445
version_prefix: "v0" # Default version prefix for versioned signatures
4546
}.freeze
@@ -157,7 +158,7 @@ def self.build_config(config)
157158
tolerance = validator_config[:timestamp_tolerance] || DEFAULT_CONFIG[:timestamp_tolerance]
158159

159160
DEFAULT_CONFIG.merge({
160-
header: validator_config[:header] || "X-Signature",
161+
header: validator_config[:header] || DEFAULT_CONFIG[:header],
161162
timestamp_header: validator_config[:timestamp_header],
162163
timestamp_tolerance: tolerance,
163164
algorithm: algorithm,

lib/hooks/plugins/handlers/default.rb

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,37 @@
11
# frozen_string_literal: true
22

3-
# Default handler when no custom handler is found
4-
# This handler simply acknowledges receipt of the webhook and shows a few of the built-in features
3+
# Default webhook handler implementation
4+
#
5+
# This handler provides a basic webhook processing implementation that can be used
6+
# as a fallback when no custom handler is configured for an endpoint. It demonstrates
7+
# the standard handler interface and provides basic logging functionality.
8+
#
9+
# @example Usage in endpoint configuration
10+
# handler:
11+
# type: DefaultHandler
12+
#
13+
# @see Hooks::Plugins::Handlers::Base
514
class DefaultHandler < Hooks::Plugins::Handlers::Base
15+
# Process a webhook request with basic acknowledgment
16+
#
17+
# Provides a simple webhook processing implementation that logs the request
18+
# and returns a standard acknowledgment response. This is useful for testing
19+
# webhook endpoints or as a placeholder during development.
20+
#
21+
# @param payload [Hash, String] The webhook payload (parsed JSON or raw string)
22+
# @param headers [Hash<String, String>] HTTP headers from the webhook request
23+
# @param config [Hash] Endpoint configuration containing handler options
24+
# @return [Hash] Response indicating successful processing
25+
# @option config [Hash] :opts Additional handler-specific configuration options
26+
#
27+
# @example Basic usage
28+
# handler = DefaultHandler.new
29+
# response = handler.call(
30+
# payload: { "event" => "push" },
31+
# headers: { "Content-Type" => "application/json" },
32+
# config: { opts: {} }
33+
# )
34+
# # => { message: "webhook processed successfully", handler: "DefaultHandler", timestamp: "..." }
635
def call(payload:, headers:, config:)
736

837
log.info("🔔 Default handler invoked for webhook 🔔")

lib/hooks/plugins/instruments/failbot.rb

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,25 @@ module Plugins
77
module Instruments
88
# Default failbot instrument implementation
99
#
10-
# This is a stub implementation that does nothing by default.
11-
# Users can replace this with their own implementation for services
12-
# like Sentry, Rollbar, etc.
10+
# This is a no-op implementation that provides the error reporting interface
11+
# without actually sending errors anywhere. It serves as a safe default when
12+
# no custom error reporting implementation is configured.
13+
#
14+
# Users should replace this with their own implementation for services
15+
# like Sentry, Rollbar, Honeybadger, etc.
16+
#
17+
# @example Replacing with a custom implementation
18+
# # In your application initialization:
19+
# custom_failbot = MySentryFailbotImplementation.new
20+
# Hooks::Core::GlobalComponents.failbot = custom_failbot
21+
#
22+
# @see Hooks::Plugins::Instruments::FailbotBase
23+
# @see Hooks::Core::GlobalComponents
1324
class Failbot < FailbotBase
14-
# Inherit from FailbotBase to provide a default implementation of the failbot instrument.
25+
# Inherit from FailbotBase to provide a default no-op implementation
26+
# of the error reporting instrument interface.
27+
#
28+
# All methods from FailbotBase are inherited and provide safe no-op behavior.
1529
end
1630
end
1731
end

lib/hooks/plugins/instruments/failbot_base.rb

Lines changed: 57 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,70 @@
11
# frozen_string_literal: true
22

3+
require_relative "../../core/component_access"
4+
35
module Hooks
46
module Plugins
57
module Instruments
68
# Base class for all failbot instrument plugins
79
#
8-
# All custom failbot implementations must inherit from this class and implement
9-
# the required methods for error reporting.
10+
# This class provides the foundation for implementing custom error reporting
11+
# instruments. Subclasses should implement specific methods for their target
12+
# error reporting service (Sentry, Rollbar, Honeybadger, etc.).
13+
#
14+
# @abstract Subclass and implement service-specific error reporting methods
15+
# @example Implementing a custom failbot instrument
16+
# class MySentryFailbot < Hooks::Plugins::Instruments::FailbotBase
17+
# def report(error_or_message, context = {})
18+
# case error_or_message
19+
# when Exception
20+
# Sentry.capture_exception(error_or_message, extra: context)
21+
# else
22+
# Sentry.capture_message(error_or_message.to_s, extra: context)
23+
# end
24+
# log.debug("Reported error to Sentry")
25+
# end
26+
# end
27+
#
28+
# @see Hooks::Plugins::Instruments::Failbot
1029
class FailbotBase
11-
# Short logger accessor for all subclasses
12-
# @return [Hooks::Log] Logger instance
30+
include Hooks::Core::ComponentAccess
31+
32+
# Report an error or message to the error tracking service
33+
#
34+
# This is a no-op implementation that subclasses should override
35+
# to provide actual error reporting functionality.
36+
#
37+
# @param error_or_message [Exception, String] The error to report or message string
38+
# @param context [Hash] Additional context information about the error
39+
# @return [void]
40+
# @note Subclasses should implement this method for their specific service
41+
# @example Override in subclass
42+
# def report(error_or_message, context = {})
43+
# if error_or_message.is_a?(Exception)
44+
# ErrorService.report_exception(error_or_message, context)
45+
# else
46+
# ErrorService.report_message(error_or_message, context)
47+
# end
48+
# end
49+
def report(error_or_message, context = {})
50+
# No-op implementation for base class
51+
end
52+
53+
# Report a warning-level message
1354
#
14-
# Provides a convenient way for instruments to log messages without needing
15-
# to reference the full Hooks::Log namespace.
55+
# This is a no-op implementation that subclasses should override
56+
# to provide actual warning reporting functionality.
1657
#
17-
# @example Logging debug info in an inherited class
18-
# log.debug("Sending error to external service")
19-
def log
20-
Hooks::Log.instance
58+
# @param message [String] Warning message to report
59+
# @param context [Hash] Additional context information
60+
# @return [void]
61+
# @note Subclasses should implement this method for their specific service
62+
# @example Override in subclass
63+
# def warn(message, context = {})
64+
# ErrorService.report_warning(message, context)
65+
# end
66+
def warn(message, context = {})
67+
# No-op implementation for base class
2168
end
2269
end
2370
end

lib/hooks/plugins/instruments/stats.rb

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,25 @@ module Plugins
77
module Instruments
88
# Default stats instrument implementation
99
#
10-
# This is a stub implementation that does nothing by default.
11-
# Users can replace this with their own implementation for services
12-
# like DataDog, New Relic, etc.
10+
# This is a no-op implementation that provides the stats interface without
11+
# actually sending metrics anywhere. It serves as a safe default when no
12+
# custom stats implementation is configured.
13+
#
14+
# Users should replace this with their own implementation for services
15+
# like DataDog, New Relic, StatsD, etc.
16+
#
17+
# @example Replacing with a custom implementation
18+
# # In your application initialization:
19+
# custom_stats = MyCustomStatsImplementation.new
20+
# Hooks::Core::GlobalComponents.stats = custom_stats
21+
#
22+
# @see Hooks::Plugins::Instruments::StatsBase
23+
# @see Hooks::Core::GlobalComponents
1324
class Stats < StatsBase
14-
# Inherit from StatsBase to provide a default implementation of the stats instrument.
25+
# Inherit from StatsBase to provide a default no-op implementation
26+
# of the stats instrument interface.
27+
#
28+
# All methods from StatsBase are inherited and provide safe no-op behavior.
1529
end
1630
end
1731
end

lib/hooks/plugins/instruments/stats_base.rb

Lines changed: 73 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,86 @@
11
# frozen_string_literal: true
22

3+
require_relative "../../core/component_access"
4+
35
module Hooks
46
module Plugins
57
module Instruments
68
# Base class for all stats instrument plugins
79
#
8-
# All custom stats implementations must inherit from this class and implement
9-
# the required methods for metrics reporting.
10+
# This class provides the foundation for implementing custom metrics reporting
11+
# instruments. Subclasses should implement specific methods for their target
12+
# metrics service (DataDog, New Relic, StatsD, etc.).
13+
#
14+
# @abstract Subclass and implement service-specific metrics methods
15+
# @example Implementing a custom stats instrument
16+
# class MyStatsImplementation < Hooks::Plugins::Instruments::StatsBase
17+
# def increment(metric_name, tags = {})
18+
# # Send increment metric to your service
19+
# MyMetricsService.increment(metric_name, tags)
20+
# log.debug("Sent increment metric: #{metric_name}")
21+
# end
22+
#
23+
# def timing(metric_name, duration, tags = {})
24+
# # Send timing metric to your service
25+
# MyMetricsService.timing(metric_name, duration, tags)
26+
# end
27+
# end
28+
#
29+
# @see Hooks::Plugins::Instruments::Stats
1030
class StatsBase
11-
# Short logger accessor for all subclasses
12-
# @return [Hooks::Log] Logger instance
31+
include Hooks::Core::ComponentAccess
32+
33+
# Record an increment metric
34+
#
35+
# This is a no-op implementation that subclasses should override
36+
# to provide actual metrics reporting functionality.
37+
#
38+
# @param metric_name [String] Name of the metric to increment
39+
# @param tags [Hash] Optional tags/labels for the metric
40+
# @return [void]
41+
# @note Subclasses should implement this method for their specific service
42+
# @example Override in subclass
43+
# def increment(metric_name, tags = {})
44+
# statsd.increment(metric_name, tags: tags)
45+
# end
46+
def increment(metric_name, tags = {})
47+
# No-op implementation for base class
48+
end
49+
50+
# Record a timing/duration metric
51+
#
52+
# This is a no-op implementation that subclasses should override
53+
# to provide actual metrics reporting functionality.
54+
#
55+
# @param metric_name [String] Name of the timing metric
56+
# @param duration [Numeric] Duration value (typically in milliseconds)
57+
# @param tags [Hash] Optional tags/labels for the metric
58+
# @return [void]
59+
# @note Subclasses should implement this method for their specific service
60+
# @example Override in subclass
61+
# def timing(metric_name, duration, tags = {})
62+
# statsd.timing(metric_name, duration, tags: tags)
63+
# end
64+
def timing(metric_name, duration, tags = {})
65+
# No-op implementation for base class
66+
end
67+
68+
# Record a gauge metric
1369
#
14-
# Provides a convenient way for instruments to log messages without needing
15-
# to reference the full Hooks::Log namespace.
70+
# This is a no-op implementation that subclasses should override
71+
# to provide actual metrics reporting functionality.
1672
#
17-
# @example Logging an error in an inherited class
18-
# log.error("Failed to send metric to external service")
19-
def log
20-
Hooks::Log.instance
73+
# @param metric_name [String] Name of the gauge metric
74+
# @param value [Numeric] Current value for the gauge
75+
# @param tags [Hash] Optional tags/labels for the metric
76+
# @return [void]
77+
# @note Subclasses should implement this method for their specific service
78+
# @example Override in subclass
79+
# def gauge(metric_name, value, tags = {})
80+
# statsd.gauge(metric_name, value, tags: tags)
81+
# end
82+
def gauge(metric_name, value, tags = {})
83+
# No-op implementation for base class
2184
end
2285
end
2386
end

lib/hooks/version.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# frozen_string_literal: true
22

3+
# Main Hooks module containing version information
34
module Hooks
5+
# Current version of the Hooks webhook framework
6+
# @return [String] The version string following semantic versioning
47
VERSION = "0.0.3"
58
end

spec/unit/lib/hooks/core/component_access_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,4 @@
5858
end
5959
end
6060
end
61-
end
61+
end

0 commit comments

Comments
 (0)