mspac 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|