solidstats 2.0.0 → 3.0.0
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 -0
- data/Rakefile +3 -3
- data/app/assets/javascripts/solidstats/dashboard.js +0 -46
- data/app/assets/stylesheets/solidstats/dashboard.css +48 -0
- data/app/controllers/solidstats/dashboard_controller.rb +73 -61
- 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 +474 -0
- data/app/services/solidstats/log_size_monitor_service.rb +197 -66
- 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 +31 -6
- data/lib/generators/solidstats/clean/clean_generator.rb +24 -0
- data/lib/generators/solidstats/clean/templates/README +8 -0
- data/lib/generators/solidstats/install/install_generator.rb +51 -10
- data/lib/generators/solidstats/install/templates/README +7 -0
- data/lib/solidstats/engine.rb +6 -71
- data/lib/solidstats/version.rb +1 -1
- data/lib/solidstats.rb +19 -303
- data/lib/tasks/solidstats.rake +67 -0
- data/lib/tasks/solidstats_performance.rake +61 -0
- data/lib/tasks/solidstats_tasks.rake +16 -4
- metadata +33 -95
- 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/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/tasks/solidstats_install.rake +0 -133
@@ -2,30 +2,71 @@ require "rails/generators/base"
|
|
2
2
|
|
3
3
|
module Solidstats
|
4
4
|
module Generators
|
5
|
-
# This generator installs Solidstats
|
5
|
+
# This generator installs Solidstats in the host application
|
6
6
|
#
|
7
7
|
# @example
|
8
8
|
# $ rails generate solidstats:install
|
9
9
|
#
|
10
10
|
# This will:
|
11
11
|
# 1. Add the Solidstats routes to the host application's config/routes.rb
|
12
|
-
# 2.
|
12
|
+
# 2. Create a solidstats directory for data storage
|
13
|
+
# 3. Add the solidstats directory to .gitignore
|
14
|
+
# 4. Show a helpful README with next steps
|
13
15
|
class InstallGenerator < Rails::Generators::Base
|
14
16
|
source_root File.expand_path("templates", __dir__)
|
15
|
-
desc "
|
17
|
+
desc "Installs Solidstats in your Rails application"
|
16
18
|
|
17
19
|
def add_routes
|
18
|
-
|
20
|
+
route_string = %Q(mount Solidstats::Engine => "/solidstats")
|
21
|
+
route_code = %Q(
|
19
22
|
# Solidstats Routes (development only)
|
20
|
-
|
21
|
-
|
23
|
+
#{route_string} if Rails.env.development?
|
24
|
+
)
|
22
25
|
|
23
|
-
route
|
24
|
-
|
26
|
+
# Check if the route already exists
|
27
|
+
if File.read(File.join(destination_root, "config", "routes.rb")).include?(route_string)
|
28
|
+
say_status :skip, "Solidstats route already exists", :yellow
|
29
|
+
else
|
30
|
+
route route_code.strip
|
31
|
+
say_status :routes, "Mounting Solidstats engine at /solidstats (development only)", :green
|
32
|
+
end
|
25
33
|
end
|
26
34
|
|
27
|
-
def
|
28
|
-
|
35
|
+
def create_solidstats_directory
|
36
|
+
empty_directory "solidstats"
|
37
|
+
create_file "solidstats/.keep", ""
|
38
|
+
say_status :create, "solidstats directory for data storage", :green
|
39
|
+
end
|
40
|
+
|
41
|
+
def add_to_gitignore
|
42
|
+
gitignore_path = File.join(destination_root, ".gitignore")
|
43
|
+
gitignore_content = "\n# Solidstats data directory\nsolidstats/\n"
|
44
|
+
|
45
|
+
if File.exist?(gitignore_path)
|
46
|
+
append_to_file ".gitignore", gitignore_content unless File.read(gitignore_path).include?("solidstats/")
|
47
|
+
else
|
48
|
+
create_file ".gitignore", gitignore_content.strip
|
49
|
+
end
|
50
|
+
say_status :update, ".gitignore to exclude solidstats directory", :green
|
51
|
+
end
|
52
|
+
|
53
|
+
def show_next_steps
|
54
|
+
say ""
|
55
|
+
say "✅ Solidstats has been installed successfully!", :green
|
56
|
+
say ""
|
57
|
+
say "To get started, you need to prime the data for the dashboard."
|
58
|
+
say "You can prime data for all services at once by running:", :yellow
|
59
|
+
say " rake solidstats:prime:all", :cyan
|
60
|
+
say ""
|
61
|
+
say "Or, you can run them individually:", :yellow
|
62
|
+
say " rake solidstats:prime:log_size"
|
63
|
+
say " rake solidstats:prime:bundler_audit"
|
64
|
+
say " rake solidstats:prime:todos"
|
65
|
+
say " rake solidstats:prime:style_patrol"
|
66
|
+
say " rake solidstats:prime:coverage"
|
67
|
+
say " rake solidstats:prime:load_lens"
|
68
|
+
say ""
|
69
|
+
say "After the tasks complete, start your server and visit http://localhost:3000/solidstats to see the dashboard."
|
29
70
|
end
|
30
71
|
end
|
31
72
|
end
|
@@ -5,6 +5,11 @@ Solidstats has been successfully installed for development!
|
|
5
5
|
Your Solidstats dashboard is now available at: /solidstats
|
6
6
|
(Only in development environment)
|
7
7
|
|
8
|
+
Setup completed:
|
9
|
+
✓ Routes mounted at /solidstats
|
10
|
+
✓ Data directory created: ./solidstats
|
11
|
+
✓ Added solidstats/ to .gitignore
|
12
|
+
|
8
13
|
To access your stats:
|
9
14
|
1. Start your Rails server: bundle exec rails s
|
10
15
|
2. Visit: http://localhost:3000/solidstats
|
@@ -15,4 +20,6 @@ Solidstats will show you:
|
|
15
20
|
- Code quality metrics
|
16
21
|
- And more!
|
17
22
|
|
23
|
+
Note: The solidstats directory stores cached data and is excluded from git.
|
24
|
+
|
18
25
|
===============================================================================
|
data/lib/solidstats/engine.rb
CHANGED
@@ -25,91 +25,26 @@ module Solidstats
|
|
25
25
|
end
|
26
26
|
end
|
27
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
28
|
# Add custom paths for autoloading
|
34
29
|
initializer "solidstats.autoload_paths" do |app|
|
35
30
|
app.config.autoload_paths += Dir[Engine.root.join("app", "components", "**")]
|
36
31
|
app.config.autoload_paths += Dir[Engine.root.join("app", "services", "**")]
|
37
32
|
end
|
38
33
|
|
39
|
-
# Load custom rake tasks
|
40
|
-
rake_tasks do
|
41
|
-
load_rake_tasks
|
42
|
-
end
|
43
|
-
|
44
34
|
# Add custom generators path
|
45
35
|
config.generators do |g|
|
46
36
|
g.test_framework :minitest, spec: false, fixture: false
|
47
37
|
end
|
48
38
|
|
49
|
-
|
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}"
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
# Configure ViewComponent specific settings
|
77
|
-
# @param app [Rails::Application] Rails application instance
|
78
|
-
def configure_view_component_settings(app)
|
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"
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
# Setup preview paths for component development
|
92
|
-
# @param app [Rails::Application] Rails application instance
|
93
|
-
def setup_preview_paths(app)
|
94
|
-
return unless app.config.respond_to?(:view_component) && config.solidstats.enable_previews
|
95
|
-
|
96
|
-
preview_path = Engine.root.join("app", "components", "solidstats", "previews")
|
39
|
+
# Isolate the Solidstats engine's namespace
|
40
|
+
isolate_namespace Solidstats
|
97
41
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
end
|
42
|
+
# Set up Solidstats asset precompilation
|
43
|
+
initializer "solidstats.assets.precompile" do |app|
|
44
|
+
app.config.assets.precompile += %w[solidstats/application.css]
|
102
45
|
end
|
103
46
|
|
104
|
-
|
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
|
47
|
+
private
|
113
48
|
|
114
49
|
# Logging helpers with consistent formatting
|
115
50
|
def log_info(message)
|
data/lib/solidstats/version.rb
CHANGED
data/lib/solidstats.rb
CHANGED
@@ -1,315 +1,31 @@
|
|
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
|
|
4
|
+
# Top-level module for Solidstats gem
|
8
5
|
module Solidstats
|
9
|
-
#
|
10
|
-
|
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
|
-
class << self
|
22
|
-
# Returns the absolute path to this gem's root directory
|
23
|
-
# @return [Pathname] Gem root path
|
24
|
-
def root
|
25
|
-
@root ||= Pathname.new(File.dirname(__dir__))
|
26
|
-
end
|
27
|
-
|
28
|
-
# Returns version string
|
29
|
-
# @return [String] Version
|
30
|
-
def version
|
31
|
-
VERSION
|
32
|
-
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
|
6
|
+
# Gem setup
|
7
|
+
extend self
|
159
8
|
|
160
|
-
|
161
|
-
|
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
|
9
|
+
# Gem version
|
10
|
+
def version
|
11
|
+
VERSION
|
221
12
|
end
|
222
13
|
|
223
|
-
#
|
224
|
-
|
225
|
-
|
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
|
14
|
+
# Simple logger for internal use
|
15
|
+
def logger
|
16
|
+
@logger ||= Logger.new($stdout)
|
300
17
|
end
|
301
|
-
end
|
302
18
|
|
303
|
-
#
|
304
|
-
|
305
|
-
|
306
|
-
|
19
|
+
# Error classes for Solidstats specific exceptions
|
20
|
+
class Error < StandardError; end
|
21
|
+
class ComponentError < Error; end
|
22
|
+
class ServiceError < Error; end
|
307
23
|
|
308
|
-
#
|
309
|
-
|
310
|
-
|
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}"
|
24
|
+
# Load and initialize Solidstats in a Rails environment
|
25
|
+
def self.load!
|
26
|
+
nil unless defined?(Rails)
|
314
27
|
end
|
315
28
|
end
|
29
|
+
|
30
|
+
# Load Solidstats automatically when Rails is loaded
|
31
|
+
Solidstats.load! if defined?(Rails)
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rails/generators"
|
4
|
+
|
5
|
+
namespace :solidstats do
|
6
|
+
desc "Install Solidstats in your Rails application"
|
7
|
+
task install: :environment do
|
8
|
+
puts "🚀 Running Solidstats installer..."
|
9
|
+
Rails::Generators.invoke("solidstats:install")
|
10
|
+
end
|
11
|
+
|
12
|
+
namespace :prime do
|
13
|
+
desc "Prime data for all Solidstats services"
|
14
|
+
task all: [
|
15
|
+
:log_size,
|
16
|
+
:bundler_audit,
|
17
|
+
:todos,
|
18
|
+
:style_patrol,
|
19
|
+
:coverage,
|
20
|
+
:load_lens
|
21
|
+
] do
|
22
|
+
puts "✅ All Solidstats data has been primed."
|
23
|
+
end
|
24
|
+
|
25
|
+
desc "Prime data for LogSizeMonitorService"
|
26
|
+
task log_size: :environment do
|
27
|
+
puts "Priming data for Log Size Monitor..."
|
28
|
+
Solidstats::LogSizeMonitorService.scan_and_cache
|
29
|
+
puts "-> Log Size Monitor data primed."
|
30
|
+
end
|
31
|
+
|
32
|
+
desc "Prime data for BundlerAuditService"
|
33
|
+
task bundler_audit: :environment do
|
34
|
+
puts "Priming data for Bundler Audit..."
|
35
|
+
Solidstats::BundlerAuditService.scan_and_cache
|
36
|
+
puts "-> Bundler Audit data primed."
|
37
|
+
end
|
38
|
+
|
39
|
+
desc "Prime data for MyTodoService"
|
40
|
+
task todos: :environment do
|
41
|
+
puts "Priming data for My Todos..."
|
42
|
+
Solidstats::MyTodoService.collect_todos
|
43
|
+
puts "-> My Todos data primed."
|
44
|
+
end
|
45
|
+
|
46
|
+
desc "Prime data for StylePatrolService"
|
47
|
+
task style_patrol: :environment do
|
48
|
+
puts "Priming data for Style Patrol..."
|
49
|
+
Solidstats::StylePatrolService.refresh_cache
|
50
|
+
puts "-> Style Patrol data primed."
|
51
|
+
end
|
52
|
+
|
53
|
+
desc "Prime data for CoverageCompassService"
|
54
|
+
task coverage: :environment do
|
55
|
+
puts "Priming data for Coverage Compass..."
|
56
|
+
Solidstats::CoverageCompassService.refresh_cache
|
57
|
+
puts "-> Coverage Compass data primed."
|
58
|
+
end
|
59
|
+
|
60
|
+
desc "Prime data for LoadLensService"
|
61
|
+
task load_lens: :environment do
|
62
|
+
puts "Priming data for Load Lens..."
|
63
|
+
Solidstats::LoadLensService.scan_and_cache
|
64
|
+
puts "-> Load Lens data primed."
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,61 @@
|
|
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
|
+
end
|
@@ -1,4 +1,16 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
require "fileutils"
|
2
|
+
|
3
|
+
namespace :solidstats do
|
4
|
+
desc "Clean up all JSON files and caches generated by Solidstats"
|
5
|
+
task :clean do
|
6
|
+
solidstats_dir = Rails.root.join("solidstats")
|
7
|
+
|
8
|
+
if Dir.exist?(solidstats_dir)
|
9
|
+
puts "Removing Solidstats data directory: #{solidstats_dir}"
|
10
|
+
FileUtils.rm_rf(solidstats_dir)
|
11
|
+
puts "Solidstats data cleaned."
|
12
|
+
else
|
13
|
+
puts "Solidstats data directory not found, nothing to clean."
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|