mootool 0.1.2 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.DS_Store +0 -0
- data/.github/workflows/ci.yml +15 -15
- data/.github/workflows/gem-push.yml +26 -26
- data/.overcommit.yml +79 -0
- data/.rubocop.yml +147 -0
- data/.ruby-version +1 -1
- data/.run/All Specs.run.xml +46 -0
- data/CODE_OF_CONDUCT.md +2 -1
- data/Gemfile +14 -11
- data/Gemfile.lock +90 -32
- data/README.md +12 -6
- data/bin/tapioca +27 -0
- data/lib/mootool/command.rb +1 -0
- data/lib/mootool/controller_base.rb +4 -1
- data/lib/mootool/controllers/dwarf.rb +8 -0
- data/lib/mootool/controllers/dyld_linker.rb +8 -0
- data/lib/mootool/controllers/dyld_shared_cache.rb +8 -0
- data/lib/mootool/controllers/fat_binary.rb +8 -0
- data/lib/mootool/controllers/kernel_collection.rb +21 -15
- data/lib/mootool/controllers/sections.rb +8 -0
- data/lib/mootool/core_extensions.rb +26 -0
- data/lib/mootool/models/device_tree.rb +85 -0
- data/lib/mootool/models/img4.rb +49 -0
- data/lib/mootool/models/ipsw.rb +19 -0
- data/lib/mootool/version.rb +1 -1
- data/lib/mootool/views/sections.full.erb +2 -2
- data/lib/mootool.rb +10 -3
- data/mootool.gemspec +17 -12
- data/sorbet/rbi/annotations/rainbow.rbi +269 -0
- data/sorbet/rbi/gems/ast@2.4.2.rbi +618 -0
- data/sorbet/rbi/gems/childprocess@4.1.0.rbi +447 -0
- data/sorbet/rbi/gems/coderay@1.1.3.rbi +8 -0
- data/sorbet/rbi/gems/diff-lcs@1.5.0.rbi +1219 -0
- data/sorbet/rbi/gems/iniparse@1.5.0.rbi +1007 -0
- data/sorbet/rbi/gems/json@2.6.2.rbi +1650 -0
- data/sorbet/rbi/gems/method_source@1.0.0.rbi +8 -0
- data/sorbet/rbi/gems/netrc@0.11.0.rbi +186 -0
- data/sorbet/rbi/gems/overcommit@0.59.1.rbi +2747 -0
- data/sorbet/rbi/gems/parallel@1.22.1.rbi +353 -0
- data/sorbet/rbi/gems/parser@3.1.2.1.rbi +6198 -0
- data/sorbet/rbi/gems/plist@3.6.0.rbi +212 -0
- data/sorbet/rbi/gems/pry@0.14.1.rbi +8 -0
- data/sorbet/rbi/gems/rainbow@3.1.1.rbi +452 -0
- data/sorbet/rbi/gems/rake@13.0.6.rbi +3587 -0
- data/sorbet/rbi/gems/rbi@0.0.15.rbi +3619 -0
- data/sorbet/rbi/gems/regexp_parser@2.5.0.rbi +3927 -0
- data/sorbet/rbi/gems/rexml@3.2.5.rbi +5238 -0
- data/sorbet/rbi/gems/rspec-core@3.11.0.rbi +12834 -0
- data/sorbet/rbi/gems/rspec-expectations@3.11.0.rbi +9151 -0
- data/sorbet/rbi/gems/rspec-mocks@3.11.1.rbi +6506 -0
- data/sorbet/rbi/gems/rspec-support@3.11.0.rbi +2040 -0
- data/sorbet/rbi/gems/rspec@3.11.0.rbi +120 -0
- data/sorbet/rbi/gems/rubocop-ast@1.21.0.rbi +7990 -0
- data/sorbet/rbi/gems/rubocop-rake@0.6.0.rbi +413 -0
- data/sorbet/rbi/gems/rubocop-rspec@2.12.1.rbi +7604 -0
- data/sorbet/rbi/gems/rubocop@1.35.0.rbi +62260 -0
- data/sorbet/rbi/gems/ruby-macho@3.0.0.rbi +5039 -0
- data/sorbet/rbi/gems/ruby-progressbar@1.11.0.rbi +1445 -0
- data/sorbet/rbi/gems/rubyzip@2.3.2.rbi +2868 -0
- data/sorbet/rbi/gems/spoom@1.1.12.rbi +2829 -0
- data/sorbet/rbi/gems/tapioca@0.9.3.rbi +2151 -0
- data/sorbet/rbi/gems/thor@1.2.1.rbi +4532 -0
- data/sorbet/rbi/gems/unicode-display_width@2.2.0.rbi +60 -0
- data/sorbet/rbi/gems/unparser@0.6.5.rbi +8 -0
- data/sorbet/rbi/gems/webrick@1.7.0.rbi +3075 -0
- data/sorbet/rbi/gems/yard-sorbet@0.6.1.rbi +458 -0
- data/sorbet/rbi/gems/yard@0.9.28.rbi +20844 -0
- data/sorbet/rbi/sorbet-typed/lib/rainbow/all/rainbow.rbi +72 -24
- data/sorbet/rbi/sorbet-typed/lib/rake/all/rake.rbi +1697 -385
- data/sorbet/rbi/sorbet-typed/lib/rspec-core/all/rspec-core.rbi +30 -7
- data/sorbet/rbi/sorbet-typed/lib/rubocop/>=1.8/rubocop.rbi +3 -1
- data/sorbet/rbi/todo.rbi +7 -0
- data/sorbet/tapioca/config.yml +13 -0
- data/sorbet/tapioca/require.rb +4 -0
- metadata +90 -10
data/lib/mootool/command.rb
CHANGED
@@ -3,7 +3,10 @@
|
|
3
3
|
CONTROLLERS_PATH = File.join(File.dirname(__FILE__), 'controllers')
|
4
4
|
|
5
5
|
module MooTool
|
6
|
+
# Controller base is the base class for all controllers that respond to command line requests.
|
6
7
|
class ControllerBase
|
8
|
+
@controllers = []
|
9
|
+
|
7
10
|
def self.load_all
|
8
11
|
Dir.glob(File.join(CONTROLLERS_PATH, '*')).each do |file|
|
9
12
|
require file
|
@@ -15,8 +18,8 @@ module MooTool
|
|
15
18
|
end
|
16
19
|
|
17
20
|
def self.inherited(child)
|
18
|
-
@@controllers ||= []
|
19
21
|
@@controllers << child
|
22
|
+
super
|
20
23
|
end
|
21
24
|
|
22
25
|
class << self
|
@@ -1,24 +1,30 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module MooTool
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
module Controllers
|
5
|
+
# Controller for extracting or viewing a KernelCollection (.kc file)
|
6
|
+
class KernelCollection < ControllerBase
|
7
|
+
command 'kc'
|
8
|
+
description 'Kernel Collections'
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
-
|
10
|
+
def extract(command, output_folder)
|
11
|
+
file = MachO.open command.file
|
12
|
+
input = File.open(command.file, 'rb')
|
11
13
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
file.command(:LC_FILESET_ENTRY).each do |entry|
|
15
|
+
output_path = File.join(output_folder, entry.entry_id.to_s)
|
16
|
+
puts "Writing to #{output_path}"
|
17
|
+
output_file = File.open(output_path, 'wb')
|
18
|
+
# rubocop:disable Naming/VariableNumber
|
19
|
+
# We do not have control of this name as it is part of ruby-macho
|
20
|
+
matching = file.command(:LC_SEGMENT_64).find { |c| c.fileoff == entry.fileoff }
|
21
|
+
# rubocop:enable Naming/VariableNumber
|
17
22
|
|
18
|
-
|
19
|
-
|
20
|
-
|
23
|
+
input.seek(matching.fileoff)
|
24
|
+
output_file.write input.read(matching.filesize)
|
25
|
+
output_file.close
|
26
|
+
end
|
21
27
|
end
|
22
28
|
end
|
23
29
|
end
|
24
|
-
end
|
30
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: true
|
3
|
+
|
4
|
+
# rubocop:disable Style/Documentation
|
5
|
+
|
6
|
+
class Integer
|
7
|
+
# rubocop:enable Style/Documentation
|
8
|
+
extend T::Sig
|
9
|
+
# Aligns the integer to the nearest multiple of the alignment.
|
10
|
+
# @param alignment [Integer] the alignment
|
11
|
+
# @return [Integer] the aligned integer
|
12
|
+
sig { params(alignment: T.nilable(Integer)).returns(Integer) }
|
13
|
+
def align(alignment = nil)
|
14
|
+
alignment ||= Integer.size
|
15
|
+
|
16
|
+
return self if alignment < 2
|
17
|
+
|
18
|
+
alignment -= 1
|
19
|
+
|
20
|
+
if (self & alignment).zero?
|
21
|
+
self
|
22
|
+
else
|
23
|
+
(self | alignment) + 1
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# typed: true
|
3
|
+
|
4
|
+
require 'sorbet-runtime'
|
5
|
+
|
6
|
+
module MooTool
|
7
|
+
module Models
|
8
|
+
# DeviceTree is a Apple Device Tree node that has been parsed
|
9
|
+
class DeviceTree
|
10
|
+
extend T::Sig
|
11
|
+
|
12
|
+
NODE_FORMAT = 'VV'
|
13
|
+
PROP_FORMAT = 'A32V'
|
14
|
+
|
15
|
+
# Represents a single node in the device tree
|
16
|
+
class Node
|
17
|
+
extend T::Sig
|
18
|
+
|
19
|
+
attr_reader :children, :properties
|
20
|
+
|
21
|
+
sig { params(data: T.any(IO, StringIO)).void }
|
22
|
+
def initialize(data)
|
23
|
+
vals = T.must(data.read(8)).unpack(NODE_FORMAT)
|
24
|
+
property_count = T.cast(vals[0], Integer)
|
25
|
+
child_count = T.cast(vals[1], Integer)
|
26
|
+
|
27
|
+
@properties = T.let({}, T::Hash[String, Property])
|
28
|
+
@children = T.let([], T::Array[Node])
|
29
|
+
|
30
|
+
property_count.times do
|
31
|
+
prop = Property.new(data)
|
32
|
+
@properties[prop.name] = prop
|
33
|
+
end
|
34
|
+
child_count.times { @children << Node.new(data) }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Represents a single property and it's value
|
39
|
+
class Property
|
40
|
+
extend T::Sig
|
41
|
+
|
42
|
+
attr_accessor :name, :value
|
43
|
+
|
44
|
+
sig { params(data: T.any(StringIO, IO)).void }
|
45
|
+
def initialize(data)
|
46
|
+
args = T.must(data.read(36)).unpack(PROP_FORMAT)
|
47
|
+
|
48
|
+
@name = T.let(T.cast(args[0], String), String)
|
49
|
+
@size = T.let(T.cast(args[1], Integer), Integer)
|
50
|
+
|
51
|
+
if @size & 0x80000000 != 0
|
52
|
+
@template = true
|
53
|
+
@size &= 0x7fffffff
|
54
|
+
end
|
55
|
+
|
56
|
+
@value = data.read(@size.align(4))
|
57
|
+
@value = T.must(@value)[0..@size]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
attr_reader :root
|
62
|
+
|
63
|
+
# @param [String] data
|
64
|
+
sig { params(data: T.any(IO, String, StringIO, Pathname)).void }
|
65
|
+
def initialize(data)
|
66
|
+
case data
|
67
|
+
when Pathname
|
68
|
+
data = T.assert_type!(data, Pathname)
|
69
|
+
@data = File.open(data.realpath, 'rb')
|
70
|
+
when String
|
71
|
+
data = T.assert_type!(data, String)
|
72
|
+
@data = StringIO.new(data)
|
73
|
+
when IO
|
74
|
+
@data = T.cast(data, IO)
|
75
|
+
end
|
76
|
+
@root = Node.new(@data)
|
77
|
+
end
|
78
|
+
|
79
|
+
sig { params(path: String).returns(DeviceTree) }
|
80
|
+
def self.open(path)
|
81
|
+
DeviceTree.new(Pathname.new(path))
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'openssl'
|
4
|
+
|
5
|
+
module MooTool
|
6
|
+
# Module for Apple's IMG4 encryption and signing format
|
7
|
+
module Img4
|
8
|
+
# An instance of a IMG4 file
|
9
|
+
class File
|
10
|
+
attr_reader :payload, :manifest
|
11
|
+
|
12
|
+
def initialize(path)
|
13
|
+
@path = path
|
14
|
+
der = ::File.binread(path)
|
15
|
+
@data = OpenSSL::ASN1.decode(der)
|
16
|
+
|
17
|
+
case @data.first.value
|
18
|
+
when 'IM4P'
|
19
|
+
@type = @data.value[1].value
|
20
|
+
@build = @data.value[2].value
|
21
|
+
@payload = @data.value[3].value
|
22
|
+
when 'IMG4', 'IM4M'
|
23
|
+
raise 'Not implemented'
|
24
|
+
else
|
25
|
+
raise "Unknown IMG4 type #{@data.first.value}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def payload?
|
30
|
+
!@payload.nil?
|
31
|
+
end
|
32
|
+
|
33
|
+
def manifest?
|
34
|
+
!@manifest.nil?
|
35
|
+
end
|
36
|
+
|
37
|
+
def basename
|
38
|
+
basename = ::File.basename(@path)
|
39
|
+
extension = ::File.extname(basename)
|
40
|
+
"#{basename.chomp(extension)}.#{@type}"
|
41
|
+
end
|
42
|
+
|
43
|
+
def extract_payload
|
44
|
+
output_path = ::File.join(::File.dirname(@path), basename)
|
45
|
+
::File.write(output_path, @payload)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'zip'
|
4
|
+
require 'plist'
|
5
|
+
|
6
|
+
module MooTool
|
7
|
+
# Represents a single IPSW package
|
8
|
+
class IPSW
|
9
|
+
def initialize(file)
|
10
|
+
@file = file
|
11
|
+
@zip = Zip::File.open(file)
|
12
|
+
manifest = @zip.find_entry('BuildManifest.plist')
|
13
|
+
|
14
|
+
raise 'Invalid IPSW, does not contain BuildManifest.plist' unless manifest
|
15
|
+
|
16
|
+
@manifest = Plist.parse_xml(manifest.get_input_stream.read)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/mootool/version.rb
CHANGED
data/lib/mootool.rb
CHANGED
@@ -1,14 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
require 'bundler/setup'
|
3
|
+
require_relative 'mootool/version'
|
6
4
|
|
7
5
|
require 'macho'
|
6
|
+
require 'zip'
|
7
|
+
|
8
|
+
require_relative 'mootool/core_extensions'
|
8
9
|
|
10
|
+
# MooTool
|
9
11
|
module MooTool
|
10
12
|
class Error < StandardError; end
|
13
|
+
|
11
14
|
# Your code goes here...
|
12
15
|
autoload :Command, 'mootool/command'
|
13
16
|
autoload :ControllerBase, 'mootool/controller_base'
|
17
|
+
|
18
|
+
autoload :Img4, 'mootool/models/img4'
|
19
|
+
autoload :DeviceTree, 'mootool/models/device_tree'
|
20
|
+
autoload :IPSW, 'mootool/models/ipsw'
|
14
21
|
end
|
data/mootool.gemspec
CHANGED
@@ -5,15 +5,17 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
5
5
|
require 'mootool/version'
|
6
6
|
|
7
7
|
Gem::Specification.new do |spec|
|
8
|
-
spec.name
|
9
|
-
spec.version
|
10
|
-
spec.authors
|
11
|
-
spec.email
|
8
|
+
spec.name = 'mootool'
|
9
|
+
spec.version = MooTool::VERSION
|
10
|
+
spec.authors = ['Rick Mark']
|
11
|
+
spec.email = ['rickmark@outlook.com']
|
12
12
|
|
13
|
-
spec.summary
|
14
|
-
spec.description
|
15
|
-
spec.homepage
|
16
|
-
spec.license
|
13
|
+
spec.summary = "Mach-O's Other Tool"
|
14
|
+
spec.description = 'mootool is a swiss army knife for dealing with Apple Mach-O files'
|
15
|
+
spec.homepage = 'https://github.com/hack-different/mootool'
|
16
|
+
spec.license = 'MIT'
|
17
|
+
|
18
|
+
spec.required_ruby_version = '>= 3.0'
|
17
19
|
|
18
20
|
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
19
21
|
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
@@ -23,7 +25,7 @@ Gem::Specification.new do |spec|
|
|
23
25
|
spec.metadata['changelog_uri'] = 'https://github.com/hack-different/mootool'
|
24
26
|
else
|
25
27
|
raise 'RubyGems 2.0 or newer is required to protect against ' \
|
26
|
-
|
28
|
+
'public gem pushes.'
|
27
29
|
end
|
28
30
|
|
29
31
|
# Specify which files should be added to the gem when it is released.
|
@@ -31,10 +33,13 @@ Gem::Specification.new do |spec|
|
|
31
33
|
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
32
34
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
33
35
|
end
|
34
|
-
spec.bindir
|
35
|
-
spec.executables
|
36
|
+
spec.bindir = 'exe'
|
37
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
36
38
|
spec.require_paths = ['lib']
|
37
39
|
|
38
|
-
spec.add_runtime_dependency '
|
40
|
+
spec.add_runtime_dependency 'plist', '~> 3'
|
39
41
|
spec.add_runtime_dependency 'ruby-macho', '~> 3'
|
42
|
+
spec.add_runtime_dependency 'rubyzip', '~> 2'
|
43
|
+
spec.add_runtime_dependency 'sorbet-runtime', '~> 0'
|
44
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
40
45
|
end
|
@@ -0,0 +1,269 @@
|
|
1
|
+
# typed: strict
|
2
|
+
|
3
|
+
# DO NOT EDIT MANUALLY
|
4
|
+
# This file was pulled from a central RBI files repository.
|
5
|
+
# Please run `bin/tapioca annotations` to update it.
|
6
|
+
|
7
|
+
module Rainbow
|
8
|
+
# @shim: https://github.com/sickill/rainbow/blob/master/lib/rainbow.rb#L10-L12
|
9
|
+
sig { returns(T::Boolean) }
|
10
|
+
attr_accessor :enabled
|
11
|
+
|
12
|
+
class Color
|
13
|
+
sig { returns(Symbol) }
|
14
|
+
attr_reader :ground
|
15
|
+
|
16
|
+
sig { params(ground: Symbol, values: T.any([Integer], [Integer, Integer, Integer])).returns(Color) }
|
17
|
+
def self.build(ground, values); end
|
18
|
+
|
19
|
+
sig { params(hex: String).returns([Integer, Integer, Integer]) }
|
20
|
+
def self.parse_hex_color(hex); end
|
21
|
+
|
22
|
+
class Indexed < Rainbow::Color
|
23
|
+
sig { returns(Integer) }
|
24
|
+
attr_reader :num
|
25
|
+
|
26
|
+
sig { params(ground: Symbol, num: Integer).void }
|
27
|
+
def initialize(ground, num); end
|
28
|
+
|
29
|
+
sig { returns(T::Array[Integer]) }
|
30
|
+
def codes; end
|
31
|
+
end
|
32
|
+
|
33
|
+
class Named < Rainbow::Color::Indexed
|
34
|
+
NAMES = T.let(nil, T::Hash[Symbol, Integer])
|
35
|
+
|
36
|
+
sig { params(ground: Symbol, name: Symbol).void }
|
37
|
+
def initialize(ground, name); end
|
38
|
+
|
39
|
+
sig { returns(T::Array[Symbol]) }
|
40
|
+
def self.color_names; end
|
41
|
+
|
42
|
+
sig { returns(String) }
|
43
|
+
def self.valid_names; end
|
44
|
+
end
|
45
|
+
|
46
|
+
class RGB < Rainbow::Color::Indexed
|
47
|
+
sig { returns(Integer) }
|
48
|
+
attr_reader :r, :g, :b
|
49
|
+
|
50
|
+
sig { params(ground: Symbol, values: Integer).void }
|
51
|
+
def initialize(ground, *values); end
|
52
|
+
|
53
|
+
sig { returns(T::Array[Integer]) }
|
54
|
+
def codes; end
|
55
|
+
|
56
|
+
sig { params(value: Numeric).returns(Integer) }
|
57
|
+
def self.to_ansi_domain(value); end
|
58
|
+
end
|
59
|
+
|
60
|
+
class X11Named < Rainbow::Color::RGB
|
61
|
+
include Rainbow::X11ColorNames
|
62
|
+
|
63
|
+
sig { returns(T::Array[Symbol]) }
|
64
|
+
def self.color_names; end
|
65
|
+
|
66
|
+
sig { returns(String) }
|
67
|
+
def self.valid_names; end
|
68
|
+
|
69
|
+
sig { params(ground: Symbol, name: Symbol).void }
|
70
|
+
def initialize(ground, name); end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
sig { returns(Wrapper) }
|
75
|
+
def self.global; end
|
76
|
+
|
77
|
+
sig { returns(T::Boolean) }
|
78
|
+
def self.enabled; end
|
79
|
+
|
80
|
+
sig { params(value: T::Boolean).returns(T::Boolean) }
|
81
|
+
def self.enabled=(value); end
|
82
|
+
|
83
|
+
sig { params(string: String).returns(String) }
|
84
|
+
def self.uncolor(string); end
|
85
|
+
|
86
|
+
class NullPresenter < String
|
87
|
+
sig { params(values: T.any([Integer], [Integer, Integer, Integer])).returns(NullPresenter) }
|
88
|
+
def color(*values); end
|
89
|
+
|
90
|
+
sig { params(values: T.any([Integer], [Integer, Integer, Integer])).returns(NullPresenter) }
|
91
|
+
def foreground(*values); end
|
92
|
+
|
93
|
+
sig { params(values: T.any([Integer], [Integer, Integer, Integer])).returns(NullPresenter) }
|
94
|
+
def fg(*values); end
|
95
|
+
|
96
|
+
sig { params(values: T.any([Integer], [Integer, Integer, Integer])).returns(NullPresenter) }
|
97
|
+
def background(*values); end
|
98
|
+
|
99
|
+
sig { params(values: T.any([Integer], [Integer, Integer, Integer])).returns(NullPresenter) }
|
100
|
+
def bg(*values); end
|
101
|
+
|
102
|
+
sig { returns(NullPresenter) }
|
103
|
+
def reset; end
|
104
|
+
|
105
|
+
sig { returns(NullPresenter) }
|
106
|
+
def bright; end
|
107
|
+
|
108
|
+
sig { returns(NullPresenter) }
|
109
|
+
def faint; end
|
110
|
+
|
111
|
+
sig { returns(NullPresenter) }
|
112
|
+
def italic; end
|
113
|
+
|
114
|
+
sig { returns(NullPresenter) }
|
115
|
+
def underline; end
|
116
|
+
|
117
|
+
sig { returns(NullPresenter) }
|
118
|
+
def blink; end
|
119
|
+
|
120
|
+
sig { returns(NullPresenter) }
|
121
|
+
def inverse; end
|
122
|
+
|
123
|
+
sig { returns(NullPresenter) }
|
124
|
+
def hide; end
|
125
|
+
|
126
|
+
sig { returns(NullPresenter) }
|
127
|
+
def cross_out; end
|
128
|
+
|
129
|
+
sig { returns(NullPresenter) }
|
130
|
+
def black; end
|
131
|
+
|
132
|
+
sig { returns(NullPresenter) }
|
133
|
+
def red; end
|
134
|
+
|
135
|
+
sig { returns(NullPresenter) }
|
136
|
+
def green; end
|
137
|
+
|
138
|
+
sig { returns(NullPresenter) }
|
139
|
+
def yellow; end
|
140
|
+
|
141
|
+
sig { returns(NullPresenter) }
|
142
|
+
def blue; end
|
143
|
+
|
144
|
+
sig { returns(NullPresenter) }
|
145
|
+
def magenta; end
|
146
|
+
|
147
|
+
sig { returns(NullPresenter) }
|
148
|
+
def cyan; end
|
149
|
+
|
150
|
+
sig { returns(NullPresenter) }
|
151
|
+
def white; end
|
152
|
+
|
153
|
+
sig { returns(NullPresenter) }
|
154
|
+
def bold; end
|
155
|
+
|
156
|
+
sig { returns(NullPresenter) }
|
157
|
+
def dark; end
|
158
|
+
|
159
|
+
sig { returns(NullPresenter) }
|
160
|
+
def strike; end
|
161
|
+
end
|
162
|
+
|
163
|
+
class Presenter < String
|
164
|
+
TERM_EFFECTS = T.let(nil, T::Hash[Symbol, Integer])
|
165
|
+
|
166
|
+
sig { params(values: T.any([Integer], [Integer, Integer, Integer])).returns(Presenter) }
|
167
|
+
def color(*values); end
|
168
|
+
|
169
|
+
sig { params(values: T.any([Integer], [Integer, Integer, Integer])).returns(Presenter) }
|
170
|
+
def foreground(*values); end
|
171
|
+
|
172
|
+
sig { params(values: T.any([Integer], [Integer, Integer, Integer])).returns(Presenter) }
|
173
|
+
def fg(*values); end
|
174
|
+
|
175
|
+
sig { params(values: T.any([Integer], [Integer, Integer, Integer])).returns(Presenter) }
|
176
|
+
def background(*values); end
|
177
|
+
|
178
|
+
sig { params(values: T.any([Integer], [Integer, Integer, Integer])).returns(Presenter) }
|
179
|
+
def bg(*values); end
|
180
|
+
|
181
|
+
sig { returns(Presenter) }
|
182
|
+
def reset; end
|
183
|
+
|
184
|
+
sig { returns(Presenter) }
|
185
|
+
def bright; end
|
186
|
+
|
187
|
+
sig { returns(Presenter) }
|
188
|
+
def faint; end
|
189
|
+
|
190
|
+
sig { returns(Presenter) }
|
191
|
+
def italic; end
|
192
|
+
|
193
|
+
sig { returns(Presenter) }
|
194
|
+
def underline; end
|
195
|
+
|
196
|
+
sig { returns(Presenter) }
|
197
|
+
def blink; end
|
198
|
+
|
199
|
+
sig { returns(Presenter) }
|
200
|
+
def inverse; end
|
201
|
+
|
202
|
+
sig { returns(Presenter) }
|
203
|
+
def hide; end
|
204
|
+
|
205
|
+
sig { returns(Presenter) }
|
206
|
+
def cross_out; end
|
207
|
+
|
208
|
+
sig { returns(Presenter) }
|
209
|
+
def black; end
|
210
|
+
|
211
|
+
sig { returns(Presenter) }
|
212
|
+
def red; end
|
213
|
+
|
214
|
+
sig { returns(Presenter) }
|
215
|
+
def green; end
|
216
|
+
|
217
|
+
sig { returns(Presenter) }
|
218
|
+
def yellow; end
|
219
|
+
|
220
|
+
sig { returns(Presenter) }
|
221
|
+
def blue; end
|
222
|
+
|
223
|
+
sig { returns(Presenter) }
|
224
|
+
def magenta; end
|
225
|
+
|
226
|
+
sig { returns(Presenter) }
|
227
|
+
def cyan; end
|
228
|
+
|
229
|
+
sig { returns(Presenter) }
|
230
|
+
def white; end
|
231
|
+
|
232
|
+
sig { returns(Presenter) }
|
233
|
+
def bold; end
|
234
|
+
|
235
|
+
sig { returns(Presenter) }
|
236
|
+
def dark; end
|
237
|
+
|
238
|
+
sig { returns(Presenter) }
|
239
|
+
def strike; end
|
240
|
+
end
|
241
|
+
|
242
|
+
class StringUtils
|
243
|
+
sig { params(string: String, codes: T::Array[Integer]).returns(String) }
|
244
|
+
def self.wrap_with_sgr(string, codes); end
|
245
|
+
|
246
|
+
sig { params(string: String).returns(String) }
|
247
|
+
def self.uncolor(string); end
|
248
|
+
end
|
249
|
+
|
250
|
+
VERSION = T.let(nil, String)
|
251
|
+
|
252
|
+
class Wrapper
|
253
|
+
sig { returns(T::Boolean) }
|
254
|
+
attr_accessor :enabled
|
255
|
+
|
256
|
+
sig { params(enabled: T::Boolean).void }
|
257
|
+
def initialize(enabled = true); end
|
258
|
+
|
259
|
+
sig { params(string: String).returns(T.any(Rainbow::Presenter, Rainbow::NullPresenter)) }
|
260
|
+
def wrap(string); end
|
261
|
+
end
|
262
|
+
|
263
|
+
module X11ColorNames
|
264
|
+
NAMES = T.let(nil, T::Hash[Symbol, [Integer, Integer, Integer]])
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
sig { params(string: String).returns(Rainbow::Presenter) }
|
269
|
+
def Rainbow(string); end
|