mspac 0.1.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.
- checksums.yaml +7 -0
- data/bin/mspac +248 -0
- data/lib/mspac.rb +177 -0
- data/lib/mspac/error.rb +10 -0
- data/lib/mspac/error/invalid_operation_error.rb +5 -0
- data/lib/mspac/error/missing_pellet_error.rb +9 -0
- data/lib/mspac/error/multiple_operations_error.rb +5 -0
- data/lib/mspac/error/pellet_not_installed_error.rb +5 -0
- data/lib/mspac/error/pellet_repo_error.rb +5 -0
- data/lib/mspac/error/unsupported_package_manager_error.rb +5 -0
- data/lib/mspac/error/unsupported_vcs_error.rb +5 -0
- data/lib/mspac/package_manager.rb +57 -0
- data/lib/mspac/pellet.rb +170 -0
- data/lib/mspac/version_control.rb +49 -0
- data/lib/string.rb +32 -0
- metadata +82 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f11225e1ee515b02e7fae345ed72edc3ab734635
|
4
|
+
data.tar.gz: 24864d1e8f46ea0092b60766740dbb7c88496d32
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 37d5dbb4644156f768cae5c31accca659b3ef7710d168fe56f631e196e600b4d9785b3e00118d48f1a00c69248fdfb08033d0157729ab2a0dc6dfcc2d82b56dd
|
7
|
+
data.tar.gz: f3260122855734fb191536a3b1db047a33e50f61ca6f4234fe6771659131e38e3becf9d9d55b1359399a310c346a4ed6c3fde7e79a3bc4819f166845eedd489c
|
data/bin/mspac
ADDED
@@ -0,0 +1,248 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "mspac"
|
4
|
+
require "optparse"
|
5
|
+
require "string"
|
6
|
+
|
7
|
+
class MsPacExit
|
8
|
+
GOOD = 0
|
9
|
+
INVALID_OPTION = 1
|
10
|
+
INVALID_ARGUMENT = 2
|
11
|
+
MISSING_ARGUMENT = 3
|
12
|
+
INVALID_OPERATION = 4
|
13
|
+
MULTIPLE_OPERATIONS = 5
|
14
|
+
EXCEPTION = 6
|
15
|
+
end
|
16
|
+
|
17
|
+
class Operation
|
18
|
+
LIST_CACHED = 1
|
19
|
+
LIST_INSTALLED = 2
|
20
|
+
LIST_PELLETS = 3
|
21
|
+
LOCK = 4
|
22
|
+
REMOVE = 5
|
23
|
+
SYNC = 6
|
24
|
+
UNLOCK = 7
|
25
|
+
end
|
26
|
+
|
27
|
+
def parse(args)
|
28
|
+
options = Hash.new
|
29
|
+
options["clean"] = false
|
30
|
+
options["force"] = false
|
31
|
+
options["nosave"] = false
|
32
|
+
options["operation"] = nil
|
33
|
+
options["refresh"] = false
|
34
|
+
options["upgrade"] = false
|
35
|
+
|
36
|
+
parser = OptionParser.new do |opts|
|
37
|
+
opts.banner =
|
38
|
+
"Usage: #{File.basename($0)} <operation> [OPTIONS] " \
|
39
|
+
"[pellets]"
|
40
|
+
|
41
|
+
opts.on("", "OPERATIONS")
|
42
|
+
|
43
|
+
opts.on("-h", "--help", "Display this help message") do
|
44
|
+
puts opts
|
45
|
+
exit
|
46
|
+
end
|
47
|
+
|
48
|
+
opts.on("--list-cached", "List cached pellets") do
|
49
|
+
options["operation"] = Operation::LIST_CACHED
|
50
|
+
end
|
51
|
+
|
52
|
+
opts.on("--list-installed", "List installed pellets") do
|
53
|
+
options["operation"] = Operation::LIST_INSTALLED
|
54
|
+
end
|
55
|
+
|
56
|
+
opts.on("--list-pellets", "List available pellets") do
|
57
|
+
options["operation"] = Operation::LIST_PELLETS
|
58
|
+
end
|
59
|
+
|
60
|
+
opts.on(
|
61
|
+
"-L",
|
62
|
+
"--lock",
|
63
|
+
"Lock a pellet at it's current version"
|
64
|
+
) do
|
65
|
+
if (options["operation"])
|
66
|
+
puts opts
|
67
|
+
exit MsPacExit::MULTIPLE_OPERATIONS
|
68
|
+
end
|
69
|
+
options["operation"] = Operation::LOCK
|
70
|
+
end
|
71
|
+
|
72
|
+
opts.on("-R", "--remove", "Remove pellets") do
|
73
|
+
if (options["operation"])
|
74
|
+
puts opts
|
75
|
+
exit MsPacExit::MULTIPLE_OPERATIONS
|
76
|
+
end
|
77
|
+
options["operation"] = Operation::REMOVE
|
78
|
+
end
|
79
|
+
|
80
|
+
opts.on("-S", "--sync", "Synchronize pellets") do
|
81
|
+
if (options["operation"])
|
82
|
+
puts opts
|
83
|
+
exit MsPacExit::MULTIPLE_OPERATIONS
|
84
|
+
end
|
85
|
+
options["operation"] = Operation::SYNC
|
86
|
+
end
|
87
|
+
|
88
|
+
opts.on("-U", "--unlock", "Unlock a pellet") do
|
89
|
+
if (options["operation"])
|
90
|
+
puts opts
|
91
|
+
exit MsPacExit::MULTIPLE_OPERATIONS
|
92
|
+
end
|
93
|
+
options["operation"] = Operation::UNLOCK
|
94
|
+
end
|
95
|
+
|
96
|
+
opts.on("", "SYNC OPTIONS")
|
97
|
+
|
98
|
+
opts.on(
|
99
|
+
"-c",
|
100
|
+
"--clean",
|
101
|
+
"Remove pellets that are no longer installed",
|
102
|
+
"from the cache"
|
103
|
+
) do
|
104
|
+
if (options["operation"] == Operation::SYNC)
|
105
|
+
options["clean"] = true
|
106
|
+
else
|
107
|
+
puts opts
|
108
|
+
exit MsPacExit::INVALID_OPERATION
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
opts.on(
|
113
|
+
"-f",
|
114
|
+
"--force",
|
115
|
+
"Force a reinstall/recompilation of the pellet"
|
116
|
+
) do
|
117
|
+
if (options["operation"] == Operation::SYNC)
|
118
|
+
options["force"] = true
|
119
|
+
else
|
120
|
+
puts opts
|
121
|
+
exit MsPacExit::INVALID_OPERATION
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
opts.on(
|
126
|
+
"-s",
|
127
|
+
"--search=regex",
|
128
|
+
"Search each pellet for names matching the",
|
129
|
+
"provided regex and display them"
|
130
|
+
) do |regex|
|
131
|
+
if (
|
132
|
+
(options["operation"] == Operation::SYNC) &&
|
133
|
+
!options["upgrade"]
|
134
|
+
)
|
135
|
+
options["regex"] = regex
|
136
|
+
else
|
137
|
+
puts opts
|
138
|
+
exit MsPacExit::INVALID_OPERATION
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
opts.on("-u", "--sysupgrade", "Upgrade all pellets") do
|
143
|
+
if (
|
144
|
+
(options["operation"] == Operation::SYNC) &&
|
145
|
+
!options.has_key?("regex")
|
146
|
+
)
|
147
|
+
options["upgrade"] = true
|
148
|
+
else
|
149
|
+
puts opts
|
150
|
+
exit MsPacExit::INVALID_OPERATION
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
opts.on("-y", "--refresh", "Refresh available pellets") do
|
155
|
+
if (options["operation"] == Operation::SYNC)
|
156
|
+
options["refresh"] = true
|
157
|
+
else
|
158
|
+
puts opts
|
159
|
+
exit MsPacExit::INVALID_OPERATION
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
opts.on("", "REMOVE OPTIONS")
|
164
|
+
|
165
|
+
opts.on(
|
166
|
+
"-n",
|
167
|
+
"--nosave",
|
168
|
+
"Completely remove pellet"
|
169
|
+
) do
|
170
|
+
if (options["operation"] == Operation::REMOVE)
|
171
|
+
options["nosave"] = true
|
172
|
+
else
|
173
|
+
puts opts
|
174
|
+
exit MsPacExit::INVALID_OPERATION
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
begin
|
180
|
+
parser.parse!
|
181
|
+
rescue OptionParser::InvalidOption => e
|
182
|
+
puts e.message
|
183
|
+
puts parser
|
184
|
+
exit MsPacExit::INVALID_OPTION
|
185
|
+
rescue OptionParser::InvalidArgument => e
|
186
|
+
puts e.message
|
187
|
+
puts parser
|
188
|
+
exit MsPacExit::INVALID_ARGUMENT
|
189
|
+
rescue OptionParser::MissingArgument => e
|
190
|
+
puts e.message
|
191
|
+
puts parser
|
192
|
+
exit MsPacExit::MISSING_ARGUMENT
|
193
|
+
end
|
194
|
+
|
195
|
+
options["pellets"] = args
|
196
|
+
|
197
|
+
if (options.has_key?("regex") && !options["pellets"].empty?)
|
198
|
+
puts parser
|
199
|
+
exit MsPacExit::INVALID_OPERATION
|
200
|
+
end
|
201
|
+
|
202
|
+
return options
|
203
|
+
end
|
204
|
+
|
205
|
+
# Parse CLI args
|
206
|
+
options = parse(ARGV)
|
207
|
+
|
208
|
+
begin
|
209
|
+
mspac = MsPac.new
|
210
|
+
|
211
|
+
case options["operation"]
|
212
|
+
when Operation::LIST_CACHED
|
213
|
+
puts mspac.cached
|
214
|
+
when Operation::LIST_INSTALLED
|
215
|
+
puts mspac.installed
|
216
|
+
when Operation::LIST_PELLETS
|
217
|
+
puts mspac.pellets
|
218
|
+
when Operation::LOCK
|
219
|
+
mspac.lock(options["pellets"])
|
220
|
+
when Operation::REMOVE
|
221
|
+
mspac.remove(options["pellets"], options["nosave"])
|
222
|
+
when Operation::SYNC
|
223
|
+
mspac.clean if (options["clean"])
|
224
|
+
mspac.refresh if (options["refresh"])
|
225
|
+
|
226
|
+
if (options.has_key?("regex"))
|
227
|
+
mspac.search(options["regex"])
|
228
|
+
elsif (options["upgrade"])
|
229
|
+
mspac.upgrade
|
230
|
+
else
|
231
|
+
if (
|
232
|
+
!options["refresh"] ||
|
233
|
+
(options["pellets"] && !options["pellets"].empty?)
|
234
|
+
)
|
235
|
+
mspac.install(options["pellets"], options["force"])
|
236
|
+
end
|
237
|
+
end
|
238
|
+
when Operation::UNLOCK
|
239
|
+
mspac.unlock(options["pellets"])
|
240
|
+
end
|
241
|
+
exit MsPacExit::GOOD
|
242
|
+
rescue MsPac::Error => e
|
243
|
+
puts e.message.red
|
244
|
+
exit MsPacExit::EXCEPTION
|
245
|
+
rescue Interrupt => e
|
246
|
+
# ^C
|
247
|
+
puts
|
248
|
+
end
|
data/lib/mspac.rb
ADDED
@@ -0,0 +1,177 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
require "json"
|
3
|
+
require "pathname"
|
4
|
+
require "scoobydoo"
|
5
|
+
require "string"
|
6
|
+
|
7
|
+
class MsPac
|
8
|
+
def cached
|
9
|
+
return @pellets.keys.sort.delete_if do |name|
|
10
|
+
!@pellets[name].cached?
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def clean
|
15
|
+
@pellets.each do |name, pellet|
|
16
|
+
pellet.purge if (pellet.cached? && !pellet.installed?)
|
17
|
+
end
|
18
|
+
# FIXME will miss pellets that get deleted by refresh
|
19
|
+
end
|
20
|
+
|
21
|
+
def ensure_pellets_repo
|
22
|
+
@pellets_dir = Pathname.new("~/.mspac/pellets").expand_path
|
23
|
+
return if (@pellets_dir && @pellets_dir.exist?)
|
24
|
+
|
25
|
+
puts "Installing MsPac dependencies...".white
|
26
|
+
@pm.install(["git"]) if (ScoobyDoo.where_are_you("git").nil?)
|
27
|
+
Dir.chdir(@mspac_dir) do
|
28
|
+
@vcs.clone("https://gitlab.com/mjwhitta/pellets.git")
|
29
|
+
end
|
30
|
+
|
31
|
+
@pellets_dir = Pathname.new("~/.mspac/pellets").expand_path
|
32
|
+
if (@pellets_dir.nil? || !@pellets_dir.exist?)
|
33
|
+
raise Error::PelletRepoError.new
|
34
|
+
end
|
35
|
+
end
|
36
|
+
private :ensure_pellets_repo
|
37
|
+
|
38
|
+
def initialize
|
39
|
+
FileUtils.mkdir_p(Pathname.new("~/.mspac").expand_path)
|
40
|
+
@mspac_dir = Pathname.new("~/.mspac").expand_path
|
41
|
+
@pm = PackageManager.new
|
42
|
+
@vcs = VersionControl.new("git")
|
43
|
+
load_pellets
|
44
|
+
end
|
45
|
+
|
46
|
+
def install(pellets, force = false)
|
47
|
+
if (pellets.nil? || pellets.empty?)
|
48
|
+
raise Error::MissingPelletError.new
|
49
|
+
end
|
50
|
+
|
51
|
+
pellets.each do |name|
|
52
|
+
if (@pellets.has_key?(name))
|
53
|
+
pellet = @pellets[name]
|
54
|
+
if (pellet.installed?)
|
55
|
+
pellet.update(force)
|
56
|
+
elsif (pellet.cached?)
|
57
|
+
pellet.link
|
58
|
+
pellet.update(true)
|
59
|
+
else
|
60
|
+
pellet.fetch
|
61
|
+
pellet.install
|
62
|
+
end
|
63
|
+
else
|
64
|
+
raise Error::MissingPelletError.new(name)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def installed
|
70
|
+
return @pellets.keys.sort.delete_if do |name|
|
71
|
+
!@pellets[name].installed?
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def load_pellets
|
76
|
+
ensure_pellets_repo
|
77
|
+
|
78
|
+
@pellets = Hash.new
|
79
|
+
Dir["#{@pellets_dir}/*.pellet"].each do |pellet|
|
80
|
+
begin
|
81
|
+
p = Pellet.new(JSON.parse(File.read(pellet)))
|
82
|
+
@pellets[p.name] = p
|
83
|
+
rescue JSON::ParserError => e
|
84
|
+
puts "#{pellet} is not valid JSON!".red
|
85
|
+
puts e.message.red
|
86
|
+
rescue Exception => e
|
87
|
+
puts e.message.red
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
private :load_pellets
|
92
|
+
|
93
|
+
def lock(pellets)
|
94
|
+
if (pellets.nil? || pellets.empty?)
|
95
|
+
raise Error::MissingPelletError.new
|
96
|
+
end
|
97
|
+
|
98
|
+
pellets.each do |name|
|
99
|
+
if (@pellets.has_key?(name))
|
100
|
+
@pellets[name].lock
|
101
|
+
else
|
102
|
+
raise Error::MissingPelletError.new(name)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def pellets
|
108
|
+
return @pellets.keys.sort
|
109
|
+
end
|
110
|
+
|
111
|
+
def refresh
|
112
|
+
puts "Refreshing pellets...".white
|
113
|
+
Dir.chdir(@pellets_dir) do
|
114
|
+
@vcs.update
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def remove(pellets, nosave)
|
119
|
+
if (pellets.nil? || pellets.empty?)
|
120
|
+
raise Error::MissingPelletError.new
|
121
|
+
end
|
122
|
+
|
123
|
+
pellets.each do |name|
|
124
|
+
if (@pellets.has_key?(name))
|
125
|
+
@pellets[name].remove(nosave)
|
126
|
+
else
|
127
|
+
raise Error::MissingPelletError.new(name)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def search(regex)
|
133
|
+
@pellets.keys.sort.each do |name|
|
134
|
+
pellet = @pellets[name]
|
135
|
+
name_match = pellet.name.match(/#{regex}/)
|
136
|
+
desc_match = pellet.desc.match(/#{regex}/)
|
137
|
+
if (name_match || desc_match)
|
138
|
+
print "#{pellet.name}".white
|
139
|
+
if (pellet.installed?)
|
140
|
+
puts " [installed]".green
|
141
|
+
elsif (pellet.cached?)
|
142
|
+
puts " [cached]".blue
|
143
|
+
else
|
144
|
+
puts
|
145
|
+
end
|
146
|
+
puts " #{pellet.repo}"
|
147
|
+
puts " #{pellet.desc}"
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def unlock(pellets)
|
153
|
+
if (pellets.nil? || pellets.empty?)
|
154
|
+
raise Error::MissingPelletError.new
|
155
|
+
end
|
156
|
+
|
157
|
+
pellets.each do |name|
|
158
|
+
if (@pellets.has_key?(name))
|
159
|
+
@pellets[name].unlock
|
160
|
+
else
|
161
|
+
raise Error::MissingPelletError.new(name)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def upgrade
|
167
|
+
@pellets.keys.sort.each do |name|
|
168
|
+
pellet = @pellets[name]
|
169
|
+
pellet.update if (pellet.installed?)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
require "mspac/error"
|
175
|
+
require "mspac/package_manager"
|
176
|
+
require "mspac/pellet"
|
177
|
+
require "mspac/version_control"
|
data/lib/mspac/error.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
class MsPac::Error < RuntimeError
|
2
|
+
end
|
3
|
+
|
4
|
+
require "mspac/error/invalid_operation_error"
|
5
|
+
require "mspac/error/missing_pellet_error"
|
6
|
+
require "mspac/error/multiple_operations_error"
|
7
|
+
require "mspac/error/pellet_not_installed_error"
|
8
|
+
require "mspac/error/pellet_repo_error"
|
9
|
+
require "mspac/error/unsupported_package_manager_error"
|
10
|
+
require "mspac/error/unsupported_vcs_error"
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require "scoobydoo"
|
2
|
+
|
3
|
+
class MsPac::PackageManager
|
4
|
+
attr_reader :pkgmgr
|
5
|
+
|
6
|
+
def alt_install(packages, pkgmgr = @pkgmgr)
|
7
|
+
return if (packages.nil? || packages.empty?)
|
8
|
+
packages.each do |pkg|
|
9
|
+
pkgmgr_install(pkg, pkgmgr)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
if (ScoobyDoo.where_are_you("apt-get"))
|
15
|
+
@pkgmgr = "apt-get"
|
16
|
+
elsif (ScoobyDoo.where_are_you("brew"))
|
17
|
+
raise Error::UnsupportedPackageManagerError.new("brew")
|
18
|
+
elsif (ScoobyDoo.where_are_you("pacman"))
|
19
|
+
@pkgmgr = "pacman"
|
20
|
+
elsif (ScoobyDoo.where_are_you("yum"))
|
21
|
+
raise Error::UnsupportedPackageManagerError.new("yum")
|
22
|
+
elsif (ScoobyDoo.where_are_you("zipper"))
|
23
|
+
raise Error::UnsupportedPackageManagerError.new("zipper")
|
24
|
+
else
|
25
|
+
raise Error::UnsupportedPackageManagerError.new
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def install(packages, pkgmgr = @pkgmgr)
|
30
|
+
return if (packages.nil? || packages.empty?)
|
31
|
+
pkgmgr_install(packages.join(" "), pkgmgr)
|
32
|
+
end
|
33
|
+
|
34
|
+
def pkgmgr_install(pkgs, pkgmgr = @pkgmgr)
|
35
|
+
case pkgmgr
|
36
|
+
when "apt-get"
|
37
|
+
system("sudo apt-get install -y #{pkgs}")
|
38
|
+
when "brew"
|
39
|
+
raise Error::UnsupportedPackageManagerError.new("brew")
|
40
|
+
when "pacman"
|
41
|
+
system("sudo pacman --needed --noconfirm -S #{pkgs}")
|
42
|
+
when "perl"
|
43
|
+
system("sudo cpan #{pkgs}")
|
44
|
+
when "python2"
|
45
|
+
system("python2 -m pip install #{pkgs}")
|
46
|
+
when "python3"
|
47
|
+
system("python3 -m pip install #{pkgs}")
|
48
|
+
when "yum"
|
49
|
+
raise Error::UnsupportedPackageManagerError.new("yum")
|
50
|
+
when "zipper"
|
51
|
+
raise Error::UnsupportedPackageManagerError.new("zipper")
|
52
|
+
else
|
53
|
+
raise Error::UnsupportedPackageManagerError.new
|
54
|
+
end
|
55
|
+
end
|
56
|
+
private :pkgmgr_install
|
57
|
+
end
|
data/lib/mspac/pellet.rb
ADDED
@@ -0,0 +1,170 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
require "string"
|
3
|
+
|
4
|
+
class MsPac::Pellet < Hash
|
5
|
+
@@cache_dir = Pathname("~/.mspac/cache").expand_path
|
6
|
+
@@install_dir = Pathname("~/.mspac/installed").expand_path
|
7
|
+
|
8
|
+
def initialize(json)
|
9
|
+
json.keys.each do |key|
|
10
|
+
self[key] = json[key]
|
11
|
+
end
|
12
|
+
|
13
|
+
@pm = MsPac::PackageManager.new
|
14
|
+
@vcs = MsPac::VersionControl.new(self["vcs"])
|
15
|
+
end
|
16
|
+
|
17
|
+
def cached?
|
18
|
+
Pathname.new("#{@@cache_dir}/#{name}").expand_path.exist?
|
19
|
+
end
|
20
|
+
|
21
|
+
def compile
|
22
|
+
return if (self["compile"].empty?)
|
23
|
+
puts "Compiling #{name}...".white
|
24
|
+
execute("compile")
|
25
|
+
end
|
26
|
+
private :compile
|
27
|
+
|
28
|
+
def desc
|
29
|
+
return self["desc"]
|
30
|
+
end
|
31
|
+
|
32
|
+
def execute(operation)
|
33
|
+
Dir.chdir("#{@@install_dir}/#{name}") do
|
34
|
+
system(self[operation].join("; "))
|
35
|
+
end if (!self[operation].empty?)
|
36
|
+
end
|
37
|
+
private :execute
|
38
|
+
|
39
|
+
def fetch
|
40
|
+
FileUtils.mkdir_p(@@cache_dir)
|
41
|
+
FileUtils.mkdir_p(@@install_dir)
|
42
|
+
|
43
|
+
get_deps
|
44
|
+
|
45
|
+
puts "Fetching #{name}...".white
|
46
|
+
if (Pathname.new("#{@@cache_dir}/#{name}").expand_path.exist?)
|
47
|
+
Dir.chdir("#{@@cache_dir}/#{name}") do
|
48
|
+
@vcs.update
|
49
|
+
end
|
50
|
+
else
|
51
|
+
Dir.chdir(@@cache_dir) do
|
52
|
+
@vcs.clone(self["repo"])
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def get_deps
|
58
|
+
puts "Installing dependencies...".white
|
59
|
+
@pm.install([self["vcs"]].concat(self["deps"][@pm.pkgmgr]))
|
60
|
+
@pm.install(self["deps"]["perl"], "perl")
|
61
|
+
@pm.install(self["deps"]["python2"], "python2")
|
62
|
+
@pm.install(self["deps"]["python3"], "python3")
|
63
|
+
end
|
64
|
+
private :get_deps
|
65
|
+
|
66
|
+
def install
|
67
|
+
if (!cached?)
|
68
|
+
raise MsPac::Error::PelletNotInstalledError.new(name)
|
69
|
+
end
|
70
|
+
|
71
|
+
link if (!installed?)
|
72
|
+
compile
|
73
|
+
|
74
|
+
puts "Installing #{name}...".white
|
75
|
+
execute("install")
|
76
|
+
end
|
77
|
+
|
78
|
+
def installed?
|
79
|
+
Pathname.new("#{@@install_dir}/#{name}").expand_path.exist?
|
80
|
+
end
|
81
|
+
|
82
|
+
def link
|
83
|
+
if (!cached?)
|
84
|
+
raise MsPac::Error::PelletNotInstalledError.new(name)
|
85
|
+
end
|
86
|
+
|
87
|
+
puts "Linking #{name}...".white
|
88
|
+
FileUtils.ln_sf(
|
89
|
+
"#{@@cache_dir}/#{name}",
|
90
|
+
"#{@@install_dir}/#{name}"
|
91
|
+
)
|
92
|
+
end
|
93
|
+
|
94
|
+
def lock
|
95
|
+
if (!installed?)
|
96
|
+
raise MsPac::Error::PelletNotInstalledError.new(name)
|
97
|
+
end
|
98
|
+
|
99
|
+
puts "Locking #{name}...".white
|
100
|
+
FileUtils.touch("#{@@install_dir}/#{name}/.mspac_lock")
|
101
|
+
end
|
102
|
+
|
103
|
+
def name
|
104
|
+
return self["name"]
|
105
|
+
end
|
106
|
+
|
107
|
+
def purge
|
108
|
+
if (!cached?)
|
109
|
+
raise MsPac::Error::PelletNotInstalledError.new(name)
|
110
|
+
end
|
111
|
+
|
112
|
+
puts "Purging #{name}...".white
|
113
|
+
FileUtils.rm_rf("#{@@cache_dir}/#{name}")
|
114
|
+
end
|
115
|
+
|
116
|
+
def remove(nosave = false)
|
117
|
+
if (!installed?)
|
118
|
+
raise MsPac::Error::PelletNotInstalledError.new(name)
|
119
|
+
end
|
120
|
+
|
121
|
+
puts "Removing #{name}...".white
|
122
|
+
execute("remove")
|
123
|
+
unlink
|
124
|
+
purge if (nosave)
|
125
|
+
end
|
126
|
+
|
127
|
+
def repo
|
128
|
+
return self["repo"]
|
129
|
+
end
|
130
|
+
|
131
|
+
def unlink
|
132
|
+
if (!installed?)
|
133
|
+
raise MsPac::Error::PelletNotInstalledError.new(name)
|
134
|
+
end
|
135
|
+
|
136
|
+
puts "Unlinking #{name}...".white
|
137
|
+
FileUtils.rm_f("#{@@install_dir}/#{name}")
|
138
|
+
end
|
139
|
+
|
140
|
+
def unlock
|
141
|
+
if (!installed?)
|
142
|
+
raise MsPac::Error::PelletNotInstalledError.new(name)
|
143
|
+
end
|
144
|
+
|
145
|
+
puts "Unlocking #{name}...".white
|
146
|
+
FileUtils.rm_f("#{@@install_dir}/#{name}/.mspac_lock")
|
147
|
+
end
|
148
|
+
|
149
|
+
def update(force = false)
|
150
|
+
if (!installed?)
|
151
|
+
raise MsPac::Error::PelletNotInstalledError.new(name)
|
152
|
+
end
|
153
|
+
|
154
|
+
Dir.chdir("#{@@install_dir}/#{name}") do
|
155
|
+
if (Pathname.new(".mspac_lock").expand_path.exist?)
|
156
|
+
puts "Locked: #{name}".red
|
157
|
+
return
|
158
|
+
end
|
159
|
+
|
160
|
+
puts "Updating #{name}...".white
|
161
|
+
tip = @vcs.revision
|
162
|
+
@vcs.update
|
163
|
+
new_tip = @vcs.revision
|
164
|
+
|
165
|
+
if ((tip != new_tip) || force)
|
166
|
+
install
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
class MsPac::VersionControl
|
2
|
+
def clone(repo)
|
3
|
+
return if (repo.nil? || repo.empty?)
|
4
|
+
|
5
|
+
case @vcs
|
6
|
+
when "git", "hg"
|
7
|
+
system("#{@vcs} clone #{repo}")
|
8
|
+
else
|
9
|
+
raise Error::UnsupportedVCSError.new(@vcs)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(vcs)
|
14
|
+
case vcs
|
15
|
+
when "bzr"
|
16
|
+
raise Error::UnsupportedVCSError.new(vcs)
|
17
|
+
when "git"
|
18
|
+
@vcs = vcs
|
19
|
+
when "hg"
|
20
|
+
@vcs = vcs
|
21
|
+
when "svn"
|
22
|
+
raise Error::UnsupportedVCSError.new(vcs)
|
23
|
+
else
|
24
|
+
raise Error::UnsupportedVCSError.new
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def revision
|
29
|
+
case @vcs
|
30
|
+
when "git"
|
31
|
+
%x(git log --oneline | head -n 1 | awk '{print $1}')
|
32
|
+
when "hg"
|
33
|
+
%(hg tip --template "{node}")
|
34
|
+
else
|
35
|
+
raise Error::UnsupportedVCSError.new(@vcs)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def update
|
40
|
+
case @vcs
|
41
|
+
when "git"
|
42
|
+
system("git reset && git pull")
|
43
|
+
when "hg"
|
44
|
+
system("hg pull && hg update")
|
45
|
+
else
|
46
|
+
raise Error::UnsupportedVCSError.new(@vcs)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/string.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# Redefine String class to allow for colorizing, rsplit, and word wrap
|
2
|
+
class String
|
3
|
+
def blue
|
4
|
+
return colorize(36)
|
5
|
+
end
|
6
|
+
|
7
|
+
def colorize(color)
|
8
|
+
return "\e[#{color}m#{self}\e[0m"
|
9
|
+
end
|
10
|
+
|
11
|
+
def green
|
12
|
+
return colorize(32)
|
13
|
+
end
|
14
|
+
|
15
|
+
def red
|
16
|
+
return colorize(31)
|
17
|
+
end
|
18
|
+
|
19
|
+
def rsplit(pattern)
|
20
|
+
ret = rpartition(pattern)
|
21
|
+
ret.delete_at(1)
|
22
|
+
return ret
|
23
|
+
end
|
24
|
+
|
25
|
+
def white
|
26
|
+
return colorize(37)
|
27
|
+
end
|
28
|
+
|
29
|
+
def word_wrap(width = 70)
|
30
|
+
return scan(/\S.{0,#{width}}\S(?=\s|$)|\S+/).join("\n")
|
31
|
+
end
|
32
|
+
end
|
metadata
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mspac
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Miles Whittaker
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-11-07 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: scoobydoo
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.1'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 0.1.1
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0.1'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 0.1.1
|
33
|
+
description: MsPac is a package manager written in ruby which tries to mirror Arch's
|
34
|
+
pacman. It's meant for installing opensource tools from source. It only supports
|
35
|
+
git or hg repos at this time. I hope to add bzr and svn later. It only supports
|
36
|
+
apt-get and pacman for installing dependencies at this time. I hope to add support
|
37
|
+
for brew, yum, and zipper later.
|
38
|
+
email: mjwhitta@gmail.com
|
39
|
+
executables:
|
40
|
+
- mspac
|
41
|
+
extensions: []
|
42
|
+
extra_rdoc_files: []
|
43
|
+
files:
|
44
|
+
- bin/mspac
|
45
|
+
- lib/mspac.rb
|
46
|
+
- lib/mspac/error.rb
|
47
|
+
- lib/mspac/error/invalid_operation_error.rb
|
48
|
+
- lib/mspac/error/missing_pellet_error.rb
|
49
|
+
- lib/mspac/error/multiple_operations_error.rb
|
50
|
+
- lib/mspac/error/pellet_not_installed_error.rb
|
51
|
+
- lib/mspac/error/pellet_repo_error.rb
|
52
|
+
- lib/mspac/error/unsupported_package_manager_error.rb
|
53
|
+
- lib/mspac/error/unsupported_vcs_error.rb
|
54
|
+
- lib/mspac/package_manager.rb
|
55
|
+
- lib/mspac/pellet.rb
|
56
|
+
- lib/mspac/version_control.rb
|
57
|
+
- lib/string.rb
|
58
|
+
homepage: http://mjwhitta.github.io/mspac
|
59
|
+
licenses:
|
60
|
+
- GPL-3.0
|
61
|
+
metadata: {}
|
62
|
+
post_install_message:
|
63
|
+
rdoc_options: []
|
64
|
+
require_paths:
|
65
|
+
- lib
|
66
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
71
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
requirements: []
|
77
|
+
rubyforge_project:
|
78
|
+
rubygems_version: 2.4.5.1
|
79
|
+
signing_key:
|
80
|
+
specification_version: 4
|
81
|
+
summary: Simple package manager for installing from source
|
82
|
+
test_files: []
|