ronin-repos 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.
- checksums.yaml +7 -0
- data/.document +5 -0
- data/.github/workflows/ruby.yml +27 -0
- data/.gitignore +13 -0
- data/.rspec +1 -0
- data/.ruby-version +1 -0
- data/.yardopts +1 -0
- data/COPYING.txt +165 -0
- data/ChangeLog.md +7 -0
- data/Gemfile +32 -0
- data/README.md +159 -0
- data/Rakefile +34 -0
- data/bin/ronin-repos +35 -0
- data/data/templates/repo/README.md.erb +11 -0
- data/gemspec.yml +36 -0
- data/lib/ronin/repos/cache_dir.rb +267 -0
- data/lib/ronin/repos/class_dir.rb +150 -0
- data/lib/ronin/repos/cli/command.rb +63 -0
- data/lib/ronin/repos/cli/commands/install.rb +71 -0
- data/lib/ronin/repos/cli/commands/list.rb +80 -0
- data/lib/ronin/repos/cli/commands/new.rb +83 -0
- data/lib/ronin/repos/cli/commands/purge.rb +39 -0
- data/lib/ronin/repos/cli/commands/remove.rb +71 -0
- data/lib/ronin/repos/cli/commands/update.rb +91 -0
- data/lib/ronin/repos/cli.rb +45 -0
- data/lib/ronin/repos/exceptions.rb +33 -0
- data/lib/ronin/repos/repository.rb +343 -0
- data/lib/ronin/repos/root.rb +26 -0
- data/lib/ronin/repos/version.rb +24 -0
- data/lib/ronin/repos.rb +81 -0
- data/man/ronin-repos-install.1 +64 -0
- data/man/ronin-repos-install.1.md +49 -0
- data/man/ronin-repos-list.1 +54 -0
- data/man/ronin-repos-list.1.md +41 -0
- data/man/ronin-repos-new.1 +37 -0
- data/man/ronin-repos-purge.1 +54 -0
- data/man/ronin-repos-purge.1.md +41 -0
- data/man/ronin-repos-remove.1 +60 -0
- data/man/ronin-repos-remove.1.md +46 -0
- data/man/ronin-repos-update.1 +64 -0
- data/man/ronin-repos-update.1.md +49 -0
- data/man/ronin-repos.1 +49 -0
- data/man/ronin-repos.1.md +37 -0
- data/ronin-repos.gemspec +62 -0
- data/spec/cache_dir_spec.rb +272 -0
- data/spec/class_dir_spec.rb +97 -0
- data/spec/fixtures/cache/repo1/dir/file1.txt +0 -0
- data/spec/fixtures/cache/repo1/file1.txt +0 -0
- data/spec/fixtures/cache/repo1/file2.txt +0 -0
- data/spec/fixtures/cache/repo2/dir/file1.txt +0 -0
- data/spec/fixtures/cache/repo2/dir/file2.txt +0 -0
- data/spec/fixtures/cache/repo2/file1.txt +0 -0
- data/spec/fixtures/cache/repo2/file2.txt +0 -0
- data/spec/fixtures/cache/repo2/only-exists-in-repo2.txt +0 -0
- data/spec/fixtures/class_dir/file1.rb +0 -0
- data/spec/fixtures/class_dir/file2.rb +0 -0
- data/spec/fixtures/class_dir/only_in_class_dir.rb +0 -0
- data/spec/repos_spec.rb +67 -0
- data/spec/repository_spec.rb +415 -0
- data/spec/spec_helper.rb +6 -0
- metadata +143 -0
@@ -0,0 +1,267 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# Copyright (c) 2021 Hal Brodigan (postmodern.mod3 at gmail.com)
|
4
|
+
#
|
5
|
+
# ronin-repos 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-repos 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-repos. If not, see <https://www.gnu.org/licenses/>.
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'ronin/repos/exceptions'
|
20
|
+
require 'ronin/repos/repository'
|
21
|
+
require 'ronin/core/home'
|
22
|
+
|
23
|
+
require 'set'
|
24
|
+
|
25
|
+
module Ronin
|
26
|
+
module Repos
|
27
|
+
#
|
28
|
+
# Manages the `~/.cache/ronin-repos/` directory and the repositories
|
29
|
+
# contained within.
|
30
|
+
#
|
31
|
+
# @api private
|
32
|
+
#
|
33
|
+
class CacheDir
|
34
|
+
|
35
|
+
include Enumerable
|
36
|
+
|
37
|
+
# The ~/.cache/ronin-repos/ directory where all repos are stored.
|
38
|
+
PATH = Core::Home.cache_dir('ronin-repos')
|
39
|
+
|
40
|
+
# The path to the cache directory.
|
41
|
+
#
|
42
|
+
# @return [String]
|
43
|
+
attr_reader :path
|
44
|
+
|
45
|
+
#
|
46
|
+
# Initializes the repository cache.
|
47
|
+
#
|
48
|
+
# @param [String] path
|
49
|
+
# The path to the repository cache directory.
|
50
|
+
#
|
51
|
+
def initialize(path=PATH)
|
52
|
+
@path = path
|
53
|
+
end
|
54
|
+
|
55
|
+
#
|
56
|
+
# Accesses a repository from the cache directory.
|
57
|
+
#
|
58
|
+
# @param [String] name
|
59
|
+
# The name of the repository.
|
60
|
+
#
|
61
|
+
# @return [Repository]
|
62
|
+
# The repository from the cache.
|
63
|
+
#
|
64
|
+
# @raise [RepositoryNotFound]
|
65
|
+
# No repository exists with the given name in the cache directory.
|
66
|
+
#
|
67
|
+
def [](name)
|
68
|
+
path = File.join(@path,name.to_s)
|
69
|
+
|
70
|
+
unless File.directory?(path)
|
71
|
+
raise(RepositoryNotFound,"repository not found: #{name.inspect}")
|
72
|
+
end
|
73
|
+
|
74
|
+
return Repository.new(path)
|
75
|
+
end
|
76
|
+
|
77
|
+
#
|
78
|
+
# Enumerates through every repository in the cache directory.
|
79
|
+
#
|
80
|
+
# @yield [repo]
|
81
|
+
# The given block will be passed each repository.
|
82
|
+
#
|
83
|
+
# @yieldparam [Repository] repo
|
84
|
+
# A repository from the cache directory.
|
85
|
+
#
|
86
|
+
# @return [Enumerator]
|
87
|
+
# If no block is given, an Enumerator will be returned.
|
88
|
+
#
|
89
|
+
def each
|
90
|
+
return enum_for unless block_given?
|
91
|
+
|
92
|
+
each_child_directory do |path|
|
93
|
+
yield Repository.new(path)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
#
|
98
|
+
# Clones and installs a repository into the cache directory.
|
99
|
+
#
|
100
|
+
# @param [String, URI::HTTPS] uri
|
101
|
+
# The URI to clone the repository from.
|
102
|
+
#
|
103
|
+
# @param [String, nil] name
|
104
|
+
# The explicit name of the repository to use. Defaults to the base-name
|
105
|
+
# of the URI's path, sans any `.git` extension.
|
106
|
+
#
|
107
|
+
# @return [Repository]
|
108
|
+
# The newly installed repository.
|
109
|
+
#
|
110
|
+
# @raise [CommandFailed]
|
111
|
+
# One of the `git` commands failed.
|
112
|
+
#
|
113
|
+
# @raise [CommandNotInstalled]
|
114
|
+
# The `git` command is not installed.
|
115
|
+
#
|
116
|
+
def install(uri,name=nil)
|
117
|
+
uri = uri.to_s
|
118
|
+
name ||= File.basename(uri,File.extname(uri))
|
119
|
+
path = File.join(@path,name)
|
120
|
+
|
121
|
+
return Repository.install(uri,path)
|
122
|
+
end
|
123
|
+
|
124
|
+
#
|
125
|
+
# Updates all repositories in the cache directory.
|
126
|
+
#
|
127
|
+
# @raise [CommandNotInstalled]
|
128
|
+
# The `git` command is not installed.
|
129
|
+
#
|
130
|
+
def update
|
131
|
+
each do |repo|
|
132
|
+
begin
|
133
|
+
repo.update
|
134
|
+
rescue CommandFailed
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
#
|
140
|
+
# Removes a repository from the cache directory.
|
141
|
+
#
|
142
|
+
# @param [String] name
|
143
|
+
# The repository name to find and delete.
|
144
|
+
#
|
145
|
+
# @raise [RepositoryNotFound]
|
146
|
+
# The repository with the given name does not exist in the cache
|
147
|
+
# directory.
|
148
|
+
#
|
149
|
+
def remove(name)
|
150
|
+
self[name].delete
|
151
|
+
end
|
152
|
+
|
153
|
+
#
|
154
|
+
# Deletes all repositories in the cache directory.
|
155
|
+
#
|
156
|
+
def purge
|
157
|
+
each(&:delete)
|
158
|
+
end
|
159
|
+
|
160
|
+
#
|
161
|
+
# Finds the first matching file.
|
162
|
+
#
|
163
|
+
# @param [String] path
|
164
|
+
# The relative path of the file.
|
165
|
+
#
|
166
|
+
# @return [String, nil]
|
167
|
+
# The absolute path of the matching file or `nil` if no matching file
|
168
|
+
# could be found.
|
169
|
+
#
|
170
|
+
# @example
|
171
|
+
# repos.find_file("wordlists/wordlist.txt")
|
172
|
+
# # => "/home/user/.cache/ronin-repos/foo-repo/wordlists/wordlist.txt"
|
173
|
+
#
|
174
|
+
def find_file(path)
|
175
|
+
each do |repo|
|
176
|
+
if (file = repo.find_file(path))
|
177
|
+
return file
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
#
|
183
|
+
# Finds all files in all repos that matches the glob pattern.
|
184
|
+
#
|
185
|
+
# @param [String] pattern
|
186
|
+
# The file glob pattern to search for.
|
187
|
+
#
|
188
|
+
# @return [Array<String>]
|
189
|
+
# The absolute paths to the files that match the glob pattern.
|
190
|
+
#
|
191
|
+
# @example
|
192
|
+
# repos.glob("wordlists/*.txt")
|
193
|
+
# # => ["/home/user/.cache/ronin-repos/foo-repo/wordlists/cities.txt",
|
194
|
+
# # "/home/user/.cache/ronin-repos/foo-repo/wordlists/states.txt",
|
195
|
+
# # "/home/user/.cache/ronin-repos/bar-repo/wordlists/bands.txt",
|
196
|
+
# # "/home/user/.cache/ronin-repos/bar-repo/wordlists/beers.txt"]
|
197
|
+
#
|
198
|
+
def glob(pattern,&block)
|
199
|
+
return enum_for(__method__,pattern).to_a unless block_given?
|
200
|
+
|
201
|
+
each do |repo|
|
202
|
+
repo.glob(pattern,&block)
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
#
|
207
|
+
# Lists all files across all repos installed in the cache directory.
|
208
|
+
#
|
209
|
+
# @param [String] pattern
|
210
|
+
# The optional glob pattern to use to list specific files.
|
211
|
+
#
|
212
|
+
# @return [Set<String>]
|
213
|
+
# The matching paths within the repository.
|
214
|
+
#
|
215
|
+
# @example
|
216
|
+
# repos.list_files('exploits/{**/}*.rb')
|
217
|
+
# # => #<Set: {"exploits/exploit1.rb", "exploits/exploit2.rb"}>
|
218
|
+
#
|
219
|
+
def list_files(pattern='{**/}*.*')
|
220
|
+
each_with_object(Set.new) do |repo,files|
|
221
|
+
files.merge(repo.list_files(pattern))
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
#
|
226
|
+
# Converts the cache directory to a String.
|
227
|
+
#
|
228
|
+
# @return [String]
|
229
|
+
# The path to the cache directory.
|
230
|
+
#
|
231
|
+
def to_s
|
232
|
+
@path
|
233
|
+
end
|
234
|
+
|
235
|
+
private
|
236
|
+
|
237
|
+
#
|
238
|
+
# Enumerates over each directory in the cache directory.
|
239
|
+
#
|
240
|
+
# @yield [dir]
|
241
|
+
# The given block will be passed each repository's directory path.
|
242
|
+
#
|
243
|
+
# @yieldparam [String] dir
|
244
|
+
# A path to a repository directory within the cache directory.
|
245
|
+
#
|
246
|
+
# @return [Enumerator]
|
247
|
+
# If no block is given, an Enumerator will be returned.
|
248
|
+
#
|
249
|
+
def each_child_directory
|
250
|
+
return enum_for(__method__) unless block_given?
|
251
|
+
|
252
|
+
if File.directory?(@path)
|
253
|
+
Dir.children(@path).sort.each do |name|
|
254
|
+
path = File.join(@path,name)
|
255
|
+
|
256
|
+
if File.directory?(path)
|
257
|
+
yield path
|
258
|
+
end
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
return nil
|
263
|
+
end
|
264
|
+
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
@@ -0,0 +1,150 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# Copyright (c) 2021 Hal Brodigan (postmodern.mod3 at gmail.com)
|
4
|
+
#
|
5
|
+
# ronin-repos 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-repos 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-repos. If not, see <https://www.gnu.org/licenses/>.
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'ronin/repos'
|
20
|
+
require 'ronin/core/class_registry'
|
21
|
+
|
22
|
+
require 'set'
|
23
|
+
|
24
|
+
module Ronin
|
25
|
+
module Repos
|
26
|
+
#
|
27
|
+
# Adds the ability to load classes from directories within installed
|
28
|
+
# repositories.
|
29
|
+
#
|
30
|
+
# ## Example
|
31
|
+
#
|
32
|
+
# `lib/ronin/exploits.rb`:
|
33
|
+
#
|
34
|
+
# require 'ronin/core/module_registry'
|
35
|
+
# require 'ronin/repos/class_dir'
|
36
|
+
#
|
37
|
+
# module Ronin
|
38
|
+
# module Exploits
|
39
|
+
# include Ronin::Core::ClassRegistry
|
40
|
+
# include Ronin::Repos::ClassDir
|
41
|
+
#
|
42
|
+
# class_dir "#{__dir__}/classes"
|
43
|
+
# repo_class_dir "exploits"
|
44
|
+
# end
|
45
|
+
# end
|
46
|
+
#
|
47
|
+
# `lib/ronin/exploits/exploit.rb`:
|
48
|
+
#
|
49
|
+
# module Ronin
|
50
|
+
# module Exploits
|
51
|
+
# class Exploit
|
52
|
+
#
|
53
|
+
# def self.register(name)
|
54
|
+
# Exploits.register(name,self)
|
55
|
+
# end
|
56
|
+
#
|
57
|
+
# end
|
58
|
+
# end
|
59
|
+
# end
|
60
|
+
#
|
61
|
+
# `~/.cache/ronin-repos/repo1/exploits/my_exploit.rb`:
|
62
|
+
#
|
63
|
+
# require 'ronin/exploits/exploit'
|
64
|
+
#
|
65
|
+
# module Ronin
|
66
|
+
# module Exploits
|
67
|
+
# class MyExploit < Exploit
|
68
|
+
#
|
69
|
+
# register 'my_exploit'
|
70
|
+
#
|
71
|
+
# end
|
72
|
+
# end
|
73
|
+
# end
|
74
|
+
#
|
75
|
+
# @api semipublic
|
76
|
+
#
|
77
|
+
module ClassDir
|
78
|
+
#
|
79
|
+
# Includes `Ronin::Core::ClassRegistry` and adds {ClassMethods}.
|
80
|
+
#
|
81
|
+
# @param [Module] namespace
|
82
|
+
# The module that is including {ClassDir}.
|
83
|
+
#
|
84
|
+
# @api private
|
85
|
+
#
|
86
|
+
def self.included(namespace)
|
87
|
+
namespace.send :include, Core::ClassRegistry
|
88
|
+
namespace.extend ClassMethods
|
89
|
+
end
|
90
|
+
|
91
|
+
module ClassMethods
|
92
|
+
#
|
93
|
+
# Gets or sets the repository module directory name.
|
94
|
+
#
|
95
|
+
# @param [String, nil] new_dir
|
96
|
+
# The new module directory path.
|
97
|
+
#
|
98
|
+
# @return [String]
|
99
|
+
# The repository module directory name.
|
100
|
+
#
|
101
|
+
# @raise [NotImplementedError]
|
102
|
+
# The `repo_class_dir` method was not defined in the module.
|
103
|
+
#
|
104
|
+
# @example
|
105
|
+
# repo_class_dir "exploits"
|
106
|
+
#
|
107
|
+
def repo_class_dir(new_dir=nil)
|
108
|
+
if new_dir
|
109
|
+
@repo_class_dir = new_dir
|
110
|
+
else
|
111
|
+
@repo_class_dir || raise(NotImplementedError,"#{self} did not define a repo_class_dir")
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
#
|
116
|
+
# List the module names within the `class_dir` and within
|
117
|
+
# {#repo_class_dir} across all installed repositories.
|
118
|
+
#
|
119
|
+
# @return [Array<String>]
|
120
|
+
#
|
121
|
+
def list_files
|
122
|
+
modules = Set.new(super)
|
123
|
+
pattern = File.join(repo_class_dir,"{**/}*.rb")
|
124
|
+
|
125
|
+
Repos.list_files(pattern).each do |path|
|
126
|
+
modules << path.chomp('.rb')
|
127
|
+
end
|
128
|
+
|
129
|
+
return modules.to_a
|
130
|
+
end
|
131
|
+
|
132
|
+
#
|
133
|
+
# Finds a module within `class_dir` or within `repo_class_dir`
|
134
|
+
# in one of the installed repositories.
|
135
|
+
#
|
136
|
+
# @param [String] name
|
137
|
+
# The module name to lookup.
|
138
|
+
#
|
139
|
+
# @return [String, nil]
|
140
|
+
# The path to the module or `nil` if the module could not be found
|
141
|
+
# in `class_dir` or any of the installed repositories.
|
142
|
+
#
|
143
|
+
def path_for(name)
|
144
|
+
super(name) ||
|
145
|
+
Repos.find_file(File.join(repo_class_dir,"#{name}.rb"))
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# Copyright (c) 2021 Hal Brodigan (postmodern.mod3 at gmail.com)
|
4
|
+
#
|
5
|
+
# ronin-repos 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-repos 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-repos. If not, see <https://www.gnu.org/licenses/>.
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'ronin/repos/root'
|
20
|
+
require 'ronin/repos/cache_dir'
|
21
|
+
|
22
|
+
require 'ronin/core/cli/command'
|
23
|
+
|
24
|
+
module Ronin
|
25
|
+
module Repos
|
26
|
+
class CLI
|
27
|
+
class Command < Core::CLI::Command
|
28
|
+
|
29
|
+
man_dir File.join(ROOT,'man')
|
30
|
+
|
31
|
+
bug_report_url 'https://github.com/ronin-rb/ronin-repos/issues/new'
|
32
|
+
|
33
|
+
option :cache_dir, short: '-C',
|
34
|
+
value: {
|
35
|
+
type: String,
|
36
|
+
usage: 'DIR'
|
37
|
+
},
|
38
|
+
desc: 'Overrides the default cache directory' do |dir|
|
39
|
+
@cache_dir = CacheDir.new(dir)
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
# The ronin-repos cache directory.
|
44
|
+
#
|
45
|
+
# @return [CacheDir]
|
46
|
+
attr_reader :cache_dir
|
47
|
+
|
48
|
+
#
|
49
|
+
# Initializes the command.
|
50
|
+
#
|
51
|
+
# @param [Hash{Symbol => Object}] kwargs
|
52
|
+
# Additional keyword arguments for `initialize`.
|
53
|
+
#
|
54
|
+
def initialize(**kwargs)
|
55
|
+
super(**kwargs)
|
56
|
+
|
57
|
+
@cache_dir = CacheDir.new
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# Copyright (c) 2021 Hal Brodigan (postmodern.mod3 at gmail.com)
|
4
|
+
#
|
5
|
+
# ronin-repos 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-repos 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-repos. If not, see <https://www.gnu.org/licenses/>.
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'ronin/repos/cli/command'
|
20
|
+
|
21
|
+
module Ronin
|
22
|
+
module Repos
|
23
|
+
class CLI
|
24
|
+
module Commands
|
25
|
+
#
|
26
|
+
# Installs a git repository into the cache directory.
|
27
|
+
#
|
28
|
+
# ## Usage
|
29
|
+
#
|
30
|
+
# ronin-repos install [options] [REPO]
|
31
|
+
#
|
32
|
+
# ## Options
|
33
|
+
#
|
34
|
+
# -C, --cache-dir DIR Overrides the default cache directory
|
35
|
+
# -h, --help Print help information
|
36
|
+
#
|
37
|
+
# ## Arguments
|
38
|
+
#
|
39
|
+
# URI URI of the git repository
|
40
|
+
#
|
41
|
+
class Install < Command
|
42
|
+
|
43
|
+
usage '[options] URI'
|
44
|
+
|
45
|
+
argument :uri, required: true,
|
46
|
+
usage: 'URI',
|
47
|
+
desc: 'URI of the git repository'
|
48
|
+
|
49
|
+
description 'Installs a git repository into the cache directory'
|
50
|
+
|
51
|
+
man_page 'ronin-repos-install.1'
|
52
|
+
|
53
|
+
#
|
54
|
+
# Runs the `ronin-repos install` command.
|
55
|
+
#
|
56
|
+
# @param [String] uri
|
57
|
+
# The repository's git URI to install from.
|
58
|
+
#
|
59
|
+
def run(uri)
|
60
|
+
log_info "Installing repository from #{uri} ..."
|
61
|
+
cache_dir.download(uri)
|
62
|
+
rescue CommandFailed => error
|
63
|
+
print_error(error.message)
|
64
|
+
exit(-1)
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# Copyright (c) 2021 Hal Brodigan (postmodern.mod3 at gmail.com)
|
4
|
+
#
|
5
|
+
# ronin-repos 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-repos 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-repos. If not, see <https://www.gnu.org/licenses/>.
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'ronin/repos/cli/command'
|
20
|
+
|
21
|
+
module Ronin
|
22
|
+
module Repos
|
23
|
+
class CLI
|
24
|
+
module Commands
|
25
|
+
#
|
26
|
+
# Lists all repositories in the cache directory.
|
27
|
+
#
|
28
|
+
# ## Usage
|
29
|
+
#
|
30
|
+
# ronin-repos list [options] [REPO]
|
31
|
+
#
|
32
|
+
# ## Options
|
33
|
+
#
|
34
|
+
# -C, --cache-dir DIR Overrides the default cache directory
|
35
|
+
# -h, --help Print help information
|
36
|
+
#
|
37
|
+
# ## Arguments
|
38
|
+
#
|
39
|
+
# [REPO] Optional repository name to list
|
40
|
+
#
|
41
|
+
class List < Command
|
42
|
+
|
43
|
+
usage '[options] [REPO]'
|
44
|
+
|
45
|
+
argument :name, required: false,
|
46
|
+
usage: 'REPO',
|
47
|
+
desc: 'Optional repository name to list'
|
48
|
+
|
49
|
+
description 'Lists all repositories in the cache directory'
|
50
|
+
|
51
|
+
man_page 'ronin-repos-list.1'
|
52
|
+
|
53
|
+
#
|
54
|
+
# Runs the `ronin-repos list` command.
|
55
|
+
#
|
56
|
+
# @param [String, nil] name
|
57
|
+
# The optional repo name to list.
|
58
|
+
#
|
59
|
+
def run(name=nil)
|
60
|
+
if name
|
61
|
+
begin
|
62
|
+
repo = cache_dir[name]
|
63
|
+
|
64
|
+
puts " #{repo}"
|
65
|
+
rescue RepositoryNotFound => error
|
66
|
+
print_error(error.message)
|
67
|
+
exit(-1)
|
68
|
+
end
|
69
|
+
else
|
70
|
+
cache_dir.each do |repo|
|
71
|
+
puts " #{repo}"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# Copyright (c) 2021 Hal Brodigan (postmodern.mod3 at gmail.com)
|
4
|
+
#
|
5
|
+
# ronin-repos 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-repos 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-repos. If not, see <https://www.gnu.org/licenses/>.
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'ronin/repos/cli/command'
|
20
|
+
require 'ronin/repos/root'
|
21
|
+
|
22
|
+
require 'ronin/core/cli/generator'
|
23
|
+
require 'ronin/core/git'
|
24
|
+
|
25
|
+
module Ronin
|
26
|
+
module Repos
|
27
|
+
class CLI
|
28
|
+
module Commands
|
29
|
+
#
|
30
|
+
# Creates a new git repository.
|
31
|
+
#
|
32
|
+
# ## Usage
|
33
|
+
#
|
34
|
+
# ronin-repos new [options] PATH
|
35
|
+
#
|
36
|
+
# ## Options
|
37
|
+
#
|
38
|
+
# -C, --cache-dir DIR Overrides the default cache directory
|
39
|
+
# -h, --help Print help information
|
40
|
+
#
|
41
|
+
# ## Arguments
|
42
|
+
#
|
43
|
+
# PATH The path to the new repository
|
44
|
+
#
|
45
|
+
class New < Command
|
46
|
+
|
47
|
+
include Core::CLI::Generator
|
48
|
+
|
49
|
+
template_dir File.join(ROOT,'data','templates','repo')
|
50
|
+
|
51
|
+
usage '[options] PATH'
|
52
|
+
|
53
|
+
argument :path, desc: 'The path to the new repository'
|
54
|
+
|
55
|
+
description 'Creates a new git repository'
|
56
|
+
|
57
|
+
man_page 'ronin-repos.1'
|
58
|
+
|
59
|
+
#
|
60
|
+
# Runs the `ronin-repos new` command.
|
61
|
+
#
|
62
|
+
# @param [String] path
|
63
|
+
# The path to the new repo directory to create.
|
64
|
+
#
|
65
|
+
def run(path)
|
66
|
+
@name = File.basename(path)
|
67
|
+
@github_user = Core::Git.github_user || ENV['USER']
|
68
|
+
|
69
|
+
mkdir path
|
70
|
+
erb 'README.md.erb', File.join(path,'README.md')
|
71
|
+
|
72
|
+
Dir.chdir(path) do
|
73
|
+
sh 'git', 'init', '-q', '-b', 'main'
|
74
|
+
sh 'git', 'add', 'README.md'
|
75
|
+
sh 'git', 'commit', '-q', '-m', 'Initial commit.'
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|