solidstats 2.0.0 → 3.0.0.beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -63
- data/README.md +27 -33
- data/Rakefile +3 -3
- data/app/assets/stylesheets/solidstats/application.css +1 -6
- data/app/assets/stylesheets/solidstats/dashboard.css +48 -0
- data/app/controllers/solidstats/dashboard_controller.rb +81 -62
- data/app/controllers/solidstats/logs_controller.rb +72 -0
- data/app/controllers/solidstats/performance_controller.rb +25 -0
- data/app/controllers/solidstats/productivity_controller.rb +39 -0
- data/app/controllers/solidstats/quality_controller.rb +152 -0
- data/app/controllers/solidstats/securities_controller.rb +30 -0
- data/app/helpers/solidstats/application_helper.rb +124 -11
- data/app/helpers/solidstats/performance_helper.rb +87 -0
- data/app/helpers/solidstats/productivity_helper.rb +38 -0
- data/app/services/solidstats/bundler_audit_service.rb +206 -0
- data/app/services/solidstats/coverage_compass_service.rb +335 -0
- data/app/services/solidstats/load_lens_service.rb +454 -0
- data/app/services/solidstats/log_size_monitor_service.rb +207 -76
- data/app/services/solidstats/my_todo_service.rb +242 -0
- data/app/services/solidstats/style_patrol_service.rb +319 -0
- data/app/views/layouts/solidstats/application.html.erb +8 -2
- data/app/views/layouts/solidstats/dashboard.html.erb +84 -0
- data/app/views/solidstats/dashboard/dashboard.html.erb +39 -0
- data/app/views/solidstats/logs/logs_size.html.erb +409 -0
- data/app/views/solidstats/performance/load_lens.html.erb +158 -0
- data/app/views/solidstats/productivity/_todo_list.html.erb +49 -0
- data/app/views/solidstats/productivity/my_todos.html.erb +84 -0
- data/app/views/solidstats/quality/coverage_compass.html.erb +420 -0
- data/app/views/solidstats/quality/style_patrol.html.erb +463 -0
- data/app/views/solidstats/securities/bundler_audit.html.erb +345 -0
- data/app/views/solidstats/shared/_dashboard_card.html.erb +160 -0
- data/app/views/solidstats/shared/_quick_actions.html.erb +26 -0
- data/config/routes.rb +32 -7
- data/lib/generators/solidstats/install/install_generator.rb +28 -2
- data/lib/generators/solidstats/install/templates/README +7 -0
- data/lib/solidstats/engine.rb +9 -114
- data/lib/solidstats/version.rb +1 -1
- data/lib/solidstats.rb +2 -299
- data/lib/tasks/solidstats_install.rake +2 -122
- data/lib/tasks/solidstats_performance.rake +84 -0
- metadata +32 -103
- data/app/assets/javascripts/solidstats/application.js +0 -257
- data/app/assets/javascripts/solidstats/dashboard.js +0 -225
- data/app/assets/javascripts/solidstats/gem_metadata.js +0 -554
- data/app/assets/stylesheets/solidstats/components/action_button.css +0 -99
- data/app/assets/stylesheets/solidstats/components/dashboard.css +0 -151
- data/app/assets/stylesheets/solidstats/components/dashboard_header.css +0 -93
- data/app/assets/stylesheets/solidstats/components/dashboard_layout.css +0 -97
- data/app/assets/stylesheets/solidstats/components/gem_metadata.css +0 -1403
- data/app/assets/stylesheets/solidstats/components/navigation.css +0 -80
- data/app/assets/stylesheets/solidstats/components/quick_navigation.css +0 -54
- data/app/assets/stylesheets/solidstats/components/security.css +0 -332
- data/app/assets/stylesheets/solidstats/components/status_badge.css +0 -58
- data/app/assets/stylesheets/solidstats/components/summary_card.css +0 -66
- data/app/assets/stylesheets/solidstats/components/tab_navigation.css +0 -95
- data/app/components/solidstats/base_component.rb +0 -88
- data/app/components/solidstats/code_quality/code_quality_section_component.html.erb +0 -0
- data/app/components/solidstats/code_quality/code_quality_section_component.rb +0 -0
- data/app/components/solidstats/code_quality/section_component.html.erb +0 -45
- data/app/components/solidstats/code_quality/section_component.rb +0 -34
- data/app/components/solidstats/dashboard_header_component.html.erb +0 -39
- data/app/components/solidstats/dashboard_header_component.rb +0 -33
- data/app/components/solidstats/previews/action_button_component_preview/button_vs_link.html.erb +0 -6
- data/app/components/solidstats/previews/action_button_component_preview/sizes.html.erb +0 -6
- data/app/components/solidstats/previews/action_button_component_preview/variants.html.erb +0 -6
- data/app/components/solidstats/previews/action_button_component_preview/with_icons.html.erb +0 -6
- data/app/components/solidstats/previews/action_button_component_preview.rb +0 -64
- data/app/components/solidstats/previews/navigation_component_preview.rb +0 -74
- data/app/components/solidstats/previews/stats_overview_component_preview.rb +0 -100
- data/app/components/solidstats/previews/status_badge_component_preview/sizes.html.erb +0 -6
- data/app/components/solidstats/previews/status_badge_component_preview/statuses.html.erb +0 -6
- data/app/components/solidstats/previews/status_badge_component_preview/with_icons.html.erb +0 -6
- data/app/components/solidstats/previews/status_badge_component_preview.rb +0 -49
- data/app/components/solidstats/previews/summary_card_component_preview/clickable.html.erb +0 -9
- data/app/components/solidstats/previews/summary_card_component_preview/dashboard_layout.html.erb +0 -9
- data/app/components/solidstats/previews/summary_card_component_preview/statuses.html.erb +0 -6
- data/app/components/solidstats/previews/summary_card_component_preview/value_formats.html.erb +0 -6
- data/app/components/solidstats/previews/summary_card_component_preview.rb +0 -67
- data/app/components/solidstats/quick_navigation_component.html.erb +0 -8
- data/app/components/solidstats/quick_navigation_component.rb +0 -21
- data/app/components/solidstats/security/gem_impact_analysis_component.html.erb +0 -44
- data/app/components/solidstats/security/gem_impact_analysis_component.rb +0 -45
- data/app/components/solidstats/security/overview_component.html.erb +0 -21
- data/app/components/solidstats/security/overview_component.rb +0 -104
- data/app/components/solidstats/security/section_component.html.erb +0 -26
- data/app/components/solidstats/security/section_component.rb +0 -52
- data/app/components/solidstats/security/timeline_component.html.erb +0 -39
- data/app/components/solidstats/security/timeline_component.rb +0 -43
- data/app/components/solidstats/tasks_section_component.html.erb +0 -17
- data/app/components/solidstats/tasks_section_component.rb +0 -22
- data/app/components/solidstats/ui/action_button_component.html.erb +0 -6
- data/app/components/solidstats/ui/action_button_component.rb +0 -71
- data/app/components/solidstats/ui/dashboard_layout_component.html.erb +0 -19
- data/app/components/solidstats/ui/dashboard_layout_component.rb +0 -85
- data/app/components/solidstats/ui/navigation_component.html.erb +0 -34
- data/app/components/solidstats/ui/navigation_component.rb +0 -72
- data/app/components/solidstats/ui/stats_overview_component.html.erb +0 -14
- data/app/components/solidstats/ui/stats_overview_component.rb +0 -78
- data/app/components/solidstats/ui/status_badge_component.html.erb +0 -6
- data/app/components/solidstats/ui/status_badge_component.rb +0 -42
- data/app/components/solidstats/ui/summary_card_component.html.erb +0 -12
- data/app/components/solidstats/ui/summary_card_component.rb +0 -63
- data/app/components/solidstats/ui/tab_navigation_component.html.erb +0 -22
- data/app/components/solidstats/ui/tab_navigation_component.rb +0 -79
- data/app/controllers/solidstats/gem_metadata_controller.rb +0 -12
- data/app/services/solidstats/audit_service.rb +0 -56
- data/app/services/solidstats/data_collector_service.rb +0 -83
- data/app/services/solidstats/gem_metadata/fetcher_service.rb +0 -136
- data/app/services/solidstats/todo_service.rb +0 -114
- data/app/views/solidstats/dashboard/_log_monitor.html.erb +0 -759
- data/app/views/solidstats/dashboard/_todos.html.erb +0 -151
- data/app/views/solidstats/dashboard/audit/_additional_styles.css +0 -22
- data/app/views/solidstats/dashboard/audit/_audit_badge.html.erb +0 -5
- data/app/views/solidstats/dashboard/audit/_audit_details.html.erb +0 -495
- data/app/views/solidstats/dashboard/audit/_audit_summary.html.erb +0 -26
- data/app/views/solidstats/dashboard/audit/_no_vulnerabilities.html.erb +0 -3
- data/app/views/solidstats/dashboard/audit/_security_audit.html.erb +0 -14
- data/app/views/solidstats/dashboard/audit/_vulnerabilities_table.html.erb +0 -1120
- data/app/views/solidstats/dashboard/audit/_vulnerability_details.html.erb +0 -63
- data/app/views/solidstats/dashboard/index.html.erb +0 -81
- data/app/views/solidstats/gem_metadata/_panel.html.erb +0 -419
- data/lib/generators/solidstats/feature/feature_generator.rb +0 -170
- data/lib/generators/solidstats/feature/templates/component.html.erb +0 -84
- data/lib/generators/solidstats/feature/templates/component.rb.erb +0 -103
- data/lib/generators/solidstats/feature/templates/component.scss +0 -243
- data/lib/generators/solidstats/feature/templates/component_test.rb.erb +0 -183
- data/lib/generators/solidstats/feature/templates/controller.rb.erb +0 -44
- data/lib/generators/solidstats/feature/templates/controller_test.rb.erb +0 -111
- data/lib/generators/solidstats/feature/templates/detail_view.html.erb +0 -755
- data/lib/generators/solidstats/feature/templates/preview.rb.erb +0 -107
- data/lib/generators/solidstats/feature/templates/service.rb.erb +0 -132
- data/lib/generators/solidstats/feature/templates/service_test.rb.erb +0 -109
- data/lib/generators/solidstats/install_generator.rb +0 -109
- data/lib/generators/solidstats/templates/initializer.rb +0 -112
- data/lib/solidstats/asset_compatibility.rb +0 -238
- data/lib/solidstats/asset_manifest.rb +0 -205
- data/lib/tasks/solidstats_tasks.rake +0 -4
data/lib/solidstats/engine.rb
CHANGED
@@ -1,127 +1,22 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "rails/engine" if defined?(Rails)
|
4
|
-
|
5
1
|
module Solidstats
|
6
2
|
class Engine < ::Rails::Engine
|
7
|
-
isolate_namespace Solidstats
|
8
|
-
|
9
|
-
# Engine configuration
|
10
|
-
config.solidstats = ActiveSupport::OrderedOptions.new
|
11
|
-
|
12
|
-
# Set default configuration values
|
13
|
-
config.before_configuration do
|
14
|
-
config.solidstats.cache_duration = 1.hour
|
15
|
-
config.solidstats.enable_components = true
|
16
|
-
config.solidstats.log_level = :info
|
17
|
-
config.solidstats.enable_previews = Rails.env.development?
|
18
|
-
end
|
3
|
+
isolate_namespace Solidstats
|
19
4
|
|
20
|
-
|
21
|
-
initializer "solidstats.environment_check", before: :load_config_initializers do
|
5
|
+
initializer "solidstats.only_in_dev" do
|
22
6
|
unless Rails.env.development?
|
23
|
-
raise Solidstats
|
24
|
-
"Solidstats can only be used in development mode. Current environment: #{Rails.env}"
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
# Load and configure ViewComponent if available
|
29
|
-
initializer "solidstats.setup_view_component", after: :load_config_initializers do |app|
|
30
|
-
setup_view_component(app) if view_component_available?
|
31
|
-
end
|
32
|
-
|
33
|
-
# Add custom paths for autoloading
|
34
|
-
initializer "solidstats.autoload_paths" do |app|
|
35
|
-
app.config.autoload_paths += Dir[Engine.root.join("app", "components", "**")]
|
36
|
-
app.config.autoload_paths += Dir[Engine.root.join("app", "services", "**")]
|
37
|
-
end
|
38
|
-
|
39
|
-
# Load custom rake tasks
|
40
|
-
rake_tasks do
|
41
|
-
load_rake_tasks
|
42
|
-
end
|
43
|
-
|
44
|
-
# Add custom generators path
|
45
|
-
config.generators do |g|
|
46
|
-
g.test_framework :minitest, spec: false, fixture: false
|
47
|
-
end
|
48
|
-
|
49
|
-
private
|
50
|
-
|
51
|
-
# Check if ViewComponent is available and properly loaded
|
52
|
-
# @return [Boolean] true if ViewComponent is available
|
53
|
-
def view_component_available?
|
54
|
-
defined?(ViewComponent::Base) && Solidstats.view_component_available?
|
55
|
-
end
|
56
|
-
|
57
|
-
# Configure ViewComponent integration
|
58
|
-
# @param app [Rails::Application] Rails application instance
|
59
|
-
def setup_view_component(app)
|
60
|
-
log_info "🔍 Solidstats: Setting up ViewComponent integration..."
|
61
|
-
|
62
|
-
begin
|
63
|
-
version = ViewComponent::VERSION rescue "unknown"
|
64
|
-
log_info "✅ ViewComponent #{version} detected and configured"
|
65
|
-
|
66
|
-
configure_view_component_settings(app)
|
67
|
-
setup_preview_paths(app)
|
68
|
-
|
69
|
-
log_info "🎯 ViewComponent::Base: #{ViewComponent::Base}"
|
70
|
-
rescue StandardError => e
|
71
|
-
log_error "❌ ViewComponent setup failed: #{e.message}"
|
72
|
-
raise Solidstats::ComponentError, "Failed to configure ViewComponent: #{e.message}"
|
7
|
+
raise "Solidstats can only be used in development mode."
|
73
8
|
end
|
74
9
|
end
|
75
10
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
return unless app.config.respond_to?(:view_component)
|
80
|
-
|
81
|
-
view_component_config = app.config.view_component
|
82
|
-
view_component_config.show_previews = config.solidstats.enable_previews
|
83
|
-
view_component_config.default_preview_layout = "solidstats/component_preview"
|
84
|
-
|
85
|
-
# Set preview controller if not already set
|
86
|
-
unless view_component_config.preview_controller
|
87
|
-
view_component_config.preview_controller = "Solidstats::ComponentPreviewsController"
|
11
|
+
initializer "solidstats.assets.precompile" do |app|
|
12
|
+
if Rails.env.development?
|
13
|
+
app.config.assets.precompile += %w[ solidstats/application.css ]
|
88
14
|
end
|
89
15
|
end
|
90
16
|
|
91
|
-
#
|
92
|
-
|
93
|
-
|
94
|
-
return unless app.config.respond_to?(:view_component) && config.solidstats.enable_previews
|
95
|
-
|
96
|
-
preview_path = Engine.root.join("app", "components", "solidstats", "previews")
|
97
|
-
|
98
|
-
unless app.config.view_component.preview_paths.include?(preview_path)
|
99
|
-
app.config.view_component.preview_paths << preview_path
|
100
|
-
log_info "📁 Added preview path: #{preview_path}"
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
# Load custom rake tasks
|
105
|
-
def load_rake_tasks
|
106
|
-
task_files = Dir[Engine.root.join("lib", "tasks", "**", "*.rake")]
|
107
|
-
task_files.each { |file| load file }
|
108
|
-
|
109
|
-
log_info "📋 Loaded #{task_files.size} rake task(s)" if task_files.any?
|
110
|
-
rescue StandardError => e
|
111
|
-
log_error "Failed to load rake tasks: #{e.message}"
|
112
|
-
end
|
113
|
-
|
114
|
-
# Logging helpers with consistent formatting
|
115
|
-
def log_info(message)
|
116
|
-
Rails.logger&.info("[Solidstats] #{message}")
|
117
|
-
end
|
118
|
-
|
119
|
-
def log_error(message)
|
120
|
-
Rails.logger&.error("[Solidstats] #{message}")
|
121
|
-
end
|
122
|
-
|
123
|
-
def log_debug(message)
|
124
|
-
Rails.logger&.debug("[Solidstats] #{message}")
|
17
|
+
# Load the solidstats rake tasks
|
18
|
+
rake_tasks do
|
19
|
+
Dir[File.join(File.dirname(__FILE__), "../tasks/**/*.rake")].each { |f| load f }
|
125
20
|
end
|
126
21
|
end
|
127
22
|
end
|
data/lib/solidstats/version.rb
CHANGED
data/lib/solidstats.rb
CHANGED
@@ -1,28 +1,12 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
require "solidstats/version"
|
4
2
|
require "solidstats/engine"
|
5
|
-
require "solidstats/asset_compatibility"
|
6
|
-
require "solidstats/asset_manifest"
|
7
3
|
|
8
4
|
module Solidstats
|
9
|
-
# Base error class for all Solidstats-specific errors
|
10
|
-
class Error < StandardError; end
|
11
|
-
|
12
|
-
# Configuration-related errors
|
13
|
-
class ConfigurationError < Error; end
|
14
|
-
|
15
|
-
# Component-related errors
|
16
|
-
class ComponentError < Error; end
|
17
|
-
|
18
|
-
# Service-related errors
|
19
|
-
class ServiceError < Error; end
|
20
|
-
|
21
5
|
class << self
|
22
6
|
# Returns the absolute path to this gem's root directory
|
23
|
-
# @return [
|
7
|
+
# @return [String] Gem root path
|
24
8
|
def root
|
25
|
-
|
9
|
+
File.dirname(__dir__)
|
26
10
|
end
|
27
11
|
|
28
12
|
# Returns version string
|
@@ -30,286 +14,5 @@ module Solidstats
|
|
30
14
|
def version
|
31
15
|
VERSION
|
32
16
|
end
|
33
|
-
|
34
|
-
# Returns the gem's app directory
|
35
|
-
# @return [Pathname] App directory path
|
36
|
-
def app_path
|
37
|
-
@app_path ||= root.join("app")
|
38
|
-
end
|
39
|
-
|
40
|
-
# Returns the components directory
|
41
|
-
# @return [Pathname] Components directory path
|
42
|
-
def components_path
|
43
|
-
@components_path ||= app_path.join("components", "solidstats")
|
44
|
-
end
|
45
|
-
|
46
|
-
# Returns the services directory
|
47
|
-
# @return [Pathname] Services directory path
|
48
|
-
def services_path
|
49
|
-
@services_path ||= app_path.join("services", "solidstats")
|
50
|
-
end
|
51
|
-
|
52
|
-
# Check if ViewComponent is available and properly loaded
|
53
|
-
# @return [Boolean] True if ViewComponent is loaded and usable
|
54
|
-
def view_component_available?
|
55
|
-
defined?(ViewComponent::Base) &&
|
56
|
-
ViewComponent::Base.respond_to?(:new) &&
|
57
|
-
defined?(Rails)
|
58
|
-
end
|
59
|
-
|
60
|
-
# Safely load ViewComponent if not already loaded
|
61
|
-
# @return [Boolean] True if ViewComponent was loaded successfully
|
62
|
-
def ensure_view_component!
|
63
|
-
return true if view_component_available?
|
64
|
-
|
65
|
-
unless defined?(Rails)
|
66
|
-
logger.warn "[Solidstats] Rails not available - ViewComponent cannot be loaded"
|
67
|
-
return false
|
68
|
-
end
|
69
|
-
|
70
|
-
begin
|
71
|
-
require "view_component"
|
72
|
-
require "view_component/engine"
|
73
|
-
|
74
|
-
# Verify it loaded correctly
|
75
|
-
if view_component_available?
|
76
|
-
logger.info "[Solidstats] ViewComponent loaded successfully"
|
77
|
-
true
|
78
|
-
else
|
79
|
-
logger.error "[Solidstats] ViewComponent loaded but not properly initialized"
|
80
|
-
false
|
81
|
-
end
|
82
|
-
rescue LoadError => e
|
83
|
-
logger.warn "[Solidstats] ViewComponent not available: #{e.message}"
|
84
|
-
false
|
85
|
-
rescue StandardError => e
|
86
|
-
logger.error "[Solidstats] Failed to load ViewComponent: #{e.message}"
|
87
|
-
false
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
# Check if running in development mode
|
92
|
-
# @return [Boolean] True if in development
|
93
|
-
def development?
|
94
|
-
defined?(Rails) && Rails.env.development?
|
95
|
-
end
|
96
|
-
|
97
|
-
# Check if running in production mode
|
98
|
-
# @return [Boolean] True if in production
|
99
|
-
def production?
|
100
|
-
defined?(Rails) && Rails.env.production?
|
101
|
-
end
|
102
|
-
|
103
|
-
# Check if running in test mode
|
104
|
-
# @return [Boolean] True if in test
|
105
|
-
def test?
|
106
|
-
defined?(Rails) && Rails.env.test?
|
107
|
-
end
|
108
|
-
|
109
|
-
# Current Rails environment
|
110
|
-
# @return [String, nil] Environment name or nil if Rails not available
|
111
|
-
def environment
|
112
|
-
Rails.env if defined?(Rails)
|
113
|
-
end
|
114
|
-
|
115
|
-
# Configuration object for the gem
|
116
|
-
# @return [Configuration] Configuration instance
|
117
|
-
def configuration
|
118
|
-
@configuration ||= Configuration.new
|
119
|
-
end
|
120
|
-
|
121
|
-
# Configure the gem with a block
|
122
|
-
# @yield [Configuration] Configuration object
|
123
|
-
# @example
|
124
|
-
# Solidstats.configure do |config|
|
125
|
-
# config.cache_duration = 30.minutes
|
126
|
-
# config.enable_components = true
|
127
|
-
# end
|
128
|
-
def configure
|
129
|
-
yield(configuration) if block_given?
|
130
|
-
configuration
|
131
|
-
end
|
132
|
-
|
133
|
-
# Reset configuration to defaults
|
134
|
-
# @return [Configuration] New configuration instance
|
135
|
-
def reset_configuration!
|
136
|
-
@configuration = Configuration.new
|
137
|
-
end
|
138
|
-
|
139
|
-
# Logger instance with fallback
|
140
|
-
# @return [Logger] Logger instance
|
141
|
-
def logger
|
142
|
-
@logger ||= build_logger
|
143
|
-
end
|
144
|
-
|
145
|
-
# Set a custom logger
|
146
|
-
# @param custom_logger [Logger] Custom logger instance
|
147
|
-
def logger=(custom_logger)
|
148
|
-
@logger = custom_logger
|
149
|
-
end
|
150
|
-
|
151
|
-
# Check if Solidstats can run in current environment
|
152
|
-
# @return [Boolean] True if environment is suitable
|
153
|
-
# @raise [ConfigurationError] If environment is not suitable
|
154
|
-
def environment_suitable?
|
155
|
-
unless development?
|
156
|
-
raise ConfigurationError,
|
157
|
-
"Solidstats can only be used in development mode. Current: #{environment || 'unknown'}"
|
158
|
-
end
|
159
|
-
|
160
|
-
true
|
161
|
-
end
|
162
|
-
|
163
|
-
# Get engine instance
|
164
|
-
# @return [Solidstats::Engine] Engine instance
|
165
|
-
def engine
|
166
|
-
Engine
|
167
|
-
end
|
168
|
-
|
169
|
-
# Get asset strategy for current application
|
170
|
-
# @return [Symbol] Asset strategy (:sprockets, :webpacker, :importmap, :auto)
|
171
|
-
def asset_strategy
|
172
|
-
return configuration.assets[:strategy] if configuration.assets[:strategy] != :auto
|
173
|
-
|
174
|
-
# Auto-detect asset strategy
|
175
|
-
if defined?(Importmap) && File.exist?(Rails.root.join("config/importmap.rb"))
|
176
|
-
:importmap
|
177
|
-
elsif defined?(Webpacker) && File.exist?(Rails.root.join("config/webpacker.yml"))
|
178
|
-
:webpacker
|
179
|
-
elsif defined?(Sprockets)
|
180
|
-
:sprockets
|
181
|
-
else
|
182
|
-
:none
|
183
|
-
end
|
184
|
-
end
|
185
|
-
|
186
|
-
# Check if assets should be fingerprinted
|
187
|
-
# @return [Boolean] True if fingerprinting is enabled
|
188
|
-
def asset_fingerprinting?
|
189
|
-
configuration.assets[:fingerprint] && !Rails.env.development?
|
190
|
-
end
|
191
|
-
|
192
|
-
# Get the asset prefix for engine assets
|
193
|
-
# @return [String] Asset prefix
|
194
|
-
def asset_prefix
|
195
|
-
case asset_strategy
|
196
|
-
when :importmap, :sprockets
|
197
|
-
"solidstats"
|
198
|
-
when :webpacker
|
199
|
-
"solidstats"
|
200
|
-
else
|
201
|
-
"solidstats"
|
202
|
-
end
|
203
|
-
end
|
204
|
-
|
205
|
-
private
|
206
|
-
|
207
|
-
# Build appropriate logger based on environment
|
208
|
-
# @return [Logger] Logger instance
|
209
|
-
def build_logger
|
210
|
-
if defined?(Rails) && Rails.respond_to?(:logger) && Rails.logger
|
211
|
-
Rails.logger
|
212
|
-
else
|
213
|
-
require "logger"
|
214
|
-
Logger.new($stdout, level: Logger::INFO).tap do |log|
|
215
|
-
log.formatter = proc do |severity, datetime, progname, msg|
|
216
|
-
"[#{datetime.strftime('%Y-%m-%d %H:%M:%S')}] #{severity}: #{msg}\n"
|
217
|
-
end
|
218
|
-
end
|
219
|
-
end
|
220
|
-
end
|
221
|
-
end
|
222
|
-
|
223
|
-
# Configuration class for Solidstats gem
|
224
|
-
class Configuration
|
225
|
-
# @!attribute [rw] cache_duration
|
226
|
-
# @return [ActiveSupport::Duration] Cache duration for services
|
227
|
-
attr_accessor :cache_duration
|
228
|
-
|
229
|
-
# @!attribute [rw] enable_components
|
230
|
-
# @return [Boolean] Whether to enable ViewComponent integration
|
231
|
-
attr_accessor :enable_components
|
232
|
-
|
233
|
-
# @!attribute [rw] log_level
|
234
|
-
# @return [Symbol] Logging level
|
235
|
-
attr_accessor :log_level
|
236
|
-
|
237
|
-
# @!attribute [rw] enable_previews
|
238
|
-
# @return [Boolean] Whether to enable component previews
|
239
|
-
attr_accessor :enable_previews
|
240
|
-
|
241
|
-
# @!attribute [rw] preview_layout
|
242
|
-
# @return [String] Layout for component previews
|
243
|
-
attr_accessor :preview_layout
|
244
|
-
|
245
|
-
# @!attribute [rw] assets
|
246
|
-
# @return [Hash] Asset configuration options
|
247
|
-
attr_accessor :assets
|
248
|
-
|
249
|
-
# @!attribute [rw] css_framework
|
250
|
-
# @return [Symbol] CSS framework integration (:none, :bootstrap, :tailwind)
|
251
|
-
attr_accessor :css_framework
|
252
|
-
|
253
|
-
def initialize
|
254
|
-
set_defaults
|
255
|
-
end
|
256
|
-
|
257
|
-
# Check if components are enabled and available
|
258
|
-
# @return [Boolean] True if components can be used
|
259
|
-
def components_enabled?
|
260
|
-
@enable_components && Solidstats.view_component_available?
|
261
|
-
end
|
262
|
-
|
263
|
-
# Check if previews are enabled
|
264
|
-
# @return [Boolean] True if previews should be shown
|
265
|
-
def previews_enabled?
|
266
|
-
@enable_previews && Solidstats.development?
|
267
|
-
end
|
268
|
-
|
269
|
-
# Validate configuration
|
270
|
-
# @return [Boolean] True if configuration is valid
|
271
|
-
# @raise [ConfigurationError] If configuration is invalid
|
272
|
-
def validate!
|
273
|
-
unless cache_duration.respond_to?(:seconds)
|
274
|
-
raise ConfigurationError, "cache_duration must be a time duration"
|
275
|
-
end
|
276
|
-
|
277
|
-
unless [ :debug, :info, :warn, :error, :fatal, :unknown ].include?(@log_level)
|
278
|
-
raise ConfigurationError, "log_level must be a valid log level symbol"
|
279
|
-
end
|
280
|
-
|
281
|
-
true
|
282
|
-
end
|
283
|
-
|
284
|
-
private
|
285
|
-
|
286
|
-
def set_defaults
|
287
|
-
@cache_duration = 1.hour
|
288
|
-
@enable_components = true
|
289
|
-
@log_level = :info
|
290
|
-
@enable_previews = true
|
291
|
-
@preview_layout = "solidstats/component_preview"
|
292
|
-
@assets = {
|
293
|
-
fingerprint: true,
|
294
|
-
strategy: :auto,
|
295
|
-
precompile: true,
|
296
|
-
compile_on_demand: Rails.env.development?
|
297
|
-
}
|
298
|
-
@css_framework = :none
|
299
|
-
end
|
300
|
-
end
|
301
|
-
end
|
302
|
-
|
303
|
-
# Auto-require common dependencies if in Rails environment
|
304
|
-
if defined?(Rails) && Rails.env.development?
|
305
|
-
# Ensure ViewComponent is available
|
306
|
-
Solidstats.ensure_view_component!
|
307
|
-
|
308
|
-
# Auto-require core services that are commonly used
|
309
|
-
begin
|
310
|
-
require_relative "solidstats/gem_metadata/fetcher_service" if
|
311
|
-
File.exist?(File.join(__dir__, "solidstats/gem_metadata/fetcher_service.rb"))
|
312
|
-
rescue LoadError => e
|
313
|
-
Solidstats.logger.debug "[Solidstats] Could not auto-load services: #{e.message}"
|
314
17
|
end
|
315
18
|
end
|
@@ -1,19 +1,8 @@
|
|
1
1
|
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
2
|
namespace :solidstats do
|
5
|
-
desc "Install Solidstats
|
3
|
+
desc "Install Solidstats into your Rails application"
|
6
4
|
task :install do
|
7
|
-
|
8
|
-
|
9
|
-
# Check Rails environment
|
10
|
-
unless Rails.env.development?
|
11
|
-
puts "⚠️ Warning: Solidstats is designed for development environments."
|
12
|
-
puts "Current environment: #{Rails.env}"
|
13
|
-
end
|
14
|
-
|
15
|
-
# Run the generator
|
16
|
-
if system("rails generate solidstats:install")
|
5
|
+
if system "rails g solidstats:install"
|
17
6
|
puts "\n✅ Solidstats installation completed successfully!"
|
18
7
|
puts " Start your Rails server and visit http://localhost:3000/solidstats\n\n"
|
19
8
|
else
|
@@ -21,113 +10,4 @@ namespace :solidstats do
|
|
21
10
|
puts " bundle exec rails generate solidstats:install\n\n"
|
22
11
|
end
|
23
12
|
end
|
24
|
-
|
25
|
-
desc "Validate Solidstats installation and configuration"
|
26
|
-
task validate: :environment do
|
27
|
-
puts "🔍 Validating Solidstats installation..."
|
28
|
-
|
29
|
-
begin
|
30
|
-
# Check basic configuration
|
31
|
-
Solidstats.configuration
|
32
|
-
puts "✅ Configuration loaded"
|
33
|
-
|
34
|
-
# Check ViewComponent availability
|
35
|
-
if Solidstats.view_component_available?
|
36
|
-
version = defined?(ViewComponent::VERSION) ? ViewComponent::VERSION : "unknown"
|
37
|
-
puts "✅ ViewComponent available (#{version})"
|
38
|
-
else
|
39
|
-
puts "❌ ViewComponent not available"
|
40
|
-
end
|
41
|
-
|
42
|
-
# Check asset strategy
|
43
|
-
strategy = Solidstats.asset_strategy
|
44
|
-
puts "✅ Asset strategy: #{strategy}"
|
45
|
-
|
46
|
-
# Validate asset manifest
|
47
|
-
Solidstats::AssetManifest.validate_assets!
|
48
|
-
puts "✅ All required assets present"
|
49
|
-
|
50
|
-
# Check routes
|
51
|
-
if Rails.application.routes.routes.any? { |r| r.path.spec.to_s.include?("solidstats") }
|
52
|
-
puts "✅ Routes mounted"
|
53
|
-
else
|
54
|
-
puts "⚠️ Routes not mounted - add 'mount Solidstats::Engine => \"/solidstats\"' to config/routes.rb"
|
55
|
-
end
|
56
|
-
|
57
|
-
puts "\n🎉 Solidstats validation complete!"
|
58
|
-
|
59
|
-
rescue => e
|
60
|
-
puts "❌ Validation failed: #{e.message}"
|
61
|
-
exit 1
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
desc "Show asset configuration information"
|
66
|
-
task assets: :environment do
|
67
|
-
puts "📦 Solidstats Asset Configuration"
|
68
|
-
puts "=" * 40
|
69
|
-
|
70
|
-
puts "Asset Strategy: #{Solidstats.asset_strategy}"
|
71
|
-
puts "Fingerprinting: #{Solidstats.asset_fingerprinting?}"
|
72
|
-
puts "Asset Prefix: #{Solidstats.asset_prefix}"
|
73
|
-
|
74
|
-
puts "\nPrecompiled Assets:"
|
75
|
-
Solidstats::AssetManifest.assets_for_environment.each do |asset|
|
76
|
-
puts " • #{asset}"
|
77
|
-
end
|
78
|
-
|
79
|
-
if Rails.application.config.respond_to?(:assets)
|
80
|
-
puts "\nAsset Paths:"
|
81
|
-
Rails.application.config.assets.paths.select { |p| p.include?("solidstats") }.each do |path|
|
82
|
-
puts " • #{path}"
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
desc "Test asset compilation"
|
88
|
-
task compile_assets: :environment do
|
89
|
-
puts "🔧 Testing asset compilation..."
|
90
|
-
|
91
|
-
begin
|
92
|
-
test_assets = [ "solidstats/application.css", "solidstats/application.js" ]
|
93
|
-
|
94
|
-
if Rails.application.config.respond_to?(:assets)
|
95
|
-
manifest = Rails.application.assets
|
96
|
-
|
97
|
-
# Check if we're using Propshaft (Rails 7+) or Sprockets
|
98
|
-
if manifest.respond_to?(:find_asset)
|
99
|
-
# Sprockets
|
100
|
-
test_assets.each do |asset|
|
101
|
-
if manifest.find_asset(asset)
|
102
|
-
puts "✅ #{asset} - found and compilable (Sprockets)"
|
103
|
-
else
|
104
|
-
puts "❌ #{asset} - not found (Sprockets)"
|
105
|
-
end
|
106
|
-
end
|
107
|
-
elsif manifest.respond_to?(:load_path) && manifest.load_path.respond_to?(:find)
|
108
|
-
# Propshaft
|
109
|
-
test_assets.each do |asset|
|
110
|
-
if manifest.load_path.find(asset)
|
111
|
-
puts "✅ #{asset} - found and compilable (Propshaft)"
|
112
|
-
else
|
113
|
-
puts "❌ #{asset} - not found (Propshaft)"
|
114
|
-
end
|
115
|
-
end
|
116
|
-
else
|
117
|
-
# Unknown asset pipeline
|
118
|
-
puts "⚠️ Unknown asset pipeline type: #{manifest.class}"
|
119
|
-
puts "Available methods: #{manifest.methods.grep(/find/).join(', ')}"
|
120
|
-
end
|
121
|
-
else
|
122
|
-
puts "⚠️ No asset pipeline detected"
|
123
|
-
end
|
124
|
-
|
125
|
-
puts "✅ Asset compilation test complete"
|
126
|
-
|
127
|
-
rescue => e
|
128
|
-
puts "❌ Asset compilation failed: #{e.message}"
|
129
|
-
puts "Asset pipeline class: #{Rails.application.assets.class}" if Rails.application.respond_to?(:assets)
|
130
|
-
exit 1
|
131
|
-
end
|
132
|
-
end
|
133
13
|
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
namespace :solidstats do
|
4
|
+
namespace :load_lens do
|
5
|
+
desc "Parse development log and extract LoadLens performance metrics"
|
6
|
+
task parse_logs: :environment do
|
7
|
+
result = Solidstats::LoadLensService.parse_log_and_save
|
8
|
+
|
9
|
+
if result[:success]
|
10
|
+
puts "Successfully parsed #{result[:processed]} requests for LoadLens"
|
11
|
+
else
|
12
|
+
puts "Error parsing logs for LoadLens: #{result[:error]}"
|
13
|
+
exit 1
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
desc "Refresh LoadLens performance data cache"
|
18
|
+
task refresh: :environment do
|
19
|
+
puts "Refreshing LoadLens performance data..."
|
20
|
+
Solidstats::LoadLensService.refresh_data
|
21
|
+
puts "LoadLens performance data refreshed successfully!"
|
22
|
+
end
|
23
|
+
|
24
|
+
desc "Show LoadLens performance data summary"
|
25
|
+
task summary: :environment do
|
26
|
+
data = Solidstats::LoadLensService.get_performance_data
|
27
|
+
summary = data[:summary]
|
28
|
+
|
29
|
+
puts "\n=== LoadLens Performance Summary ==="
|
30
|
+
puts "Total Requests: #{summary[:total_requests]}"
|
31
|
+
puts "Average Response Time: #{summary[:avg_response_time]}ms"
|
32
|
+
puts "Average View Time: #{summary[:avg_view_time]}ms"
|
33
|
+
puts "Average DB Time: #{summary[:avg_db_time]}ms"
|
34
|
+
puts "Slow Requests (>1000ms): #{summary[:slow_requests]}"
|
35
|
+
puts "Error Rate: #{summary[:error_rate]}%"
|
36
|
+
puts "Status: #{summary[:status]}"
|
37
|
+
puts "Last Updated: #{summary[:last_updated]}"
|
38
|
+
puts "===================================="
|
39
|
+
end
|
40
|
+
|
41
|
+
desc "Clean old LoadLens performance data files"
|
42
|
+
task clean_old_data: :environment do
|
43
|
+
data_dir = Rails.root.join('tmp', 'solidstats')
|
44
|
+
cutoff_date = 7.days.ago.to_date
|
45
|
+
deleted_count = 0
|
46
|
+
|
47
|
+
Dir.glob(data_dir.join('perf_*.json')).each do |file|
|
48
|
+
if match = File.basename(file).match(/perf_(\d{4}-\d{2}-\d{2})\.json/)
|
49
|
+
file_date = Date.parse(match[1])
|
50
|
+
if file_date < cutoff_date
|
51
|
+
File.delete(file)
|
52
|
+
deleted_count += 1
|
53
|
+
puts "Deleted #{File.basename(file)}"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
puts "Cleaned #{deleted_count} old LoadLens performance data files"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Keep performance namespace for backward compatibility
|
63
|
+
namespace :performance do
|
64
|
+
desc "Parse development log and extract performance metrics (alias for load_lens:parse_logs)"
|
65
|
+
task parse_logs: :environment do
|
66
|
+
Rake::Task["solidstats:load_lens:parse_logs"].invoke
|
67
|
+
end
|
68
|
+
|
69
|
+
desc "Refresh performance data cache (alias for load_lens:refresh)"
|
70
|
+
task refresh: :environment do
|
71
|
+
Rake::Task["solidstats:load_lens:refresh"].invoke
|
72
|
+
end
|
73
|
+
|
74
|
+
desc "Show performance data summary (alias for load_lens:summary)"
|
75
|
+
task summary: :environment do
|
76
|
+
Rake::Task["solidstats:load_lens:summary"].invoke
|
77
|
+
end
|
78
|
+
|
79
|
+
desc "Clean old performance data files (alias for load_lens:clean_old_data)"
|
80
|
+
task clean_old_data: :environment do
|
81
|
+
Rake::Task["solidstats:load_lens:clean_old_data"].invoke
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|