Class: GemOverrideMarker::Marker

Inherits:
Object
  • Object
show all
Defined in:
lib/gem_override_marker/marker.rb

Overview

@gem-override マーカー1行を解析した結果を表す値オブジェクト。

gem のメソッドを prepend で丸ごと再実装したり、gem の view / partial を コピーして丸ごと上書きしている箇所に、本家のどこを基準にしているかを 宣言するためのマーカー。decorator メソッドの直前 / 上書きファイルの冒頭に置く。

@gem-override {gem名}-{バージョン}/{gem内パス}#{メソッド名}

例:

@gem-override spree_core-5.1.6/app/models/spree/stock/packer.rb#default_package
@gem-override spree_storefront-5.1.6/app/views/spree/products/_cart_form.html.erb
@gem-override devise-4.9.4/app/controllers/devise/sessions_controller.rb#create

メソッド名 (#method) は省略可能で、省略時は対象ファイル全体を比較する (view / partial の丸ごと上書きを想定)。

Constant Summary collapse

PATTERN =

マーカーは「コメント記号 + 半角スペース1個ちょうど + @gem-override」で始まる 行だけを有効とする。これにより、ドキュメント中で字下げして例示したもの (# @gem-override ... のようにスペースが2個以上) や、文中にバッククォート等で 引用したものを本物のマーカーと誤検出しない。

対応するコメント記号: Ruby (#) / ERB (<%#) / Slim・Haml (/)。

gem 名はバージョンの直前のハイフンで区切る。gem 名側にハイフンや数字が 含まれていてもバージョン部分を正しく切り出せるよう、gem 名は最短一致とし 「数字始まりのトークン」をバージョンの開始位置とみなす。 各部の意味 (上から順に):

\A[ \t]*      行頭の字下げ。メソッドの階層に応じた任意のインデント
(?:\#|<%\#|\/) コメント記号。Ruby / ERB / Slim・Haml
[ ]           半角スペース1個ちょうど。これで字下げ例を弾く
@gem-override[ ] マーカー本体と区切りスペース1個
gem           gem 名。最短一致でバージョン直前まで
version       バージョン。数字始まり
path          gem 内の相対パス
method        メソッド名。省略可
/
  \A[ \t]*
  (?:\#|<%\#|\/)
  [ ]
  @gem-override[ ]
  (?<gem>[a-z0-9_]+?)-
  (?<version>\d[\w.\-]*)
  \/
  (?<path>[^\s\#]+)
  (?:\#(?<method>\w+[!?=]?))?
  (?:[ ]|%>|$)
/x

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(gem_name:, version:, path:, method_name: nil, file_path: nil, line_number: nil) ⇒ Marker

Returns a new instance of Marker.



68
69
70
71
72
73
74
75
# File 'lib/gem_override_marker/marker.rb', line 68

def initialize(gem_name:, version:, path:, method_name: nil, file_path: nil, line_number: nil)
  @gem_name = gem_name
  @version = version
  @path = path
  @method_name = method_name
  @file_path = file_path
  @line_number = line_number
end

Instance Attribute Details

#file_pathObject (readonly)

Returns the value of attribute file_path.



50
51
52
# File 'lib/gem_override_marker/marker.rb', line 50

def file_path
  @file_path
end

#gem_nameObject (readonly)

Returns the value of attribute gem_name.



50
51
52
# File 'lib/gem_override_marker/marker.rb', line 50

def gem_name
  @gem_name
end

#line_numberObject (readonly)

Returns the value of attribute line_number.



50
51
52
# File 'lib/gem_override_marker/marker.rb', line 50

def line_number
  @line_number
end

#method_nameObject (readonly)

Returns the value of attribute method_name.



50
51
52
# File 'lib/gem_override_marker/marker.rb', line 50

def method_name
  @method_name
end

#pathObject (readonly)

Returns the value of attribute path.



50
51
52
# File 'lib/gem_override_marker/marker.rb', line 50

def path
  @path
end

#versionObject (readonly)

Returns the value of attribute version.



50
51
52
# File 'lib/gem_override_marker/marker.rb', line 50

def version
  @version
end

Class Method Details

.parse(line, file_path: nil, line_number: nil) ⇒ Object

マーカーを含む1行を解析する。マーカーでなければ nil を返す。 file_path / line_number はマーカーが書かれた場所 (リポジトリ側) を記録する。



54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/gem_override_marker/marker.rb', line 54

def self.parse(line, file_path: nil, line_number: nil)
  match = PATTERN.match(line)
  return nil unless match

  new(
    gem_name: match[:gem],
    version: match[:version],
    path: match[:path],
    method_name: match[:method],
    file_path: file_path,
    line_number: line_number
  )
end

Instance Method Details

#logical_nameObject

マーカーが指す本家論理名 (狙い撃ち指定にそのまま使える1行表現)。



83
84
85
86
# File 'lib/gem_override_marker/marker.rb', line 83

def logical_name
  base = "#{gem_name}-#{version}/#{path}"
  whole_file? ? base : "#{base}##{method_name}"
end

#whole_file?Boolean

メソッド名を含まない = ファイル全体を対象とするマーカーか。

Returns:

  • (Boolean)


78
79
80
# File 'lib/gem_override_marker/marker.rb', line 78

def whole_file?
  method_name.nil?
end