Class: Toys::SourceInfo

Inherits:
Object
  • Object
show all
Defined in:
lib/toys/source_info.rb,
lib/toys/source_info/origin.rb

Overview

Information about the source of a tool, such as the file, git repository, or block that defined it.

This object represents a source of tool information and definitions. Such a source could include:

  • A toys directory
  • A single toys file
  • A file or directory loaded from git
  • A file or directory loaded from a gem
  • A block passed directly to the CLI
  • A tool block within a toys file
  • A subclass of Toys::Tool

The SourceInfo provides information such as the tool's context directory, and locates data and lib directories appropriate to the tool. It also locates the tool's source code so it can be reported when an error occurs.

Each tool has a unique SourceInfo with all the information specific to that tool. Additionally, SourceInfo objects are arranged in a containment hierarchy. For example, a SourceInfo object representing a toys files could have a parent representing a toys directory, and an object representing a tool block could have a parent representing an enclosing block or a file.

Child SourceInfo objects generally inherit some attributes of their parent. For example, the .toys directory in a project directory defines the context directory as that project directory. Then all tools defined under that directory will share that context directory, so all SourceInfo objects descending from that root will inherit that value (unless it's changed explicitly).

SourceInfo objects can be obtained in the DSL from DSL::Tool#source_info or at runtime by getting the Context::Key::TOOL_SOURCE key. They are created internally during CLI configuration and during loading.

Defined Under Namespace

Modules: Origin

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#context_directoryString? (readonly)

The context directory path set by this source or inherited from its parent. Sometimes this is the directory containing the toplevel toys file/directory, for example for the toys gem directory search that uses the CLI add_search* methods. But other source types typically leave this unset (nil).

This is not affected by setting a custom context directory for a tool.

Returns:

  • (String)

    The context directory path.

  • (nil)

    if there is no context directory



95
96
97
# File 'lib/toys/source_info.rb', line 95

def context_directory
  @context_directory
end

#originToys::SourceInfo::Origin::Base (readonly)

The origin of this source, describing where its content came from: the local file system, a git repository, a Ruby gem, or a block of code.

An origin is fixed when a source spec is resolved. A source created by descending from another, whether by walking a directory or by entering a block or a subclass, shares its parent origin object.

Origins are one of the following types:



168
169
170
# File 'lib/toys/source_info.rb', line 168

def origin
  @origin
end

#parentToys::SourceInfo? (readonly)

The parent of this SourceInfo.

Returns:



65
66
67
# File 'lib/toys/source_info.rb', line 65

def parent
  @parent
end

#priorityInteger (readonly)

The priority of tools defined by this source. Higher values indicate a higher priority. Lower priority values could be negative.

Returns:

  • (Integer)

    The priority.



81
82
83
# File 'lib/toys/source_info.rb', line 81

def priority
  @priority
end

#rootToys::SourceInfo (readonly)

The root ancestor of this SourceInfo. This generally represents a source that was added directly to a CLI in code.

Returns:



73
74
75
# File 'lib/toys/source_info.rb', line 73

def root
  @root
end

#sourceString, ... (readonly)

The source, which may be a path, a proc, or a class, depending on the #source_type.

Returns:

  • (String)

    Path to the source file or directory.

  • (Proc)

    The block serving as the source.

  • (Class)

    The Tool subclass serving as the source.



105
106
107
# File 'lib/toys/source_info.rb', line 105

def source
  @source
end

#source_nameString (readonly) Also known as: to_s

A user-visible name of this source.

Returns:

  • (String)


175
176
177
# File 'lib/toys/source_info.rb', line 175

def source_name
  @source_name
end

#source_pathString? (readonly)

The path of the current source file or directory.

This could be set even if #source_type is :proc, if that proc is defined within a toys file. The only time this is not set is if the source is added directly to a CLI in a code block.

Returns:

  • (String)

    The source path

  • (nil)

    if this source has no file system path.



134
135
136
# File 'lib/toys/source_info.rb', line 134

def source_path
  @source_path
end

#source_procProc? (readonly)

The source proc. This is set if #source_type is :proc.

Returns:

  • (Proc)

    The source proc

  • (nil)

    if this source has no proc.



142
143
144
# File 'lib/toys/source_info.rb', line 142

def source_proc
  @source_proc
end

#source_subclassClass? (readonly)

The source subclass. This is set if #source_type is :subclass.

Returns:

  • (Class)

    The source subclass

  • (nil)

    if this source is not a subclass.



150
151
152
# File 'lib/toys/source_info.rb', line 150

def source_subclass
  @source_subclass
end

#source_type:file, ... (readonly)

The type of source. This could be:

  • :file, representing a single toys file. The #source will be the filesystem path to that file.
  • :directory, representing a toys directory. The #source will be the filesystem path to that directory.
  • :proc, representing a proc, which could be a toplevel block added directly to a CLI, a tool block within a toys file, or a block within another block. The #source will be the proc itself.
  • :subclass, representing a subclass of Tool. The #source will be the class object.

Returns:

  • (:file, :directory, :proc, :subclass)


122
123
124
# File 'lib/toys/source_info.rb', line 122

def source_type
  @source_type
end

Instance Method Details

#find_data(path, type: nil) ⇒ String?

Locate the given data file or directory and return an absolute path.

Parameters:

  • path (String)

    The relative path to find

  • type (nil, :file, :directory) (defaults to: nil)

    Type of file system object to find, or nil (the default) to return any type.

Returns:

  • (String)

    Absolute path of the resulting data.

  • (nil)

    if the data was not found.



187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/toys/source_info.rb', line 187

def find_data(path, type: nil)
  if @source_type == :directory
    data_dir = ::File.join(@source_path, DATA_DIR_NAME)
    if ::File.directory?(data_dir) && ::File.readable?(data_dir)
      full_path = ::File.join(data_dir, path)
      case type
      when :file
        return full_path if ::File.file?(full_path)
      when :directory
        return full_path if ::File.directory?(full_path)
      else
        return full_path if ::File.readable?(full_path)
      end
    end
  end
  parent&.find_data(path, type: type)
end

#find_lib_pathsArray<String>

Find lib paths in this source and all ancestors, in order from most to least significant.

Returns:

  • (Array<String>)

    Directory paths in order



211
212
213
214
215
216
217
218
219
# File 'lib/toys/source_info.rb', line 211

def find_lib_paths
  results = []
  if @source_type == :directory
    lib_dir = ::File.join(@source_path, LIB_DIR_NAME)
    results << lib_dir if ::File.directory?(lib_dir) && ::File.readable?(lib_dir)
  end
  results += parent.find_lib_paths if parent
  results
end

#find_preload_filesArray<String>

Find all files to preload in this source only, not including ancestors.

Returns:

  • (Array<String>)

    File paths in order



226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
# File 'lib/toys/source_info.rb', line 226

def find_preload_files
  results = []
  if @source_type == :directory
    preload_file = ::File.join(@source_path, PRELOAD_FILE_NAME)
    results << preload_file if ::File.file?(preload_file) && ::File.readable?(preload_file)
    preload_dir = ::File.join(@source_path, PRELOAD_DIR_NAME)
    if ::File.directory?(preload_dir) && ::File.readable?(preload_dir)
      ::Dir.entries(preload_dir).sort.each do |child|
        next unless ::File.extname(child) == ".rb"
        preload_file = ::File.join(preload_dir, child)
        results << preload_file if ::File.file?(preload_file) && ::File.readable?(preload_file)
      end
    end
  end
  results
end