ruaur 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 50ebe39558c3e6efd9953ae693863c8d7e7686c5
4
+ data.tar.gz: f4be7e20aa56a689686470120d08c4a82d6ef496
5
+ SHA512:
6
+ metadata.gz: 35750a58dd7ba7b56e899b47504db601d8c8d211b6c0464efd5e2b50471eacdc630196b3e47e2e670b78ffd6534cee85869f83f1106d2aee18695fc3b93a6072
7
+ data.tar.gz: da1963ce9bb15df155d8b012b74d1cca7cb6a24964607fb9623a46838ba2b5e4306a4f7b7916f41497aa1e221bf734273ddc80f554fdcb48c76943fa9ee5371b
data/bin/ruaur ADDED
@@ -0,0 +1,201 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "optparse"
4
+ require "ruaur"
5
+ require "string"
6
+
7
+ class RuAURExit
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
+ REMOVE = 1
19
+ SYNC = 2
20
+ end
21
+
22
+ def parse(args)
23
+ options = Hash.new
24
+ options["operation"] = nil
25
+
26
+ # Sync options
27
+ options["clean"] = false
28
+ options["noconfirm"] = false
29
+ options["search"] = false
30
+ options["upgrade"] = false
31
+
32
+ # Remove options
33
+ options["nosave"] = false
34
+
35
+ parser = OptionParser.new do |opts|
36
+ opts.banner =
37
+ "Usage: #{File.basename($0)} <operation> [OPTIONS] [pkgs]"
38
+
39
+ opts.on("", "OPERATIONS")
40
+
41
+ opts.on("-h", "--help", "Display this help message") do
42
+ puts opts
43
+ exit
44
+ end
45
+
46
+ opts.on("-R", "--remove", "Remove packages") do
47
+ if (options["operation"])
48
+ puts opts
49
+ exit RuAURExit::MULTIPLE_OPERATIONS
50
+ end
51
+ options["operation"] = Operation::REMOVE
52
+ end
53
+
54
+ opts.on("-S", "--sync", "Synchronize packages") do
55
+ if (options["operation"])
56
+ puts opts
57
+ exit RuAURExit::MULTIPLE_OPERATIONS
58
+ end
59
+ options["operation"] = Operation::SYNC
60
+ end
61
+
62
+ opts.on("", "SYNC OPTIONS")
63
+
64
+ opts.on("-c", "--clean", "Remove packages from the cache") do
65
+ options["clean"] = true
66
+ end
67
+
68
+ opts.on(
69
+ "--noconfirm",
70
+ "Bypass any and all \"Are you sure?\" messages."
71
+ ) do
72
+ options["noconfirm"] = true
73
+ end
74
+
75
+ opts.on(
76
+ "-s",
77
+ "--search",
78
+ "Search the sync database and AUR for packages"
79
+ ) do
80
+ options["search"] = true
81
+ end
82
+
83
+ opts.on("-u", "--sysupgrade", "Upgrade all packages") do
84
+ options["upgrade"] = true
85
+ end
86
+
87
+ opts.on("", "REMOVE OPTIONS")
88
+
89
+ opts.on("-n", "--nosave", "Completely remove package") do
90
+ options["nosave"] = true
91
+ end
92
+ end
93
+
94
+ begin
95
+ parser.parse!
96
+ rescue OptionParser::InvalidOption => e
97
+ puts e.message
98
+ puts parser
99
+ exit RuAURExit::INVALID_OPTION
100
+ rescue OptionParser::InvalidArgument => e
101
+ puts e.message
102
+ puts parser
103
+ exit RuAURExit::INVALID_ARGUMENT
104
+ rescue OptionParser::MissingArgument => e
105
+ puts e.message
106
+ puts parser
107
+ exit RuAURExit::MISSING_ARGUMENT
108
+ end
109
+
110
+ if (!validate(options))
111
+ puts parser
112
+ exit RuAURExit::INVALID_OPERATION
113
+ end
114
+
115
+ options["packages"] = args
116
+
117
+ return options
118
+ end
119
+
120
+ def validate(options)
121
+ case options["operation"]
122
+ when Operation::REMOVE
123
+ if (
124
+ options["clean"] ||
125
+ options["noconfirm"] ||
126
+ options["search"] ||
127
+ options["upgrade"]
128
+ )
129
+ return false
130
+ end
131
+ when Operation::SYNC
132
+ return false if (options["nosave"])
133
+
134
+ if (options["clean"])
135
+ if (
136
+ options["noconfirm"] ||
137
+ options["search"] ||
138
+ options["upgrade"]
139
+ )
140
+ return false
141
+ end
142
+ elsif (options["noconfirm"])
143
+ if (
144
+ options["clean"] ||
145
+ options["search"] ||
146
+ options["upgrade"]
147
+ )
148
+ return false
149
+ end
150
+ elsif (options["search"])
151
+ if (
152
+ options["clean"] ||
153
+ options["noconfirm"] ||
154
+ options["upgrade"]
155
+ )
156
+ return false
157
+ end
158
+ elsif (options["upgrade"])
159
+ if (
160
+ options["clean"] ||
161
+ options["noconfirm"] ||
162
+ options["search"]
163
+ )
164
+ return false
165
+ end
166
+ end
167
+ else
168
+ return false
169
+ end
170
+
171
+ return true
172
+ end
173
+
174
+ # Parse CLI args
175
+ options = parse(ARGV)
176
+
177
+ begin
178
+ ruaur = RuAUR.new
179
+
180
+ case options["operation"]
181
+ when Operation::REMOVE
182
+ ruaur.remove(options["packages"], options["nosave"])
183
+ when Operation::SYNC
184
+ if (options["clean"])
185
+ ruaur.clean(options["noconfirm"])
186
+ elsif (options["search"])
187
+ puts ruaur.search(options["packages"].join(" "))
188
+ elsif (options["upgrade"])
189
+ ruaur.upgrade(options["noconfirm"])
190
+ else
191
+ ruaur.install(options["packages"], options["noconfirm"])
192
+ end
193
+ end
194
+ exit RuAURExit::GOOD
195
+ rescue RuAUR::Error => e
196
+ puts e.message.red
197
+ exit RuAURExit::EXCEPTION
198
+ rescue Interrupt => e
199
+ # ^C
200
+ puts
201
+ end
data/lib/ruaur/aur.rb ADDED
@@ -0,0 +1,263 @@
1
+ require "archive/tar/minitar"
2
+ require "fileutils"
3
+ require "io/wait"
4
+ require "json"
5
+ require "scoobydoo"
6
+ require "typhoeus"
7
+ require "zlib"
8
+
9
+ class RuAUR::AUR
10
+ def clean
11
+ puts "Cleaning AUR cache...".white
12
+ Dir.chdir(@cache) do
13
+ FileUtils.rm_rf(Dir["*"])
14
+ end
15
+ end
16
+
17
+ def compile(package)
18
+ puts "Compiling #{package.name}...".white
19
+ if (Process.uid == 0)
20
+ system("chown -R nobody:nobody .")
21
+ system("su -s /bin/sh nobody -c \"makepkg -sr\"")
22
+ else
23
+ system("makepkg -sr")
24
+ end
25
+
26
+ compiled = Dir["#{package.name}*.pkg.tar.xz"]
27
+ if (compiled.empty?)
28
+ raise RuAUR::Error::FailedToCompileError.new(package.name)
29
+ end
30
+
31
+ return compiled
32
+ end
33
+ private :compile
34
+
35
+ def download(package)
36
+ FileUtils.rm_f(Dir["#{package.name}.tar.gz*"])
37
+
38
+ puts "Downloading #{package.name}...".white
39
+ tarball(package.name, package.url, "#{package.name}.tar.gz")
40
+
41
+ tgz = Pathname.new("#{package.name}.tar.gz").expand_path
42
+ if (!tgz.exist?)
43
+ raise RuAUR::Error::FailedToDownloadError.new(
44
+ package.name
45
+ )
46
+ end
47
+ end
48
+ private :download
49
+
50
+ def edit_pkgbuild(package, noconfirm = false)
51
+ return false if (noconfirm)
52
+
53
+ print "Do you want to edit the PKGBUILD y/[n]/q?: "
54
+ answer = nil
55
+ while (answer.nil?)
56
+ begin
57
+ system("stty raw -echo")
58
+ if ($stdin.ready?)
59
+ answer = $stdin.getc
60
+ else
61
+ sleep 0.1
62
+ end
63
+ ensure
64
+ system("stty -raw echo")
65
+ end
66
+ end
67
+ puts
68
+
69
+ case answer
70
+ when "y", "Y"
71
+ editor = ENV["EDITOR"]
72
+ editor = ScoobyDoo.where_are_you("vim") if (editor.nil?)
73
+ editor = ScoobyDoo.where_are_you("vi") if (editor.nil?)
74
+ system("#{editor} PKGBUILD")
75
+ when "q", "Q", "\x03"
76
+ # Quit or ^C
77
+ return true
78
+ end
79
+ return false
80
+ end
81
+ private :edit_pkgbuild
82
+
83
+ def extract(package)
84
+ FileUtils.rm_rf(package.name)
85
+
86
+ puts "Extracting #{package.name}...".white
87
+ File.open("#{package.name}.tar.gz", "rb") do |tgz|
88
+ tar = Zlib::GzipReader.new(tgz)
89
+ Archive::Tar::Minitar.unpack(tar, ".")
90
+ end
91
+ FileUtils.rm_f("pax_global_header")
92
+
93
+ dir = Pathname.new(package.name).expand_path
94
+ if (!dir.exist? || !dir.directory?)
95
+ raise RuAUR::Error::FailedToExtractError.new(package.name)
96
+ end
97
+ end
98
+ private :extract
99
+
100
+ def find_upgrades
101
+ puts "Checking for AUR updates...".white
102
+
103
+ upgrades = Hash.new
104
+ multiinfo(@installed.keys).each do |package|
105
+ if (
106
+ @installed.has_key?(package.name) &&
107
+ package.newer?(@installed[package.name])
108
+ )
109
+ upgrades[package.name] = [
110
+ @installed[package.name],
111
+ package.version
112
+ ]
113
+ end
114
+ end
115
+
116
+ return upgrades
117
+ end
118
+ private :find_upgrades
119
+
120
+ def info(package)
121
+ return nil if (package.nil? || package.empty?)
122
+
123
+ query = "type=info&arg=#{package}"
124
+ body = JSON.parse(Typhoeus.get("#{@rpc_url}?#{query}").body)
125
+
126
+ if (body["type"] == "error")
127
+ raise RuAUR::Error::AURError.new(body["results"])
128
+ end
129
+
130
+ return nil if (body["results"].empty?)
131
+ return RuAUR::Package.new(body["results"])
132
+ end
133
+
134
+ def initialize(pacman, cache = "/tmp/ruaur-#{ENV["USER"]}")
135
+ @cache = Pathname.new(cache).expand_path
136
+ FileUtils.mkdir_p(@cache)
137
+ @installed = pacman.query_aur
138
+ @pacman = pacman
139
+ @rpc_url = "https://aur.archlinux.org/rpc.php"
140
+ end
141
+
142
+ def install(pkg_name, noconfirm = false)
143
+ package = info(pkg_name)
144
+
145
+ if (package.nil?)
146
+ raise RuAUR::Error::PackageNotFoundError.new(pkg_name)
147
+ end
148
+
149
+ if (
150
+ @installed.include?(pkg_name) &&
151
+ !package.newer?(@installed[pkg_name])
152
+ )
153
+ puts "Already installed: #{pkg_name}".yellow
154
+ return
155
+ end
156
+
157
+ Dir.chdir(@cache) do
158
+ download(package)
159
+ extract(package)
160
+ end
161
+ Dir.chdir("#{@cache}/#{package.name}") do
162
+ return if (edit_pkgbuild(package, noconfirm))
163
+ install_dependencies(package, noconfirm)
164
+ compiled = compile(package)
165
+ @pacman.install_local(compiled, noconfirm)
166
+ end
167
+
168
+ @installed.merge!(@pacman.query_aur(pkg_name))
169
+ end
170
+
171
+ def install_dependencies(package, noconfirm)
172
+ pkgbuild = File.read("PKGBUILD")
173
+
174
+ pkgbuild.match(/^depends\=\(([^\)]+)\)/m) do |match|
175
+ match.captures.each do |cap|
176
+ cap.gsub(/\n/, " ").scan(/[^' ]+/) do |scan|
177
+ dep = scan.gsub(/(\<|\=|\>).*$/, "")
178
+ if (!@installed.has_key?(dep))
179
+ puts "Installing dependency: #{dep}".purple
180
+ if (@pacman.exist?(dep))
181
+ @pacman.install(dep, noconfirm)
182
+ else
183
+ install(dep, noconfirm)
184
+ end
185
+ end
186
+ end
187
+ end
188
+ end
189
+ end
190
+ private :install_dependencies
191
+
192
+ def multiinfo(pkgs)
193
+ results = Array.new
194
+ return results if (pkgs.nil? || pkgs.empty?)
195
+
196
+ query = "type=multiinfo&arg[]=#{pkgs.join("&arg[]=")}"
197
+ body = JSON.parse(Typhoeus.get("#{@rpc_url}?#{query}").body)
198
+
199
+ if (body["type"] == "error")
200
+ raise RuAUR::Error::AURError.new(body["results"])
201
+ end
202
+
203
+ body["results"].each do |result|
204
+ results.push(RuAUR::Package.new(result))
205
+ end
206
+ return results.sort
207
+ end
208
+
209
+ def search(string)
210
+ results = Array.new
211
+ return results if (string.nil? || string.empty?)
212
+
213
+ query = "type=search&arg=#{string}"
214
+ body = JSON.parse(Typhoeus.get("#{@rpc_url}?#{query}").body)
215
+
216
+ if (body["type"] == "error")
217
+ raise RuAUR::Error::AURError.new(body["results"])
218
+ end
219
+
220
+ body["results"].each do |result|
221
+ results.push(RuAUR::Package.new(result))
222
+ end
223
+
224
+ results.each do |package|
225
+ if (@installed.has_key?(package.name))
226
+ package.installed(@installed[package.name])
227
+ end
228
+ end
229
+ return results.sort
230
+ end
231
+
232
+ def tarball(name, url, file)
233
+ if (url.nil? || url.empty? || file.nil? || file.empty?)
234
+ return nil
235
+ end
236
+
237
+ tgz = File.open(file, "wb")
238
+ request = Typhoeus::Request.new(url)
239
+ request.on_headers do |response|
240
+ if (response.code != 200)
241
+ raise RuAUR::Error::FailedToDownloadError.new(name)
242
+ end
243
+ end
244
+ request.on_body do |chunk|
245
+ tgz.write(chunk)
246
+ end
247
+ request.on_complete do
248
+ tgz.close
249
+ end
250
+ request.run
251
+ end
252
+ private :tarball
253
+
254
+ def upgrade(noconfirm = false)
255
+ find_upgrades.each do |pkg_name, versions|
256
+ old, new = versions
257
+
258
+ puts "Upgrading #{pkg_name}...".white
259
+ puts "#{old.red} -> #{new.green}"
260
+ install(pkg_name, noconfirm)
261
+ end
262
+ end
263
+ end
@@ -0,0 +1,5 @@
1
+ class RuAUR::Error::AURError < RuAUR::Error
2
+ def initialize(msg)
3
+ super(msg)
4
+ end
5
+ end
@@ -0,0 +1,6 @@
1
+ class RuAUR::Error::FailedToCompileError < RuAUR::Error
2
+ def initialize(package = nil)
3
+ super("Failed to compile: #{package}") if (package)
4
+ super("Failed to compile") if (package.nil?)
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ class RuAUR::Error::FailedToDownloadError < RuAUR::Error
2
+ def initialize(package = nil)
3
+ super("Failed to download: #{package}") if (package)
4
+ super("Failed to download") if (package.nil?)
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ class RuAUR::Error::FailedToExtractError < RuAUR::Error
2
+ def initialize(package = nil)
3
+ super("Failed to extract: #{package}") if (package)
4
+ super("Failed to extract") if (package.nil?)
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ class RuAUR::Error::MissingDependencyError < RuAUR::Error
2
+ def initialize(dep = nil)
3
+ super("Dependency not found: #{dep}") if (dep)
4
+ super("Dependency not found") if (dep.nil?)
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ class RuAUR::Error::PackageNotFoundError < RuAUR::Error
2
+ def initialize(package = nil)
3
+ super("Package not found: #{package}") if (package)
4
+ super("No package was specified") if (package.nil?)
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ class RuAUR::Error::PackageNotInstalledError < RuAUR::Error
2
+ def initialize(package = nil)
3
+ super("Package not installed: #{package}") if (package)
4
+ super("Package not installed") if (package.nil?)
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ class RuAUR::Error::RuAURAlreadyRunningError < RuAUR::Error
2
+ def initialize
3
+ super("RuAUR is already running")
4
+ end
5
+ end
@@ -0,0 +1,11 @@
1
+ class RuAUR::Error < RuntimeError
2
+ end
3
+
4
+ require "ruaur/error/aur_error"
5
+ require "ruaur/error/failed_to_compile_error"
6
+ require "ruaur/error/failed_to_download_error"
7
+ require "ruaur/error/failed_to_extract_error"
8
+ require "ruaur/error/missing_dependency_error"
9
+ require "ruaur/error/package_not_found_error"
10
+ require "ruaur/error/package_not_installed_error"
11
+ require "ruaur/error/ruaur_already_running_error"
@@ -0,0 +1,95 @@
1
+ require "string"
2
+
3
+ class RuAUR::Package
4
+ attr_accessor :description
5
+ attr_accessor :installed
6
+ attr_accessor :json
7
+ attr_accessor :name
8
+ attr_accessor :repo
9
+ attr_accessor :url
10
+ attr_accessor :version
11
+ attr_accessor :votes
12
+
13
+ def <=>(other)
14
+ if (self.name.downcase == other.name.downcase)
15
+ self_version = self.version.split(/\D+/).map(&:to_i)
16
+ other_version = self.version.split(/\D+/).map(&:to_i)
17
+
18
+ [self_version.size, other_version.size].max.times do |i|
19
+ cmp = self_version[i] <=> other_version[i]
20
+ return cmp if (cmp != 0)
21
+ end
22
+ end
23
+ return (self.name.downcase <=> other.name.downcase)
24
+ end
25
+
26
+ def initialize(json, repo = "aur")
27
+ @description = json["Description"]
28
+ @installed = nil
29
+ @json = json
30
+ @name = json["Name"]
31
+ @repo = repo
32
+ if (json["URLPath"])
33
+ @url = "https://aur.archlinux.org#{json["URLPath"]}"
34
+ else
35
+ @url = nil
36
+ end
37
+ @version = json["Version"]
38
+ @votes = nil
39
+ @votes = "(#{json["NumVotes"]})" if (json["NumVotes"])
40
+ end
41
+
42
+ def installed(version = nil)
43
+ @installed = version if (version)
44
+ @installed = @version if (version.nil?)
45
+ end
46
+
47
+ def newer?(ver)
48
+ self_version = @version.split(/\D+/).map(&:to_i)
49
+ other_version = ver.split(/\D+/).map(&:to_i)
50
+
51
+ [self_version.size, other_version.size].max.times do |i|
52
+ if (self_version[i] > other_version[i])
53
+ return true
54
+ end
55
+ end
56
+ return false
57
+ end
58
+
59
+ def older?(version)
60
+ self_version = @version.split(/\D+/).map(&:to_i)
61
+ other_version = version.split(/\D+/).map(&:to_i)
62
+
63
+ [self_version.size, other_version.size].max.times do |i|
64
+ if (self_version[i] < other_version[i])
65
+ return true
66
+ end
67
+ end
68
+ return false
69
+ end
70
+
71
+ def tarball(file)
72
+ return RuAUR::AUR.tarball(@url, file)
73
+ end
74
+
75
+ def to_s
76
+ out = Array.new
77
+ header = Array.new
78
+
79
+ header.push("#{@repo.blue}#{"/".blue}#{@name.cyan}")
80
+ if (@installed && newer?(@installed))
81
+ header.push(@installed.red)
82
+ header.push("->")
83
+ end
84
+ header.push(@version.green)
85
+ header.push(@votes.white) if (@votes)
86
+ header.push("[installed]".purple) if (@installed)
87
+ out.push(header.join(" "))
88
+
89
+ @description.word_wrap.each_line do |line|
90
+ out.push(" #{line.rstrip}")
91
+ end
92
+
93
+ return out.join("\n")
94
+ end
95
+ end
@@ -0,0 +1,124 @@
1
+ class RuAUR::Pacman
2
+ def clean(noconfirm = false)
3
+ puts "Cleaning pacman cache...".white
4
+ system("sudo #{@pac_clr} -Sc") if (!noconfirm)
5
+ system("sudo #{@pac_clr} -Sc --noconfirm") if (noconfirm)
6
+ end
7
+
8
+ def exist?(pkg_name)
9
+ return !%x(#{@pac_noclr} -Ss "^#{pkg_name}$").empty?
10
+ end
11
+
12
+ def initialize
13
+ @pac_noclr = "pacman --color=never"
14
+ @pac_clr = "pacman --color=always"
15
+ @installed = query
16
+ end
17
+
18
+ def install(pkg_name, noconfirm = false)
19
+ if (@installed.include?(pkg_name))
20
+ puts "Already installed: #{pkg_name}".yellow
21
+ return
22
+ end
23
+
24
+ puts "Installing #{pkg_name}...".white
25
+ if (!noconfirm)
26
+ system("sudo #{@pac_clr} -S #{pkg_name} --needed")
27
+ else
28
+ system(
29
+ "sudo #{@pac_clr} -S #{pkg_name} --needed --noconfirm"
30
+ )
31
+ end
32
+
33
+ @installed.merge!(query(pkg_name))
34
+ end
35
+
36
+ def install_local(pkgs, noconfirm = false)
37
+ pkgs.each do |pkg|
38
+ puts "Installing #{pkg}...".white
39
+ if (!noconfirm)
40
+ system("sudo #{@pac_clr} -U #{pkg}") if (!noconfirm)
41
+ else
42
+ system("sudo #{@pac_clr} -U #{pkg} --noconfirm")
43
+ end
44
+ end
45
+ end
46
+
47
+ def query(pkg_name = "")
48
+ results = Hash.new
49
+ %x(#{@pac_noclr} -Q #{pkg_name}).split("\n").map do |line|
50
+ line = line.split
51
+ results[line[0]] = line[1]
52
+ end
53
+ return results
54
+ end
55
+
56
+ def query_aur(pkg_name = "")
57
+ community = Pathname.new(
58
+ "/var/lib/pacman/sync/community"
59
+ ).expand_path
60
+
61
+ results = Hash.new
62
+ %x(#{@pac_noclr} -Qm #{pkg_name}).split("\n").delete_if do |p|
63
+ # Skip packages in community
64
+ Dir["#{community}/#{p.split.join("-")}"].any?
65
+ end.map do |line|
66
+ line = line.split
67
+ results[line[0]] = line[1]
68
+ end
69
+ return results
70
+ end
71
+
72
+ def remove(pkg_names, nosave = false)
73
+ puts "Removing #{pkg_names.join(" ")}...".white
74
+ if (!nosave)
75
+ system("sudo #{@pac_clr} -R #{pkg_names.join(" ")}")
76
+ else
77
+ system("sudo #{@pac_clr} -Rn #{pkg_names.join(" ")}")
78
+ end
79
+ end
80
+
81
+ def search(pkg_names)
82
+ results = Array.new
83
+ return results if (pkg_names.nil? || pkg_names.empty?)
84
+
85
+ %x(#{@pac_noclr} -Ss #{pkg_names}).each_line do |line|
86
+ reg = "^([^\/ ]+)\/([^ ]+) ([^ ]+)( .*)?$"
87
+ match = line.match(/#{reg}/)
88
+ if (match)
89
+ repo, name, version, trailing = match.captures
90
+ repo.strip!
91
+ name.strip!
92
+ version.strip!
93
+ trailing = "" if (trailing.nil?)
94
+ trailing.strip!
95
+
96
+ results.push(
97
+ RuAUR::Package.new(
98
+ {
99
+ "Description" => "",
100
+ "Name" => name,
101
+ "NumVotes" => nil,
102
+ "URLPath" => nil,
103
+ "Version" => version
104
+ },
105
+ repo
106
+ )
107
+ )
108
+ if (trailing.include?("[installed]"))
109
+ results.last.installed
110
+ end
111
+ elsif (results.any?)
112
+ results.last.description += " #{line.strip}"
113
+ end
114
+ end
115
+
116
+ return results
117
+ end
118
+
119
+ def upgrade(noconfirm = false)
120
+ puts "Updating...".white
121
+ system("sudo #{@pac_clr} -Syyu") if (!noconfirm)
122
+ system("sudo #{@pac_clr} -Syyu --noconfirm") if (noconfirm)
123
+ end
124
+ end
data/lib/ruaur.rb ADDED
@@ -0,0 +1,82 @@
1
+ require "fileutils"
2
+ require "scoobydoo"
3
+
4
+ class RuAUR
5
+ def check_and_lock
6
+ if (@lock.exist?)
7
+ raise RuAUR::Error::RuAURAlreadyRunningError.new
8
+ end
9
+
10
+ FileUtils.touch(@lock)
11
+ end
12
+ private :check_and_lock
13
+
14
+ def clean(noconfirm)
15
+ @pacman.clean(noconfirm)
16
+ @aur.clean
17
+ end
18
+
19
+ def initialize
20
+ [
21
+ "makepkg",
22
+ "pacman",
23
+ "su",
24
+ "sudo"
25
+ ].each do |dep|
26
+ if (ScoobyDoo.where_are_you(dep).nil?)
27
+ raise RuAUR::Error::MissingDependencyError.new(dep)
28
+ end
29
+ end
30
+
31
+ @pacman = RuAUR::Pacman.new
32
+ @aur = RuAUR::AUR.new(@pacman)
33
+ @lock = Pathname.new("/tmp/ruaur.lock").expand_path
34
+ end
35
+
36
+ def install(pkg_names, noconfirm = false)
37
+ if (pkg_names.nil? || pkg_names.empty?)
38
+ raise RuAUR::Error::PackageNotFoundError.new
39
+ end
40
+
41
+ check_and_lock
42
+
43
+ pkg_names.each do |pkg_name|
44
+ if (@pacman.exist?(pkg_name))
45
+ @pacman.install(pkg_name, noconfirm)
46
+ else
47
+ @aur.install(pkg_name, noconfirm)
48
+ end
49
+ end
50
+ ensure
51
+ unlock
52
+ end
53
+
54
+ def remove(pkg_names, nosave = false)
55
+ check_and_lock
56
+ @pacman.remove(pkg_names, nosave)
57
+ ensure
58
+ unlock
59
+ end
60
+
61
+ def search(string)
62
+ return @pacman.search(string).concat(@aur.search(string))
63
+ end
64
+
65
+ def unlock
66
+ FileUtils.rm_f(@lock)
67
+ end
68
+ private :unlock
69
+
70
+ def upgrade(noconfirm = false)
71
+ check_and_lock
72
+ @pacman.upgrade(noconfirm)
73
+ @aur.upgrade(noconfirm)
74
+ ensure
75
+ unlock
76
+ end
77
+ end
78
+
79
+ require "ruaur/aur"
80
+ require "ruaur/error"
81
+ require "ruaur/package"
82
+ require "ruaur/pacman"
data/lib/string.rb ADDED
@@ -0,0 +1,48 @@
1
+ # Redefine String class to allow for colorizing, rsplit, and word wrap
2
+ class String
3
+ def black
4
+ return colorize(30)
5
+ end
6
+
7
+ def blue
8
+ return colorize(34)
9
+ end
10
+
11
+ def colorize(color)
12
+ return "\e[#{color}m#{self}\e[0m"
13
+ end
14
+
15
+ def cyan
16
+ return colorize(36)
17
+ end
18
+
19
+ def green
20
+ return colorize(32)
21
+ end
22
+
23
+ def purple
24
+ return colorize(35)
25
+ end
26
+
27
+ def red
28
+ return colorize(31)
29
+ end
30
+
31
+ def rsplit(pattern)
32
+ ret = rpartition(pattern)
33
+ ret.delete_at(1)
34
+ return ret
35
+ end
36
+
37
+ def white
38
+ return colorize(37)
39
+ end
40
+
41
+ def word_wrap(width = 70)
42
+ return scan(/\S.{0,#{width}}\S(?=\s|$)|\S+/).join("\n")
43
+ end
44
+
45
+ def yellow
46
+ return colorize(33)
47
+ end
48
+ end
metadata ADDED
@@ -0,0 +1,120 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruaur
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-12-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: archive-tar-minitar
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.5'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 0.5.2
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '0.5'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 0.5.2
33
+ - !ruby/object:Gem::Dependency
34
+ name: scoobydoo
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '0.1'
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 0.1.1
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '0.1'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 0.1.1
53
+ - !ruby/object:Gem::Dependency
54
+ name: typhoeus
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '0.8'
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 0.8.0
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '0.8'
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: 0.8.0
73
+ description: RuAUR is a Ruby gem that allows searching and installing packages from
74
+ the Pacman sync database as well as the Arch User Repository (AUR).
75
+ email: mjwhitta@gmail.com
76
+ executables:
77
+ - ruaur
78
+ extensions: []
79
+ extra_rdoc_files: []
80
+ files:
81
+ - bin/ruaur
82
+ - lib/ruaur.rb
83
+ - lib/ruaur/aur.rb
84
+ - lib/ruaur/error.rb
85
+ - lib/ruaur/error/aur_error.rb
86
+ - lib/ruaur/error/failed_to_compile_error.rb
87
+ - lib/ruaur/error/failed_to_download_error.rb
88
+ - lib/ruaur/error/failed_to_extract_error.rb
89
+ - lib/ruaur/error/missing_dependency_error.rb
90
+ - lib/ruaur/error/package_not_found_error.rb
91
+ - lib/ruaur/error/package_not_installed_error.rb
92
+ - lib/ruaur/error/ruaur_already_running_error.rb
93
+ - lib/ruaur/package.rb
94
+ - lib/ruaur/pacman.rb
95
+ - lib/string.rb
96
+ homepage: https://mjwhitta.github.io/ruaur
97
+ licenses:
98
+ - GPL-3.0
99
+ metadata: {}
100
+ post_install_message:
101
+ rdoc_options: []
102
+ require_paths:
103
+ - lib
104
+ required_ruby_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ required_rubygems_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ requirements: []
115
+ rubyforge_project:
116
+ rubygems_version: 2.4.5.1
117
+ signing_key:
118
+ specification_version: 4
119
+ summary: Can search and install packages for Arch Linux
120
+ test_files: []