ronin-core 0.1.0.beta1

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.
Files changed (109) hide show
  1. checksums.yaml +7 -0
  2. data/.document +5 -0
  3. data/.github/workflows/ruby.yml +41 -0
  4. data/.gitignore +12 -0
  5. data/.rspec +1 -0
  6. data/.rubocop.yml +160 -0
  7. data/.ruby-version +1 -0
  8. data/.yardopts +1 -0
  9. data/COPYING.txt +165 -0
  10. data/ChangeLog.md +11 -0
  11. data/Gemfile +30 -0
  12. data/README.md +299 -0
  13. data/Rakefile +34 -0
  14. data/examples/ruby_shell.rb +11 -0
  15. data/gemspec.yml +28 -0
  16. data/lib/ronin/core/class_registry.rb +246 -0
  17. data/lib/ronin/core/cli/command.rb +87 -0
  18. data/lib/ronin/core/cli/command_shell/command.rb +110 -0
  19. data/lib/ronin/core/cli/command_shell.rb +345 -0
  20. data/lib/ronin/core/cli/generator/options/author.rb +106 -0
  21. data/lib/ronin/core/cli/generator/options/description.rb +54 -0
  22. data/lib/ronin/core/cli/generator/options/reference.rb +60 -0
  23. data/lib/ronin/core/cli/generator/options/summary.rb +54 -0
  24. data/lib/ronin/core/cli/generator.rb +238 -0
  25. data/lib/ronin/core/cli/logging.rb +59 -0
  26. data/lib/ronin/core/cli/options/param.rb +68 -0
  27. data/lib/ronin/core/cli/options/values/arches.rb +45 -0
  28. data/lib/ronin/core/cli/options/values/oses.rb +32 -0
  29. data/lib/ronin/core/cli/printing/arch.rb +71 -0
  30. data/lib/ronin/core/cli/printing/metadata.rb +113 -0
  31. data/lib/ronin/core/cli/printing/os.rb +54 -0
  32. data/lib/ronin/core/cli/printing/params.rb +69 -0
  33. data/lib/ronin/core/cli/ruby_shell.rb +131 -0
  34. data/lib/ronin/core/cli/shell.rb +186 -0
  35. data/lib/ronin/core/git.rb +73 -0
  36. data/lib/ronin/core/home.rb +86 -0
  37. data/lib/ronin/core/metadata/authors/author.rb +241 -0
  38. data/lib/ronin/core/metadata/authors.rb +120 -0
  39. data/lib/ronin/core/metadata/description.rb +100 -0
  40. data/lib/ronin/core/metadata/id.rb +88 -0
  41. data/lib/ronin/core/metadata/references.rb +87 -0
  42. data/lib/ronin/core/metadata/summary.rb +78 -0
  43. data/lib/ronin/core/metadata/version.rb +74 -0
  44. data/lib/ronin/core/params/exceptions.rb +38 -0
  45. data/lib/ronin/core/params/mixin.rb +317 -0
  46. data/lib/ronin/core/params/param.rb +137 -0
  47. data/lib/ronin/core/params/types/boolean.rb +64 -0
  48. data/lib/ronin/core/params/types/enum.rb +107 -0
  49. data/lib/ronin/core/params/types/float.rb +68 -0
  50. data/lib/ronin/core/params/types/integer.rb +100 -0
  51. data/lib/ronin/core/params/types/numeric.rb +106 -0
  52. data/lib/ronin/core/params/types/regexp.rb +67 -0
  53. data/lib/ronin/core/params/types/string.rb +118 -0
  54. data/lib/ronin/core/params/types/type.rb +54 -0
  55. data/lib/ronin/core/params/types/uri.rb +72 -0
  56. data/lib/ronin/core/params/types.rb +62 -0
  57. data/lib/ronin/core/params.rb +19 -0
  58. data/lib/ronin/core/version.rb +24 -0
  59. data/ronin-core.gemspec +59 -0
  60. data/spec/class_registry_spec.rb +224 -0
  61. data/spec/cli/command_shell/command_spec.rb +113 -0
  62. data/spec/cli/command_shell_spec.rb +1114 -0
  63. data/spec/cli/command_spec.rb +16 -0
  64. data/spec/cli/fixtures/irb_command +8 -0
  65. data/spec/cli/fixtures/template/dir/file1.txt +1 -0
  66. data/spec/cli/fixtures/template/dir/file2.txt +1 -0
  67. data/spec/cli/fixtures/template/file.erb +1 -0
  68. data/spec/cli/fixtures/template/file.txt +1 -0
  69. data/spec/cli/generator/options/author_spec.rb +121 -0
  70. data/spec/cli/generator/options/description_spec.rb +45 -0
  71. data/spec/cli/generator/options/reference_spec.rb +53 -0
  72. data/spec/cli/generator/options/summary_spec.rb +45 -0
  73. data/spec/cli/generator_spec.rb +244 -0
  74. data/spec/cli/logging_spec.rb +95 -0
  75. data/spec/cli/options/param_spec.rb +67 -0
  76. data/spec/cli/options/values/arches_spec.rb +62 -0
  77. data/spec/cli/printing/arch_spec.rb +130 -0
  78. data/spec/cli/printing/metadata_spec.rb +211 -0
  79. data/spec/cli/printing/os_spec.rb +64 -0
  80. data/spec/cli/printing/params_spec.rb +63 -0
  81. data/spec/cli/ruby_shell.rb +99 -0
  82. data/spec/cli/shell_spec.rb +211 -0
  83. data/spec/fixtures/example_class_registry/base_class.rb +9 -0
  84. data/spec/fixtures/example_class_registry/classes/loaded_class.rb +9 -0
  85. data/spec/fixtures/example_class_registry/classes/name_mismatch.rb +9 -0
  86. data/spec/fixtures/example_class_registry/classes/no_module.rb +4 -0
  87. data/spec/fixtures/example_class_registry.rb +8 -0
  88. data/spec/git_spec.rb +58 -0
  89. data/spec/home_spec.rb +64 -0
  90. data/spec/metadata/authors/author_spec.rb +335 -0
  91. data/spec/metadata/authors_spec.rb +126 -0
  92. data/spec/metadata/description_spec.rb +74 -0
  93. data/spec/metadata/id_spec.rb +92 -0
  94. data/spec/metadata/references_spec.rb +100 -0
  95. data/spec/metadata/summary_spec.rb +74 -0
  96. data/spec/metadata/version_spec.rb +72 -0
  97. data/spec/params/mixin_spec.rb +484 -0
  98. data/spec/params/param_spec.rb +164 -0
  99. data/spec/params/types/boolean_spec.rb +56 -0
  100. data/spec/params/types/enum_spec.rb +94 -0
  101. data/spec/params/types/float_spec.rb +107 -0
  102. data/spec/params/types/integer_spec.rb +155 -0
  103. data/spec/params/types/numeric_spec.rb +138 -0
  104. data/spec/params/types/regexp_spec.rb +64 -0
  105. data/spec/params/types/string_spec.rb +174 -0
  106. data/spec/params/types/type_spec.rb +14 -0
  107. data/spec/params/types/uri_spec.rb +62 -0
  108. data/spec/spec_helper.rb +11 -0
  109. metadata +252 -0
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # Copyright (c) 2021-2022 Hal Brodigan (postmodern.mod3 at gmail.com)
4
+ #
5
+ # ronin-core is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU Lesser General Public License as published
7
+ # by the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # ronin-core is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Lesser General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Lesser General Public License
16
+ # along with ronin-core. If not, see <https://www.gnu.org/licenses/>.
17
+ #
18
+
19
+ module Ronin
20
+ module Core
21
+ module CLI
22
+ module Printing
23
+ module OS
24
+ # Mapping of Operating System (OS) IDs to printable names.
25
+ OS_NAMES = {
26
+ unix: 'UNIX',
27
+
28
+ bsd: 'BSD',
29
+ freebsd: 'FreeBSD',
30
+ openbsd: 'OpenBSD',
31
+ netbsd: 'NetBSD',
32
+
33
+ linux: 'Linux',
34
+ macos: 'macOS',
35
+ windows: 'Windows'
36
+ }
37
+
38
+ #
39
+ # Converts the Operating System (OS) ID to a printable name.
40
+ #
41
+ # @param [Symbol] os
42
+ # The OS ID.
43
+ #
44
+ # @return [String]
45
+ # The display name for the OS ID.
46
+ #
47
+ def os_name(os)
48
+ OS_NAMES.fetch(os,&:to_s)
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # Copyright (c) 2021-2022 Hal Brodigan (postmodern.mod3 at gmail.com)
4
+ #
5
+ # ronin-core is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU Lesser General Public License as published
7
+ # by the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # ronin-core is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Lesser General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Lesser General Public License
16
+ # along with ronin-core. If not, see <https://www.gnu.org/licenses/>.
17
+ #
18
+
19
+ require 'ronin/core/params/types'
20
+
21
+ require 'command_kit/printing/tables'
22
+
23
+ module Ronin
24
+ module Core
25
+ module CLI
26
+ module Printing
27
+ #
28
+ # Handles printing {Core::Params::Mixin params} defined on a class.
29
+ #
30
+ module Params
31
+ include CommandKit::Printing::Tables
32
+
33
+ # The params table header.
34
+ PARAM_TABLE_HEADER = %w[Name Type Required Default Description]
35
+
36
+ #
37
+ # Prints the params defined in the given class.
38
+ #
39
+ # @param [Class<Core::Params::Mixin>] klass
40
+ # The class which contains the params.
41
+ #
42
+ def print_params(klass)
43
+ return if klass.params.empty?
44
+
45
+ rows = []
46
+
47
+ klass.params.each do |name,param|
48
+ param_type = param.type.class.name.split('::').last
49
+ required = if param.required? then 'Yes'
50
+ else 'No'
51
+ end
52
+ default = param.default_value
53
+ description = param.desc
54
+
55
+ rows << [name, param_type, required, default, description]
56
+ end
57
+
58
+ puts "Params:"
59
+ puts
60
+
61
+ indent do
62
+ print_table(rows,header: PARAM_TABLE_HEADER, border: :line)
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,131 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # Copyright (c) 2021-2022 Hal Brodigan (postmodern.mod3 at gmail.com)
4
+ #
5
+ # ronin-core is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU Lesser General Public License as published
7
+ # by the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # ronin-core is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Lesser General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Lesser General Public License
16
+ # along with ronin-core. If not, see <https://www.gnu.org/licenses/>.
17
+ #
18
+
19
+ require 'command_kit/colors'
20
+
21
+ require 'irb'
22
+
23
+ module Ronin
24
+ module Core
25
+ module CLI
26
+ #
27
+ # Starts a customized Interactive Ruby console.
28
+ #
29
+ # @api semipublic
30
+ #
31
+ class RubyShell
32
+
33
+ include CommandKit::Colors
34
+
35
+ # The console name.
36
+ #
37
+ # @return [String]
38
+ attr_reader :name
39
+
40
+ # The optional context to spawn the console inside of.
41
+ #
42
+ # @return [Object, nil]
43
+ attr_reader :context
44
+
45
+ #
46
+ # Initializes the console.
47
+ #
48
+ # @param [String] name
49
+ # The name of the IRB console.
50
+ #
51
+ # @param [Object] context
52
+ # Custom context to launch IRB from within.
53
+ #
54
+ # @param [Hash{Symbol => Object}] kwargs
55
+ # Additional keyword arguments for `initialize`.
56
+ #
57
+ def initialize(name: 'ronin', context: nil, **kwargs)
58
+ super(**kwargs)
59
+
60
+ @name = name
61
+ @context = context
62
+ end
63
+
64
+ #
65
+ # Starts a customized [irb] console.
66
+ # [irb]: https://github.com/ruby/irb#readme
67
+ #
68
+ # @param [Hash{Symbol => Object}] kwargs
69
+ # Additional keyword arguments for {#initialize}.
70
+ #
71
+ # @option kwargs [String] :name
72
+ # The name of the IRB console.
73
+ #
74
+ # @option kwargs [Object] :context
75
+ # Custom context to launch IRB from within.
76
+ #
77
+ def self.start(**kwargs)
78
+ new(**kwargs).start
79
+ end
80
+
81
+ #
82
+ # Configures IRB.
83
+ #
84
+ def configure
85
+ IRB.setup(nil, argv: [])
86
+ IRB.conf[:IRB_NAME] = @name
87
+
88
+ set_prompt
89
+ end
90
+
91
+ #
92
+ # Starts a customized [irb] console.
93
+ # [irb]: https://github.com/ruby/irb#readme
94
+ #
95
+ def start
96
+ configure
97
+
98
+ workspace = if @context then IRB::WorkSpace.new(@context)
99
+ else IRB::WorkSpace.new
100
+ end
101
+
102
+ irb = IRB::Irb.new(workspace)
103
+ irb.run
104
+ end
105
+
106
+ private
107
+
108
+ #
109
+ # Sets the IRB prompts for ronin.
110
+ #
111
+ def set_prompt
112
+ colors(STDOUT).tap do |c|
113
+ left_paren = c.bold(c.bright_red('('))
114
+ right_paren = c.bold(c.bright_red(')'))
115
+ prompt_prefix = "#{c.red('irb')}#{left_paren}#{c.red('%N')}#{right_paren}"
116
+
117
+ IRB.conf[:PROMPT][:RONIN] = {
118
+ AUTO_INDENT: true,
119
+ PROMPT_I: "#{prompt_prefix}#{c.bold(c.bright_red('>'))} ",
120
+ PROMPT_S: "#{prompt_prefix}%l ",
121
+ PROMPT_C: "#{prompt_prefix}* ",
122
+ RETURN: "=> %s#{$/}"
123
+ }
124
+ IRB.conf[:PROMPT_MODE] = :RONIN
125
+ end
126
+ end
127
+
128
+ end
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,186 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # Copyright (c) 2021-2022 Hal Brodigan (postmodern.mod3 at gmail.com)
4
+ #
5
+ # ronin-core is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU Lesser General Public License as published
7
+ # by the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # ronin-core is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Lesser General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Lesser General Public License
16
+ # along with ronin-core. If not, see <https://www.gnu.org/licenses/>.
17
+ #
18
+
19
+ require 'command_kit/printing'
20
+ require 'command_kit/colors'
21
+ require 'reline'
22
+
23
+ module Ronin
24
+ module Core
25
+ module CLI
26
+ class Shell
27
+
28
+ include CommandKit::Printing
29
+ include CommandKit::Colors
30
+
31
+ #
32
+ # The default shell prompt name.
33
+ #
34
+ # @param [String, nil] new_name
35
+ # The optional new shell prompt name to set.
36
+ #
37
+ # @return [String]
38
+ # The shell prompt name.
39
+ #
40
+ def self.shell_name(new_name=nil)
41
+ if new_name
42
+ @shell_name = new_name
43
+ else
44
+ @shell_name ||= if superclass < Shell
45
+ superclass.shell_name
46
+ end
47
+ end
48
+ end
49
+
50
+ #
51
+ # The default prompt sigil.
52
+ #
53
+ # @param [String, nil] new_sigil
54
+ # The optional new prompt sigil to use.
55
+ #
56
+ # @return [String]
57
+ # The prompt sigil.
58
+ #
59
+ def self.prompt_sigil(new_sigil=nil)
60
+ if new_sigil
61
+ @prompt_sigil = new_sigil
62
+ else
63
+ @prompt_sigil ||= if superclass <= Shell
64
+ superclass.prompt_sigil
65
+ end
66
+ end
67
+ end
68
+
69
+ prompt_sigil '>'
70
+
71
+ #
72
+ # Starts the shell and processes each line of input.
73
+ #
74
+ # @param [Array<Object>] arguments
75
+ # Additional arguments for `initialize`.
76
+ #
77
+ # @param [Hash{Symbol => Object}] kwargs
78
+ # Additional keyword arguments for `initialize`.
79
+ #
80
+ # @note
81
+ # The shell will exit if `Ctrl^C` or `Ctrl^D` is pressed.
82
+ #
83
+ def self.start(*arguments,**kwargs)
84
+ shell = new(*arguments,**kwargs)
85
+
86
+ Reline.completion_proc = shell.method(:complete)
87
+ use_history = true
88
+
89
+ begin
90
+ loop do
91
+ line = Reline.readline("#{shell.prompt} ", use_history)
92
+
93
+ if line.nil? # Ctrl^D
94
+ puts
95
+ break
96
+ end
97
+
98
+ line.chomp!
99
+
100
+ unless line.empty?
101
+ begin
102
+ shell.exec(line)
103
+ rescue SystemExit
104
+ break
105
+ rescue => error
106
+ shell.print_exception(error)
107
+ end
108
+ end
109
+ end
110
+ rescue Interrupt # catch Ctrl^C
111
+ end
112
+ end
113
+
114
+ #
115
+ # The partially input being tab completed.
116
+ #
117
+ # @param [String] word
118
+ # The partial input being tab completed.
119
+ #
120
+ # @param [String] preposing
121
+ # The optional command name that preceeds the argument that's being
122
+ # tab completed.
123
+ #
124
+ # @return [Array<String>, nil]
125
+ # The possible completion values.
126
+ #
127
+ # @abstract
128
+ #
129
+ def complete(word,preposing)
130
+ end
131
+
132
+ # The shell's name.
133
+ #
134
+ # @return [String, nil]
135
+ attr_reader :shell_name
136
+
137
+ # The prompt sigil character (ex: `>`).
138
+ #
139
+ # @return [String]
140
+ attr_reader :prompt_sigil
141
+
142
+ #
143
+ # Initializes the shell instance.
144
+ #
145
+ # @param [String, nil] shell_name
146
+ # The optional shell name to override {shell_name}.
147
+ #
148
+ # @param [String] prompt_sigil
149
+ # The optional prompt sigil to override {prompt_sigil}.
150
+ #
151
+ def initialize(shell_name: self.class.shell_name,
152
+ prompt_sigil: self.class.prompt_sigil,
153
+ **kwargs)
154
+ super(**kwargs)
155
+
156
+ @shell_name = shell_name
157
+ @prompt_sigil = prompt_sigil
158
+ end
159
+
160
+ #
161
+ # The shell prompt.
162
+ #
163
+ # @return [String]
164
+ #
165
+ def prompt
166
+ c = colors(stdout)
167
+
168
+ "#{c.red(shell_name)}#{c.bold(c.bright_red(prompt_sigil))}"
169
+ end
170
+
171
+ #
172
+ # Executes a command.
173
+ #
174
+ # @param [String] line
175
+ # The command to execute.
176
+ #
177
+ # @abstract
178
+ #
179
+ def exec(line)
180
+ raise(NotImplementedError,"#{self.class}##{__method__} was not implemented")
181
+ end
182
+
183
+ end
184
+ end
185
+ end
186
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # Copyright (c) 2021-2022 Hal Brodigan (postmodern.mod3 at gmail.com)
4
+ #
5
+ # ronin-core is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU Lesser General Public License as published
7
+ # by the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # ronin-core is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Lesser General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Lesser General Public License
16
+ # along with ronin-core. If not, see <https://www.gnu.org/licenses/>.
17
+ #
18
+
19
+ module Ronin
20
+ module Core
21
+ #
22
+ # @api semipublic
23
+ #
24
+ module Git
25
+ #
26
+ # Queries the git `user.name` variable from `~/.gitconfig`.
27
+ #
28
+ # @return [String, nil]
29
+ # The value of `user.name` or `nil` if it was not set.
30
+ #
31
+ def self.user_name
32
+ config_value('user.name')
33
+ end
34
+
35
+ #
36
+ # Queries the git `user.email` variable from `~/.gitconfig`.
37
+ #
38
+ # @return [String, nil]
39
+ # The value of `user.email` or `nil` if it was not set.
40
+ #
41
+ def self.user_email
42
+ config_value('user.email')
43
+ end
44
+
45
+ #
46
+ # Queries the git `github.user` variable from `~/.gitconfig`.
47
+ #
48
+ # @return [String, nil]
49
+ # The value of `github.user` or `nil` if it was not set.
50
+ #
51
+ def self.github_user
52
+ config_value('github.user')
53
+ end
54
+
55
+ #
56
+ # Queries a git configuration value.
57
+ #
58
+ # @param [String] name
59
+ # The configuration name.
60
+ #
61
+ # @return [string, nil]
62
+ # The configuration value or `nil` if nothing was returned.
63
+ #
64
+ def self.config_value(name)
65
+ output = `git config #{name}`.chomp
66
+
67
+ if output.empty? then nil
68
+ else output
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # Copyright (c) 2021-2022 Hal Brodigan (postmodern.mod3 at gmail.com)
4
+ #
5
+ # ronin-core is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU Lesser General Public License as published
7
+ # by the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # ronin-core is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU Lesser General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Lesser General Public License
16
+ # along with ronin-core. If not, see <https://www.gnu.org/licenses/>.
17
+ #
18
+
19
+ module Ronin
20
+ module Core
21
+ #
22
+ # Home directory constants and methods.
23
+ #
24
+ # @api semipublic
25
+ #
26
+ module Home
27
+ # Path to the user's home directory.
28
+ DIR = Gem.user_home
29
+
30
+ # Path to the user's `~/.cache/` directory.
31
+ CACHE_DIR = ENV.fetch('XDG_CACHE_HOME') do
32
+ File.join(DIR,'.cache')
33
+ end
34
+
35
+ #
36
+ # Returns the path to the sub-directory within the `~/.cache/` directory.
37
+ #
38
+ # @param [String] subdir
39
+ # The sub-directory.
40
+ #
41
+ # @return [String]
42
+ # The path to the `~/.cache/<subdir>` directory.
43
+ #
44
+ def self.cache_dir(subdir)
45
+ File.join(CACHE_DIR,subdir)
46
+ end
47
+
48
+ # Path to the user's `~/.config/` directory.
49
+ CONFIG_DIR = ENV.fetch('XDG_CONFIG_HOME') do
50
+ File.join(DIR,'.config')
51
+ end
52
+
53
+ #
54
+ # Returns the path to the sub-directory within the `~/.config/` directory.
55
+ #
56
+ # @param [String] subdir
57
+ # The sub-directory.
58
+ #
59
+ # @return [String]
60
+ # The path to the `~/.config/<subdir>` directory.
61
+ #
62
+ def self.config_dir(subdir)
63
+ File.join(CONFIG_DIR,subdir)
64
+ end
65
+
66
+ # Path to the user's `~/.local/share` directory.
67
+ LOCAL_SHARE_DIR = ENV.fetch('XDG_DATA_HOME') do
68
+ File.join(DIR,'.local','share')
69
+ end
70
+
71
+ #
72
+ # Returns the path to the sub-directory within the `~/.local/share/`
73
+ # directory.
74
+ #
75
+ # @param [String] subdir
76
+ # The sub-directory.
77
+ #
78
+ # @return [String]
79
+ # The path to the `~/.local/share/<subdir>` directory.
80
+ #
81
+ def self.local_share_dir(subdir)
82
+ File.join(LOCAL_SHARE_DIR,subdir)
83
+ end
84
+ end
85
+ end
86
+ end