Class: SupportTableData::Documentation::RbsFile

Inherits:
Object
  • Object
show all
Defined in:
lib/support_table_data/documentation/rbs_file.rb

Overview

Manages reading/writing the per-model RBS signature file.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(klass, source_path) ⇒ RbsFile

Returns a new instance of RbsFile.

Parameters:

  • klass (Class)

    The model class

  • source_path (Pathname)

    The path to the model’s source ‘.rb` file



13
14
15
16
17
# File 'lib/support_table_data/documentation/rbs_file.rb', line 13

def initialize(klass, source_path)
  @klass = klass
  @source_path = Pathname.new(source_path)
  @path = self.class.signatures_path_for(@source_path)
end

Instance Attribute Details

#klassObject (readonly)

Returns the value of attribute klass.



9
10
11
# File 'lib/support_table_data/documentation/rbs_file.rb', line 9

def klass
  @klass
end

#pathObject (readonly)

Returns the value of attribute path.



9
10
11
# File 'lib/support_table_data/documentation/rbs_file.rb', line 9

def path
  @path
end

#source_pathObject (readonly)

Returns the value of attribute source_path.



9
10
11
# File 'lib/support_table_data/documentation/rbs_file.rb', line 9

def source_path
  @source_path
end

Class Method Details

.project_root_for(source_path) ⇒ Object

Project root is the nearest ancestor directory containing a Gemfile or a .git directory. Falls back to the source file’s directory.



41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/support_table_data/documentation/rbs_file.rb', line 41

def self.project_root_for(source_path)
  current = Pathname.new(source_path).expand_path.parent
  loop do
    return current if current.join("Gemfile").file?
    return current if current.join(".git").exist?

    parent = current.parent
    return Pathname.new(source_path).expand_path.parent if parent == current

    current = parent
  end
end

.relative_to_project_root(source_path) ⇒ Object



54
55
56
# File 'lib/support_table_data/documentation/rbs_file.rb', line 54

def self.relative_to_project_root(source_path)
  Pathname.new(source_path).expand_path.relative_path_from(project_root_for(source_path))
end

.signatures_path_for(source_path) ⇒ Pathname

Compute where the RBS signatures should live for a given source file. Defaults to ‘<project_root>/sig/<source_path_minus_extension>.rbs`. The project root is found by walking upward looking for a `Gemfile` or `.git` directory; if neither is found, the immediate parent of the source file is used.

Parameters:

  • source_path (Pathname)

Returns:

  • (Pathname)


27
28
29
30
31
32
33
34
35
36
37
# File 'lib/support_table_data/documentation/rbs_file.rb', line 27

def self.signatures_path_for(source_path)
  if SupportTableData.rbs_signatures_path
    base = Pathname.new(SupportTableData.rbs_signatures_path)
    relative = relative_to_project_root(source_path)
    return base.join("#{relative.to_s.sub(/\.rb\z/, "")}.rbs")
  end

  root = project_root_for(source_path)
  relative = source_path.expand_path.relative_path_from(root)
  root.join("sig", "#{relative.to_s.sub(/\.rb\z/, "")}.rbs")
end

Instance Method Details

#remove!Boolean

Delete the generated RBS file if it exists. Returns true if a file was removed.

Returns:

  • (Boolean)


96
97
98
99
100
101
# File 'lib/support_table_data/documentation/rbs_file.rb', line 96

def remove!
  return false unless path.file?

  path.delete
  true
end

#signatures_contentString?

Render the desired RBS content for this model, or nil if the model has no named instances (in which case no file should be written).

Returns:

  • (String, nil)


62
63
64
# File 'lib/support_table_data/documentation/rbs_file.rb', line 62

def signatures_content
  RbsDoc.new(klass).signatures
end

#up_to_date?Boolean

Whether the existing on-disk file matches what would be generated.

Returns:

  • (Boolean)


69
70
71
72
73
74
75
76
# File 'lib/support_table_data/documentation/rbs_file.rb', line 69

def up_to_date?
  desired = signatures_content
  if desired.nil?
    !path.file?
  else
    path.file? && path.read == desired
  end
end

#write!Boolean

Write the generated RBS content to disk, creating parent directories as needed. Returns true if the file was written, false if there was nothing to write.

Returns:

  • (Boolean)


83
84
85
86
87
88
89
90
# File 'lib/support_table_data/documentation/rbs_file.rb', line 83

def write!
  content = signatures_content
  return false if content.nil?

  path.parent.mkpath
  path.write(content)
  true
end