gem_hadar 2.10.0 → 2.11.0

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.
@@ -1,67 +1,107 @@
1
1
  require 'pathname'
2
2
 
3
- # A module that provides utility methods for handling XDG Base Directory
4
- # specification compliance.
3
+ # A module that provides utility methods for GemHadar
5
4
  #
6
- # This module offers functionality to determine the appropriate configuration
7
- # directory based on the XDG Base Directory specification, construct paths for
8
- # configuration files, and retrieve configuration data from those files. It
9
- # helps ensure consistent and standardized handling of user configuration files
10
- # across different operating systems.
11
- #
12
- # @example Determining the XDG configuration directory
13
- # config_dir = GemHadar::Utils.xdg_config_home
14
- #
15
- # @example Retrieving configuration file contents
16
- # config_content = GemHadar::Utils.xdg_config('myapp', 'default_value')
5
+ # This module contains helper methods for common operations within the GemHadar
6
+ # framework, including XDG configuration directory handling, user input
7
+ # prompts, and memoization capabilities. It serves as a collection of reusable
8
+ # utilities that support various aspects of gem automation and configuration
9
+ # management.
17
10
  module GemHadar::Utils
18
- # The xdg_config_home method determines the path to the XDG configuration
19
- # directory.
11
+ # The xdg_config_home method determines the XDG configuration directory path.
20
12
  #
21
- # It first checks if the XDG_CONFIG_HOME environment variable is set and not
22
- # empty. If it is set, the method returns the value as a Pathname object. If
23
- # XDG_CONFIG_HOME is not set, it defaults to using the HOME environment
24
- # variable to construct the path within the standard .config directory.
13
+ # This method returns the path to the XDG configuration directory, which is used
14
+ # to store user-specific configuration files for applications. It first checks
15
+ # the XDG_CONFIG_HOME environment variable and returns its value if set.
16
+ # If the environment variable is not set, it falls back to the default
17
+ # configuration directory within the user's home directory, typically
18
+ # ~/.config.
25
19
  #
26
- # @return [ Pathname ] the Pathname object representing the XDG configuration directory
20
+ # @return [ Pathname ] the Pathname object representing the XDG configuration
21
+ # directory path
27
22
  def xdg_config_home
28
23
  ENV['XDG_CONFIG_HOME'].full? { Pathname.new(_1) } ||
29
24
  Pathname.new(ENV.fetch('HOME')) + '.config'
30
25
  end
31
26
 
27
+ # The xdg_config_dir method constructs the path to the XDG configuration
28
+ # directory for a specific application.
29
+ #
30
+ # This method takes an application name and returns the full path to the
31
+ # configuration directory for that application within the XDG configuration
32
+ # home directory.
33
+ #
34
+ # @param app [ String ] the name of the application to get the configuration
35
+ # directory for
36
+ #
37
+ # @return [ Pathname ] the Pathname object representing the application's
38
+ # configuration directory path
39
+ def xdg_config_dir(app)
40
+ xdg_config_home + app
41
+ end
42
+
32
43
  # The xdg_config_filename method constructs the full path to a configuration
33
- # file based on the XDG Base Directory specification.
44
+ # file within the XDG configuration directory for a specific application.
34
45
  #
35
- # It first checks if the XDG_CONFIG_HOME environment variable is set and not
36
- # empty. If it is set, the method joins this directory with the provided
37
- # filename to form the complete path. If XDG_CONFIG_HOME is not set, it
38
- # defaults to using the HOME environment variable to construct the path
39
- # within the standard .config directory.
46
+ # This method takes an application name and a filename, then combines them
47
+ # with the XDG configuration directory path to create the full path to a
48
+ # configuration file.
40
49
  #
50
+ # @param app [ String ] the name of the application to get the configuration
51
+ # directory for
41
52
  # @param name [ String ] the name of the configuration file
42
53
  #
43
- # @return [ String ] the full path to the configuration file
44
- def xdg_config_filename(name)
45
- xdg_config_home + name
54
+ # @return [ Pathname ] the Pathname object representing the full path to the
55
+ # configuration file
56
+ def xdg_config_filename(app, name)
57
+ xdg_config_dir(app) + name
46
58
  end
47
59
 
48
- memoize method:
49
- # The xdg_config method retrieves configuration data from a file following
50
- # the XDG Base Directory specification.
60
+ # The xdg_config method retrieves configuration content from XDG
61
+ # configuration directories
51
62
  #
52
- # It checks for the existence of a configuration file using the
53
- # xdg_config_filename method and returns its contents if found. If the file
54
- # does not exist, it returns the provided default value instead.
63
+ # This method checks for the existence of a configuration file within the XDG
64
+ # configuration directory structure for the specified application. If the
65
+ # file exists, it reads and returns the file's content. If the file does not
66
+ # exist, it returns the provided default value instead.
55
67
  #
56
- # @param name [ String ] the name of the configuration file to retrieve
57
- # @param default [ Object ] the default value to return if the configuration file is not found
68
+ # @param app [ String ] the name of the application to get the configuration
69
+ # directory for
70
+ # @param name [ String ] the name of the configuration file
71
+ # @param default [ String ] the default value to return if the configuration
72
+ # file does not exist
58
73
  #
59
- # @return [ String ] the content of the configuration file or the default value
60
- def xdg_config(name, default)
61
- if File.exist?(xdg_config_filename(name))
62
- File.read(xdg_config_filename(name))
74
+ # @return [ String ] the content of the configuration file or the default
75
+ # value if the file does not exist
76
+ def xdg_config(app, name, default)
77
+ if xdg_config_filename(app, name).exist?
78
+ File.read(xdg_config_filename(app, name))
63
79
  else
64
80
  default
65
81
  end
66
82
  end
83
+ memoize method: :xdg_config
84
+
85
+ # The ask? method prompts the user with a message and reads their input It
86
+ # returns a MatchData object if the input matches the provided pattern.
87
+ #
88
+ # @param prompt [ String ] the message to display to the user
89
+ # @param pattern [ Regexp ] the regular expression to match against the input
90
+ #
91
+ # @return [ MatchData, nil ] the result of the pattern match or nil if no match
92
+ def ask?(prompt, pattern, default: nil)
93
+ if prompt.include?('%{default}')
94
+ if default.present?
95
+ prompt = prompt % { default: ", default is #{default.inspect}" }
96
+ else
97
+ prompt = prompt % { default: '' }
98
+ end
99
+ end
100
+ STDOUT.print prompt
101
+ answer = STDIN.gets.chomp
102
+ default.present? && answer.blank? and answer = default
103
+ if answer =~ pattern
104
+ $~
105
+ end
106
+ end
67
107
  end
@@ -1,6 +1,6 @@
1
1
  class GemHadar
2
2
  # GemHadar version
3
- VERSION = '2.10.0'
3
+ VERSION = '2.11.0'
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:
@@ -0,0 +1,144 @@
1
+ # A class that represents a version specification for a gem.
2
+ #
3
+ # This class provides functionality to parse and manipulate version strings,
4
+ # including handling of semantic versioning formats and optional 'v' prefixes.
5
+ # It supports creating version specifications from various input formats and
6
+ # provides methods to access the underlying version information and string
7
+ # representation.
8
+ #
9
+ # @example Creating a version specification
10
+ # version_spec = GemHadar::VersionSpec['1.2.3']
11
+ #
12
+ # @example Checking if a version is a HEAD reference
13
+ # version_spec = GemHadar::VersionSpec['HEAD']
14
+ # version_spec.head? # => true
15
+ #
16
+ # @example Getting the version tag with appropriate prefixing
17
+ # version_spec = GemHadar::VersionSpec['1.2.3']
18
+ # version_spec.tag # => 'v1.2.3'
19
+ #
20
+ # @example Comparing versions
21
+ # version1 = GemHadar::VersionSpec['1.2.3']
22
+ # version2 = GemHadar::VersionSpec['1.2.4']
23
+ # version1.version < version2.version # => true
24
+ class GemHadar::VersionSpec
25
+ class << self
26
+ # The [] method creates a new VersionSpec instance from a specification.
27
+ #
28
+ # This factory method attempts to extract version information from the
29
+ # provided specification, handling both gem specifications and version
30
+ # strings. It supports optional prefix handling for the resulting version
31
+ # string.
32
+ #
33
+ # @param spec [Object] the specification to parse, typically a String or Gem::Specification
34
+ #
35
+ # @param with_prefix [Boolean] if true, ensures the version string has a 'v' prefix
36
+ #
37
+ # @param without_prefix [Boolean] if true, ensures the version string does not have a 'v' prefix
38
+ #
39
+ # @return [GemHadar::VersionSpec] a new VersionSpec instance
40
+ #
41
+ # @raise [ArgumentError] if both with_prefix and without_prefix are specified simultaneously
42
+ def [](spec, with_prefix: nil, without_prefix: nil)
43
+ !(with_prefix && without_prefix) or
44
+ raise ArgumentError, 'with_prefix and without_prefix is invalid'
45
+ spec.is_a?(self) and return spec
46
+ obj, version = nil, (spec.version rescue nil)
47
+ if version
48
+ ;
49
+ elsif /\Av?(\d+\.\d+\.\d+)\z/ =~ spec
50
+ begin
51
+ version = Tins::StringVersion::Version.new($1)
52
+ rescue ArgumentError
53
+ end
54
+ end
55
+ spec = spec.to_s
56
+ if version
57
+ if with_prefix
58
+ spec = spec.sub(/\A(?!v)/, 'v')
59
+ elsif without_prefix
60
+ spec = spec.sub(/\Av?/, '')
61
+ end
62
+ end
63
+ obj = new(spec, version)
64
+ obj.freeze
65
+ end
66
+
67
+ private_class_method :new
68
+ end
69
+
70
+ # Initializes a new VersionSpec instance.
71
+ #
72
+ # @param string [String] the original string representation of the version
73
+ # @param version [Tins::StringVersion::Version, nil] the parsed version object or nil if parsing failed
74
+ def initialize(string, version)
75
+ @string, @version = string, version
76
+ end
77
+
78
+ # Retrieves the parsed version object.
79
+ #
80
+ # @return [Tins::StringVersion::Version, nil] the parsed version object or nil if parsing failed
81
+ attr_reader :version
82
+
83
+ # Checks if a version object was successfully parsed.
84
+ #
85
+ # @return [Boolean] true if version was parsed successfully, false otherwise
86
+ def version?
87
+ !!@version
88
+ end
89
+
90
+ # The head? method checks if the version string represents a HEAD reference.
91
+ #
92
+ # This method returns true if the internal string representation of the version
93
+ # spec is exactly 'HEAD', indicating that it refers to the latest commit
94
+ # rather than a specific tagged version.
95
+ #
96
+ # @return [ Boolean ] true if the version string is 'HEAD', false otherwise
97
+ def head?
98
+ @string == 'HEAD'
99
+ end
100
+
101
+ # The tag method returns the version tag string with appropriate prefixing.
102
+ #
103
+ # This method checks if the version represents a HEAD reference and returns
104
+ # the raw string representation if so. Otherwise, it returns the version
105
+ # string with a 'v' prefix added to it.
106
+ #
107
+ # @return [ String ] the version tag string, either as-is for HEAD or with 'v' prefix added
108
+ def tag
109
+ head? ? to_s : with_prefix
110
+ end
111
+
112
+ # The untag method returns the version string without a 'v' prefix.
113
+ #
114
+ # This method checks if the version represents a HEAD reference and returns
115
+ # the raw string representation if so. Otherwise, it returns the version
116
+ # string with the 'v' prefix removed.
117
+ #
118
+ # @return [ String ] the version string without 'v' prefix or the raw string
119
+ # if it represents a HEAD reference
120
+ def untag
121
+ head? ? to_s : without_prefix
122
+ end
123
+
124
+ # Returns the original string representation.
125
+ #
126
+ # @return [String] the original version string
127
+ def to_s
128
+ @string.to_s
129
+ end
130
+
131
+ # Removes the 'v' prefix from the version string if present.
132
+ #
133
+ # @return [String] the version string without 'v' prefix
134
+ def without_prefix
135
+ to_s.sub(/\Av/, '')
136
+ end
137
+
138
+ # Adds a 'v' prefix to the version string if not already present.
139
+ #
140
+ # @return [String] the version string with 'v' prefix
141
+ def with_prefix
142
+ to_s.sub(/\A(?!v)/, 'v')
143
+ end
144
+ end
@@ -43,8 +43,6 @@ class GemHadar
43
43
  # within this method itself.
44
44
  #
45
45
  # @param msgs [ Array<Object> ] the array of message objects to display as failures
46
- #
47
- # @return [ void ]
48
46
  def fail(*msgs)
49
47
  msgs.map! do |a|
50
48
  a.respond_to?(:to_str) ? color(196) { a.to_str } : a