hackmac 1.8.2 → 1.8.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/hackmac/oc.rb CHANGED
@@ -1,9 +1,43 @@
1
1
  module Hackmac
2
+ # A class that represents an OpenCore configuration and provides access to
3
+ # its remote version information
4
+ #
5
+ # The OC class encapsulates the functionality for working with OpenCore
6
+ # bootloader configurations, including retrieving remote release information
7
+ # from GitHub sources and providing access to version metadata for comparison
8
+ # and upgrade operations
9
+ #
10
+ # @example
11
+ # oc = Hackmac::OC.new(config: config_obj)
12
+ # # Provides access to OpenCore version information through method calls
2
13
  class OC
14
+ # The initialize method sets up an OC instance by storing the provided
15
+ # configuration object.
16
+ #
17
+ # This method takes a configuration object and assigns it to an instance
18
+ # variable for later use in accessing OC-related settings and source
19
+ # information.
20
+ #
21
+ # @param config [ Object ] the configuration object containing OC-specific
22
+ # settings and source definitions
3
23
  def initialize(config:)
4
24
  @config = config
5
25
  end
6
26
 
27
+ # The remote method retrieves or creates a remote source object for
28
+ # OpenCore
29
+ #
30
+ # This method manages the initialization and caching of a remote source
31
+ # object that provides access to OpenCore release information from GitHub.
32
+ # It constructs the appropriate source configuration including
33
+ # authentication credentials and version suffix based on debug settings,
34
+ # then creates a GithubSource instance to handle communication with the
35
+ # GitHub API for retrieving release data
36
+ #
37
+ # @return [ Hackmac::GithubSource ] the cached remote source object for
38
+ # OpenCore releases
39
+ # @return [ nil ] returns nil if no OpenCore source is configured in the
40
+ # configuration
7
41
  def remote
8
42
  @remote and return @remote
9
43
  source = @config.oc.source
@@ -19,21 +53,50 @@ module Hackmac
19
53
  @remote = Hackmac::GithubSource.new(github, auth: auth, suffix: suffix)
20
54
  end
21
55
 
56
+ # The name method retrieves the name attribute from the remote source
57
+ # object
58
+ #
59
+ # This method accesses the cached remote source object and returns its name
60
+ # information if available. It uses the safe navigation operator to avoid
61
+ # errors when the remote source has not been initialized
62
+ #
63
+ # @return [ String, nil ] the name value from the remote source, or nil if no remote source is available
22
64
  def name
23
65
  remote.name
24
66
  end
25
67
 
68
+ # The version method retrieves the version identifier from the remote kext
69
+ # source
70
+ #
71
+ # This method accesses the cached remote kext source object and returns its
72
+ # version information if available. It serves as a delegate to the
73
+ # remote_kext's version attribute, providing convenient access to the
74
+ # latest version data for the kext
75
+ #
76
+ # @return [ Tins::StringVersion, String, nil ] the version object or string from
77
+ # the remote source, or nil if no remote source is available or has no version
78
+ # information
26
79
  def version
27
80
  remote.version
28
81
  end
29
82
 
83
+ # The inspect method returns a string representation of the object that
84
+ # includes its class name and string value.
85
+ #
86
+ # @return [ String ] a formatted string containing the object's class name
87
+ # and its string representation
30
88
  def inspect
31
89
  "#<#{self.class}: #{to_s}>"
32
90
  end
33
91
 
92
+ # The to_s method returns a string representation of the object by
93
+ # combining its name and version attributes into a single space-separated
94
+ # string.
95
+ #
96
+ # @return [ String ] a formatted string containing the name and version
97
+ # separated by a space
34
98
  def to_s
35
99
  "#{name} #{version}"
36
100
  end
37
101
  end
38
102
  end
39
-
@@ -1,16 +1,54 @@
1
1
  require 'fileutils'
2
2
 
3
3
  module Hackmac
4
+ # A class that handles the upgrade process for OpenCore bootloader files
5
+ #
6
+ # The OCUpgrader class manages the workflow for upgrading OpenCore bootloader
7
+ # installations by retrieving remote release information, downloading and
8
+ # decompressing new versions, and performing file system operations to replace
9
+ # existing EFI files after ensuring the installation directory is properly
10
+ # configured
11
+ #
12
+ # @example
13
+ # upgrader = Hackmac::OCUpgrader.new(mdev: '/dev/disk1', config: config_obj)
14
+ # upgrader.perform
15
+ # # Executes the OpenCore upgrade process in a temporary directory context
4
16
  class OCUpgrader
5
17
  include FileUtils::Verbose
6
18
  include Hackmac::AssetTools
7
19
 
20
+ # The initialize method sets up an OCUpgrader instance by configuring the
21
+ # installation directory based on the provided mount point and
22
+ # configuration.
23
+ #
24
+ # This method takes a mount device identifier and configuration object,
25
+ # then constructs the full path to the EFI installation directory by
26
+ # joining the mount path with the OpenCore EFI path specified in the
27
+ # configuration.
28
+ #
29
+ # @param mdev [ String ] the mount device identifier for the EFI partition
30
+ # @param config [ Object ] the configuration object containing OpenCore settings including the EFI path
31
+ #
32
+ # @return [ void ] Returns nothing but initializes instance variables for the upgrade process
8
33
  def initialize(mdev:, config:)
9
34
  @config = config
10
35
  mount_path = Pathname.new('/Volumes').join(mdev)
11
36
  @install_dir = Pathname.new(mount_path).join(@config.oc.efi_path)
12
37
  end
13
38
 
39
+ # The perform method executes the OpenCore upgrade process by isolating the
40
+ # operation in a temporary directory
41
+ #
42
+ # This method handles the complete workflow for upgrading OpenCore
43
+ # bootloader files, including retrieving remote release information,
44
+ # downloading and decompressing the new version, and performing file system
45
+ # operations to replace existing EFI files after ensuring
46
+ # the installation directory is properly configured
47
+ #
48
+ # @return [ void ] Returns nothing but performs file system operations and
49
+ # user interaction
50
+ # @raise [ RuntimeError ] raised when a remote download fails or when no
51
+ # source is defined for the OpenCore upgrade
14
52
  def perform
15
53
  isolate do |dir|
16
54
  oc = OC.new(config: @config)
@@ -28,6 +66,12 @@ module Hackmac
28
66
  end
29
67
  end
30
68
 
69
+ # The to_s method returns a string representation of the object by
70
+ # formatting the installation directory path into a descriptive string
71
+ # that indicates where the OpenCore files will be installed
72
+ #
73
+ # @return [ String ] a formatted string containing the installation path
74
+ # in the format "Installation into /path/to/installation/directory"
31
75
  def to_s
32
76
  'Installation into %s' % @install_dir
33
77
  end
@@ -1,7 +1,27 @@
1
1
  module Hackmac
2
2
  include Hackmac::AssetTools
3
-
3
+ # A class that handles validation of OpenCore bootloader configurations
4
+ #
5
+ # The OCValidator class provides functionality for verifying the correctness
6
+ # and compatibility of OpenCore EFI configuration files. It retrieves the
7
+ # latest OpenCore release, downloads the necessary validation utilities, and
8
+ # executes validation checks against a specified configuration plist file to
9
+ # ensure it meets the required standards for OpenCore bootloaders.
10
+ #
11
+ # @example
12
+ # validator = Hackmac::OCValidator.new(mdev: '/dev/disk1', config: config_obj)
13
+ # # Configures validation for an OpenCore installation on a specific disk
4
14
  class OCValidator
15
+ # The initialize method sets up an OCValidator instance by configuring the
16
+ # path to the OpenCore configuration plist file
17
+ #
18
+ # This method takes a mount device identifier and configuration object,
19
+ # then constructs the full path to the OpenCore configuration plist file by
20
+ # joining the mount path with the EFI path and OC subdirectory specified in
21
+ # the configuration
22
+ #
23
+ # @param mdev [ String ] the mount device identifier for the EFI partition
24
+ # @param config [ Object ] the configuration object containing OpenCore settings including the EFI path
5
25
  def initialize(mdev:, config:)
6
26
  @config = config
7
27
  mount_path = Pathname.new('/Volumes').join(mdev)
@@ -9,6 +29,16 @@ module Hackmac
9
29
  Pathname.new(mount_path).join(@config.oc.efi_path).join('OC/config.plist')
10
30
  end
11
31
 
32
+ # The perform method executes the OpenCore configuration validation process
33
+ #
34
+ # This method handles the complete workflow for validating an OpenCore
35
+ # configuration file by retrieving the latest OpenCore release, downloading
36
+ # the validation utilities, and running the ocvalidate tool against the
37
+ # specified configuration plist file
38
+ #
39
+ # @return [ Boolean ] returns true if validation succeeds, false if validation fails
40
+ # @raise [ RuntimeError ] raised when the OpenCore download fails or when no
41
+ # remote source is defined for the OpenCore upgrade
12
42
  def perform
13
43
  isolate do |dir|
14
44
  oc = OC.new(config: @config)
data/lib/hackmac/plist.rb CHANGED
@@ -2,23 +2,86 @@ require 'plist'
2
2
  require 'shellwords'
3
3
 
4
4
  module Hackmac
5
+ # A module that provides methods for parsing and interacting with Property
6
+ # List (plist) data
7
+ #
8
+ # The Plist module offers functionality to parse XML-formatted plist data
9
+ # from shell commands and provides convenient access to the resulting hash
10
+ # structure. It includes methods for executing commands, parsing their XML
11
+ # output, and accessing plist values through dynamic method calls.
12
+ #
13
+ # @example
14
+ # class MyClass
15
+ # include Hackmac::Plist
16
+ # end
17
+ #
18
+ # obj = MyClass.new
19
+ # obj.plist('diskutil', 'info', '-plist', '/dev/disk0')
20
+ # # Access parsed data through method_missing or as_hash
5
21
  module Plist
22
+ # Parses XML output from a command into a plist hash
23
+ #
24
+ # This method executes a shell command and parses its XML output into a
25
+ # Ruby hash using the Plist library. The resulting hash is stored in the
26
+ # @plist instance variable for later access through other methods.
27
+ #
28
+ # @param cmd [Array<String>] command and arguments to execute
29
+ #
30
+ # @return [void] Returns nothing, but sets the @plist instance variable
6
31
  def plist(*cmd)
7
32
  @plist = ::Plist.parse_xml(`#{Shellwords.join(cmd)}`)
8
33
  end
9
34
 
10
- def as_hash(*)
35
+ # Returns a duplicate of the internal plist hash
36
+ #
37
+ # This method provides access to the parsed plist data by returning a shallow copy
38
+ # of the internal @plist instance variable. This allows external code to read
39
+ # the plist contents without directly modifying the original data structure.
40
+ #
41
+ # @return [ Hash ] a duplicate of the plist hash containing the parsed XML data
42
+ def as_hash(*a)
11
43
  @plist.dup
12
44
  end
13
45
 
46
+ # The each method iterates over the parsed plist data
47
+ #
48
+ # This method provides an iterator interface for the plist hash by
49
+ # delegating to the as_hash method's each implementation. It allows callers
50
+ # to enumerate over the key-value pairs in the parsed plist structure.
51
+ #
52
+ # @yield [ key, value ] yields each key-value pair from the plist
53
+ #
54
+ # @return [ Hash ] returns the hash representation of the plist.
14
55
  def each(&block)
15
56
  as_hash.each(&block)
16
57
  end
17
58
 
59
+ # The to_json method converts the parsed plist data to a JSON string
60
+ #
61
+ # This method takes the internal plist hash and serializes it into a JSON
62
+ # format using the standard to_json method from the Hash class. It provides
63
+ # a convenient way to output the plist data in JSON representation.
64
+ #
65
+ # @param a [ Array ] additional arguments to pass to the underlying to_json method
66
+ #
67
+ # @return [ String ] a JSON string representation of the plist data
18
68
  def to_json(*a)
19
69
  as_hash.to_json(*a)
20
70
  end
21
71
 
72
+ # The method_missing method provides dynamic access to plist data by
73
+ # handling attribute reads and writes through method calls
74
+ #
75
+ # This method intercepts undefined method calls on objects that include the
76
+ # Plist module, allowing convenient access to plist values using
77
+ # method-style syntax. When a method name ends with an equals sign, it sets
78
+ # the corresponding plist key to the provided value. Otherwise, if the
79
+ # method name matches an existing plist key, it returns the value.
80
+ #
81
+ # @param name [ Symbol ] the method name being called
82
+ # @param a [ Array ] the arguments passed to the method
83
+ #
84
+ # @return [ Object ] the value of the plist key when reading, or nil when setting
22
85
  def method_missing(name, *a)
23
86
  n = name.to_s
24
87
  if n =~ /(.+)=\z/
@@ -2,19 +2,65 @@ require 'open-uri'
2
2
  require 'tins/string_version'
3
3
 
4
4
  module Hackmac
5
+ # A class that provides functionality for downloading assets from URLs with
6
+ # version tracking
7
+ #
8
+ # The URLDownload class encapsulates the logic for managing downloadable
9
+ # assets by storing their name, version, and download URL. It provides
10
+ # methods to retrieve the asset data and metadata, making it suitable for use
11
+ # in systems that need to track and download software components from web
12
+ # sources.
13
+ #
14
+ # @example
15
+ # downloader = Hackmac::URLDownload.new('Foo', '1.0.0', 'https://example.com/foo.zip')
16
+ # # Configures a download source with name, version, and URL for later retrieval
5
17
  class URLDownload
6
18
  include Tins::StringVersion
7
19
 
20
+ # The initialize method sets up a URLDownload instance by storing the
21
+ # provided name, URL, and version information.
22
+ #
23
+ # This method takes the necessary parameters to configure the download
24
+ # source and converts the version string into a Version object for later
25
+ # comparison.
26
+ #
27
+ # @param name [ String ] the descriptive name of the downloadable asset
28
+ # @param version [ String ] the version identifier to be parsed and stored
29
+ # @param url [ String ] the web address where the asset can be retrieved
8
30
  def initialize(name, version, url)
9
31
  @name = name
10
32
  @url = url
11
33
  @version = Version.new(version)
12
34
  end
13
35
 
36
+ # The name reader method provides access to the name attribute that was set
37
+ # during object initialization.
38
+ #
39
+ # This method returns the value of the name instance variable, which
40
+ # typically represents the descriptive identifier or label associated with
41
+ # the object.
42
+ #
43
+ # @return [ String ] the name value stored in the instance variable
14
44
  attr_reader :name
15
45
 
46
+ # The version reader method provides access to the version attribute that
47
+ # was set during object initialization.
48
+ #
49
+ # This method returns the value of the version instance variable, which
50
+ # typically represents the semantic version number associated with the
51
+ # object's current state or configuration.
52
+ #
53
+ # @return [ String, nil ] the version value stored in the instance variable, or nil if not set
16
54
  attr_reader :version
17
55
 
56
+ # The download_asset method retrieves binary data from a configured URL
57
+ #
58
+ # This method performs an HTTP GET request to the stored URL to download
59
+ # the associated asset file. It returns both the filename derived from
60
+ # the URL and the raw binary data content.
61
+ #
62
+ # @return [ Array<String, String> ] an array containing the filename and downloaded data
63
+ # @return [ nil ] returns nil if no URL is configured for this instance
18
64
  def download_asset
19
65
  data = URI.open(
20
66
  @url,
@@ -24,14 +70,30 @@ module Hackmac
24
70
  return File.basename(@url), data
25
71
  end
26
72
 
73
+ # The inspect method returns a string representation of the object that
74
+ # includes its class name and string value
75
+ #
76
+ # @return [ String ] a formatted string containing the object's class name
77
+ # and its string representation
27
78
  def inspect
28
79
  "#<#{self.class}: #{to_s}>"
29
80
  end
30
81
 
82
+ # The to_s method returns a string representation of the object by
83
+ # combining its name and version attributes into a single
84
+ # space-separated string.
85
+ #
86
+ # @return [ String ] a formatted string containing the name and version
87
+ # separated by a space
31
88
  def to_s
32
89
  "#{name} #{version}"
33
90
  end
34
91
 
92
+ # The to_s method returns a string representation of the object by
93
+ # combining its name and version attributes into a single space-separated
94
+ # string.
95
+ #
96
+ # @return [ String ] a formatted string containing the name and version separated by a space
35
97
  def to_s
36
98
  "#{name} #{version}"
37
99
  end
data/lib/hackmac/utils.rb CHANGED
@@ -8,9 +8,22 @@ require 'tmpdir'
8
8
  require 'shellwords'
9
9
 
10
10
  module Hackmac
11
+ # A module that provides utility methods for executing shell commands and
12
+ # interacting with users.
13
+ #
14
+ # The Utils module includes methods for running system commands with colored
15
+ # output, prompting users for input, and handling common file operations in a
16
+ # Hackmac context.
11
17
  module Utils
12
18
  include FileUtils
13
19
 
20
+ # The x method executes a shell command and displays its output with
21
+ # colorized prompts.
22
+ #
23
+ # @param cmd [ String ] the shell command to execute
24
+ # @param verbose [ TrueClass, FalseClass ] whether to show command output in verbose mode
25
+ #
26
+ # @return [ String ] the captured output of the command execution
14
27
  def x(cmd, verbose: true)
15
28
  prompt = cmd =~ /\A\s*sudo/ ? ?# : ?$
16
29
  cmd_output = "#{prompt} #{cmd}".color(27) + (verbose ? "" : " >/dev/null".yellow)
@@ -27,6 +40,10 @@ module Hackmac
27
40
  output
28
41
  end
29
42
 
43
+ # The ask method prompts the user for a yes/no response.
44
+ #
45
+ # @param prompt [ String ] the message to display to the user
46
+ # @return [ Boolean ] true if the user answered 'y' or 'Y', false otherwise
30
47
  def ask(prompt)
31
48
  print prompt.bold.yellow
32
49
  gets =~ /\Ay/i
@@ -1,6 +1,6 @@
1
1
  module Hackmac
2
2
  # Hackmac version
3
- VERSION = '1.8.2'
3
+ VERSION = '1.8.3'
4
4
  VERSION_ARRAY = VERSION.split('.').map(&:to_i) # :nodoc:
5
5
  VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
6
6
  VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hackmac
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.2
4
+ version: 1.8.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Florian Frank
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - "~>"
17
17
  - !ruby/object:Gem::Version
18
- version: '1.20'
18
+ version: '2.6'
19
19
  type: :development
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - "~>"
24
24
  - !ruby/object:Gem::Version
25
- version: '1.20'
25
+ version: '2.6'
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: debug
28
28
  requirement: !ruby/object:Gem::Requirement
@@ -176,7 +176,7 @@ extra_rdoc_files:
176
176
  - lib/hackmac/utils.rb
177
177
  - lib/hackmac/version.rb
178
178
  files:
179
- - ".gitignore"
179
+ - ".context/code_comment.rb"
180
180
  - CHANGES.md
181
181
  - Gemfile
182
182
  - LICENSE
@@ -207,7 +207,8 @@ files:
207
207
  - lib/hackmac/utils.rb
208
208
  - lib/hackmac/version.rb
209
209
  homepage: http://github.com/flori/hackmac
210
- licenses: []
210
+ licenses:
211
+ - MIT
211
212
  metadata: {}
212
213
  rdoc_options:
213
214
  - "--title"
data/.gitignore DELETED
@@ -1,9 +0,0 @@
1
- .*.sw[pon]
2
- .AppleDouble
3
- .DS_Store
4
- .bundle
5
- .byebug_history
6
- .rvmrc
7
- Gemfile.lock
8
- pkg
9
- tags