Class: MaquinaComponents::Doctor
- Inherits:
-
Object
- Object
- MaquinaComponents::Doctor
- Defined in:
- lib/maquina_components/doctor.rb
Overview
Migration scanner behind rake maquina:doctor.
Run inside a consuming app, it looks for the app's own CSS/view/JS patterns that 0.6.0 makes redundant or outright breaks, and prints file:line plus a suggested replacement for each. Advisory only: it never edits anything and never fails a build.
Plain Ruby on purpose - no Rails, no extra gems - so it can also be run against a directory from the engine's own repo.
Defined Under Namespace
Classes: Finding
Constant Summary collapse
- SEVERITIES =
{ breaking: "BREAKING - stops working in 0.6.0", review: "REVIEW - still works, but 0.6.0 gives you a token for it", cleanup: "CLEANUP - probably unnecessary in 0.6.0" }.freeze
- CSS_GLOBS =
[ "app/assets/stylesheets/**/*.css", "app/assets/tailwind/**/*.css", "app/assets/**/*.css", "app/javascript/**/*.css", "app/views/**/*.css" ].freeze
- VIEW_GLOBS =
[ "app/views/**/*.erb", "app/views/**/*.html", "app/components/**/*.erb", "app/helpers/**/*.rb" ].freeze
- JS_GLOBS =
[ "app/javascript/**/*.js" ].freeze
- EXCLUDED =
%r{/(node_modules|tmp|vendor|coverage)/|/app/assets/builds/}- COMPONENT_SELECTOR =
A component-owned selector: data-component or any data-*-part hook.
/\[data-(?:component|[a-z]+(?:-[a-z]+)*-part)\s*[~|^$*]?=/- UNIVERSAL_SELECTOR =
A rule whose every selector is the universal one, e.g.
*or*, ::before, ::after— the shape of a Tailwind-v3-style preflight shim. /\A\*(\s*,\s*(\*|::?[a-z-]+))*\z/- PRESENCE_ACTIVE =
/\[data-active\](?!\s*[~|^$*]?=)/- TAILWIND_ACTIVE_VARIANT =
/data-\[active\]/- SVG_DATA_URI =
/data:image\/svg\+xml/- MARK_TOKEN_ASSIGNMENT =
Assigning a data URI to one of the five mark properties IS the 0.6.0 pattern, so it must not be reported as a restated rule.
/--(?:checkbox-mark|checkbox-indeterminate|radio-mark|switch-thumb|select-chevron)-image\s*:/- RADIUS_DECL =
/(?:border-radius\s*:|@apply[^;{}]*\brounded(?:-[a-z0-9\[\].\/-]+)?\b)/- SHADOW_DECL =
/(?:box-shadow\s*:|@apply[^;{}]*\b(?:shadow|ring)(?:-[a-z0-9\[\].\/-]+)?\b)/- FOCUS_SELECTOR =
/:focus(-visible|-within)?\b/
Instance Attribute Summary collapse
-
#findings ⇒ Object
readonly
Returns the value of attribute findings.
-
#root ⇒ Object
readonly
Returns the value of attribute root.
-
#scanned_files ⇒ Object
readonly
Returns the value of attribute scanned_files.
Instance Method Summary collapse
- #findings_for(severity) ⇒ Object
-
#initialize(root) ⇒ Doctor
constructor
A new instance of Doctor.
- #report ⇒ Object
- #run ⇒ Object
Constructor Details
Instance Attribute Details
#findings ⇒ Object (readonly)
Returns the value of attribute findings.
58 59 60 |
# File 'lib/maquina_components/doctor.rb', line 58 def findings @findings end |
#root ⇒ Object (readonly)
Returns the value of attribute root.
58 59 60 |
# File 'lib/maquina_components/doctor.rb', line 58 def root @root end |
#scanned_files ⇒ Object (readonly)
Returns the value of attribute scanned_files.
58 59 60 |
# File 'lib/maquina_components/doctor.rb', line 58 def scanned_files @scanned_files end |
Instance Method Details
#findings_for(severity) ⇒ Object
73 74 75 |
# File 'lib/maquina_components/doctor.rb', line 73 def findings_for(severity) findings.select { |finding| finding.severity == severity } end |
#report ⇒ Object
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/maquina_components/doctor.rb', line 77 def report out = [] out << "maquina_components doctor" out << "Scanned #{scanned_files} file#{"s" unless scanned_files == 1} under #{root}" out << "" if findings.empty? out << "No at-risk patterns found. Nothing to migrate for 0.6.0." out << "" return out.join("\n") end SEVERITIES.each do |severity, heading| group = findings_for(severity) next if group.empty? out << "#{heading} (#{group.size})" out << "-" * 72 group.each do |finding| out << " #{relative(finding.path)}:#{finding.line} [#{finding.rule}]" out << " #{finding.source}" finding.suggestion.each_line { |line| out << " -> #{line.chomp}" } out << "" end end out << "Summary: " + SEVERITIES.keys.map { |s| "#{findings_for(s).size} #{s}" }.join(", ") out << "Advisory only - nothing was changed. See the 0.6.0 upgrade notes for the full token list." out << "" out.join("\n") end |
#run ⇒ Object
66 67 68 69 70 71 |
# File 'lib/maquina_components/doctor.rb', line 66 def run each_file(CSS_GLOBS) { |path| scan_css(path) } each_file(VIEW_GLOBS) { |path| scan_markup(path) } each_file(JS_GLOBS) { |path| scan_markup(path) } self end |