ruaur 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 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: []