gembuild 1.0.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/.gitignore +26 -0
- data/.rspec +2 -0
- data/.travis.yml +15 -0
- data/CHANGELOG.md +15 -0
- data/Gemfile +3 -0
- data/LICENSE +675 -0
- data/README.md +80 -0
- data/Rakefile +14 -0
- data/bin/gembuild +10 -0
- data/gembuild.gemspec +45 -0
- data/lib/gembuild.rb +142 -0
- data/lib/gembuild/aur_scraper.rb +159 -0
- data/lib/gembuild/exceptions.rb +31 -0
- data/lib/gembuild/gem_scraper.rb +205 -0
- data/lib/gembuild/pkgbuild.erb +32 -0
- data/lib/gembuild/pkgbuild.rb +283 -0
- data/lib/gembuild/project.rb +167 -0
- data/lib/gembuild/version.rb +23 -0
- metadata +301 -0
@@ -0,0 +1,31 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# Gembuild: create Arch Linux PKGBUILDs for ruby gems.
|
4
|
+
# Copyright (C) 2015 Mario Finelli <mario@finel.li>
|
5
|
+
#
|
6
|
+
# This program is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU General Public License as published by
|
8
|
+
# the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# This program is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU General Public License
|
17
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
|
19
|
+
module Gembuild
|
20
|
+
# Exception raised when rubygems.org returns a 404 error.
|
21
|
+
class GemNotFoundError < StandardError; end
|
22
|
+
|
23
|
+
# Exception raised when a non-string pkgbuild is passed.
|
24
|
+
class InvalidPkgbuildError < StandardError; end
|
25
|
+
|
26
|
+
# Exception raised when no gemname is specified.
|
27
|
+
class UndefinedGemNameError < StandardError; end
|
28
|
+
|
29
|
+
# Exception raised when no pkgname is specified.
|
30
|
+
class UndefinedPkgnameError < StandardError; end
|
31
|
+
end
|
@@ -0,0 +1,205 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# Gembuild: create Arch Linux PKGBUILDs for ruby gems.
|
4
|
+
# Copyright (C) 2015 Mario Finelli <mario@finel.li>
|
5
|
+
#
|
6
|
+
# This program is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU General Public License as published by
|
8
|
+
# the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# This program is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU General Public License
|
17
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
|
19
|
+
require 'mechanize'
|
20
|
+
require 'nokogiri'
|
21
|
+
|
22
|
+
module Gembuild
|
23
|
+
# This class is used to query for various information from rubygems.org.
|
24
|
+
#
|
25
|
+
# @!attribute [r] agent
|
26
|
+
# @return [Mechanize] the Mechanize agent
|
27
|
+
# @!attribute [r] deps
|
28
|
+
# @return [String] the rubygems URL for getting dependency information
|
29
|
+
# @!attribute [r] gem
|
30
|
+
# @return [String] the rubygems URL for the frontend
|
31
|
+
# @!attribute [r] gemname
|
32
|
+
# @return [String] the rubygem about which to query
|
33
|
+
# @!attribute [r] url
|
34
|
+
# @return [String] the rubygems URL to get version information
|
35
|
+
class GemScraper
|
36
|
+
attr_reader :agent, :deps, :gem, :gemname, :url
|
37
|
+
|
38
|
+
# Creates a new GemScraper instance
|
39
|
+
#
|
40
|
+
# @raise [Gembuild::UndefinedGemName] if the gemname is nil or empty
|
41
|
+
#
|
42
|
+
# @example Create a new GemScraper object
|
43
|
+
# Gembuild::GemScraper.new('mina')
|
44
|
+
# # => #<Gembuild::GemScraper:0x00000002f8a500
|
45
|
+
# # @agent=
|
46
|
+
# # #<Mechanize
|
47
|
+
# # #<Mechanize::CookieJar:0x00000002f8a410
|
48
|
+
# # @store=
|
49
|
+
# # #<HTTP::CookieJar::HashStore:0x00000002f8a370
|
50
|
+
# # @gc_index=0,
|
51
|
+
# # @gc_threshold=150,
|
52
|
+
# # @jar={},
|
53
|
+
# # @logger=nil,
|
54
|
+
# # @mon_count=0,
|
55
|
+
# # @mon_mutex=#<Mutex:0x00000002f8a320>,
|
56
|
+
# # @mon_owner=nil>>
|
57
|
+
# # nil>,
|
58
|
+
# # @deps="https://rubygems.org/api/v1/dependencies?gems=mina",
|
59
|
+
# # @gem="https://rubygems.org/gems/mina",
|
60
|
+
# # @gemname="mina",
|
61
|
+
# # @url="https://rubygems.org/api/v1/versions/mina.json">
|
62
|
+
#
|
63
|
+
# @param gemname [String] The gem about which to query.
|
64
|
+
# @return [Gembuild::GemScraper] a new GemScraper instance
|
65
|
+
def initialize(gemname)
|
66
|
+
fail Gembuild::UndefinedGemNameError if gemname.nil? || gemname.empty?
|
67
|
+
|
68
|
+
@gemname = gemname
|
69
|
+
@agent = Mechanize.new
|
70
|
+
|
71
|
+
@url = "https://rubygems.org/api/v1/versions/#{gemname}.json"
|
72
|
+
@deps = "https://rubygems.org/api/v1/dependencies?gems=#{gemname}"
|
73
|
+
@gem = "https://rubygems.org/gems/#{gemname}"
|
74
|
+
end
|
75
|
+
|
76
|
+
# Query the rubygems version api for the latest version.
|
77
|
+
#
|
78
|
+
# @raise [Gembuild::GemNotFoundError] if the page returns a 404 (not
|
79
|
+
# found) error.
|
80
|
+
#
|
81
|
+
# @example Query rubygems.org for version information
|
82
|
+
# s = Gembuild::GemScraper.new('mina')
|
83
|
+
# s.query_latest_version
|
84
|
+
# # => {:authors=>"Rico Sta. Cruz, Michael Galero",
|
85
|
+
# # :built_at=>"2015-07-08T00:00:00.000Z",
|
86
|
+
# # :created_at=>"2015-07-08T13:13:33.292Z",
|
87
|
+
# # :description=>"Really fast deployer and server automation tool.",
|
88
|
+
# # :downloads_count=>18709,
|
89
|
+
# # :metadata=>{},
|
90
|
+
# # :number=>"0.3.7",
|
91
|
+
# # :summary=>"Really fast deployer and server automation tool.",
|
92
|
+
# # :platform=>"ruby",
|
93
|
+
# # :ruby_version=>">= 0",
|
94
|
+
# # :prerelease=>false,
|
95
|
+
# # :licenses=>[],
|
96
|
+
# # :requirements=>[],
|
97
|
+
# # :sha=>
|
98
|
+
# # "bd1fa2b56ed1aded882a12f6365a04496f5cf8a14c07f8c4f1f3cfc944ef34f6"
|
99
|
+
# # }
|
100
|
+
#
|
101
|
+
# @return [Hash] the information about the latest version of the gem
|
102
|
+
def query_latest_version
|
103
|
+
response = JSON.parse(agent.get(url).body, symbolize_names: true)
|
104
|
+
|
105
|
+
# Skip any release marked as a "prerelease"
|
106
|
+
response.shift while response.first[:prerelease]
|
107
|
+
|
108
|
+
response.first
|
109
|
+
rescue Mechanize::ResponseCodeError, Net::HTTPNotFound
|
110
|
+
raise Gembuild::GemNotFoundError
|
111
|
+
end
|
112
|
+
|
113
|
+
# Gets the version number from the parsed response.
|
114
|
+
#
|
115
|
+
# @param response [Hash] The JSON parsed results from rubygems.org.
|
116
|
+
# @return [Gem::Version] the current version of the gem
|
117
|
+
def get_version_from_response(response)
|
118
|
+
Gem::Version.new(response.fetch(:number))
|
119
|
+
end
|
120
|
+
|
121
|
+
# Gets a well-formed gem description from the parsed response.
|
122
|
+
#
|
123
|
+
# @param response [Hash] The JSON parsed results from rubygems.org.
|
124
|
+
# @return [String] the gem description or summary ending in a full-stop
|
125
|
+
def format_description_from_response(response)
|
126
|
+
description = response.fetch(:description)
|
127
|
+
description = response.fetch(:summary) if description.empty?
|
128
|
+
|
129
|
+
# Replace any newlines or tabs (which would mess up a PKGBUILD) with
|
130
|
+
# spaces. Then, make sure there is no
|
131
|
+
description = description.gsub(/[[:space:]]+/, ' ').strip
|
132
|
+
|
133
|
+
# Ensure that the description ends in a full-stop.
|
134
|
+
description += '.' unless description[-1, 1] == '.'
|
135
|
+
|
136
|
+
description
|
137
|
+
end
|
138
|
+
|
139
|
+
# Gets the sha256 checksum returned from the rubygems.org API.
|
140
|
+
#
|
141
|
+
# @param response [Hash] The JSON parsed results from rubygems.org.
|
142
|
+
# @return [String] the sha256 sum of the gem file
|
143
|
+
def get_checksum_from_response(response)
|
144
|
+
response.fetch(:sha)
|
145
|
+
end
|
146
|
+
|
147
|
+
# Get the array of licenses under which the gem is licensed.
|
148
|
+
#
|
149
|
+
# @param response [Hash] The JSON parsed results from rubygems.org.
|
150
|
+
# @return [Array] the licenses for the gem
|
151
|
+
def get_licenses_from_response(response)
|
152
|
+
response.fetch(:licenses)
|
153
|
+
end
|
154
|
+
|
155
|
+
# Get all other gem dependencies for the given version.
|
156
|
+
#
|
157
|
+
# @param version [String|Gem::Version] The version for which to get the
|
158
|
+
# dependencies.
|
159
|
+
# @return [Array] list of other gems upon which the gem depends
|
160
|
+
def get_dependencies_for_version(version)
|
161
|
+
version = Gem::Version.new(version) if version.is_a?(String)
|
162
|
+
|
163
|
+
payload = Marshal.load(agent.get(deps).body)
|
164
|
+
|
165
|
+
dependencies = payload.find do |v|
|
166
|
+
Gem::Version.new(v[:number]) == version
|
167
|
+
end
|
168
|
+
|
169
|
+
dependencies[:dependencies].map(&:first)
|
170
|
+
end
|
171
|
+
|
172
|
+
# Scrape the rubygems.org frontend for the gem's homepage URL.
|
173
|
+
#
|
174
|
+
# @return [String] the homepage URL of the gem
|
175
|
+
def scrape_frontend_for_homepage_url
|
176
|
+
html = agent.get(gem).body
|
177
|
+
links = Nokogiri::HTML(html).css('a')
|
178
|
+
|
179
|
+
homepage_link = links.find do |a|
|
180
|
+
a.text.strip == 'Homepage'
|
181
|
+
end
|
182
|
+
|
183
|
+
homepage_link[:href]
|
184
|
+
end
|
185
|
+
|
186
|
+
# Quick method to get all important information in a single hash for
|
187
|
+
# later processing.
|
188
|
+
#
|
189
|
+
# @return [Hash] hash containing all the information available from the
|
190
|
+
# rubygems.org APIs and website
|
191
|
+
def scrape!
|
192
|
+
response = query_latest_version
|
193
|
+
version = get_version_from_response(response)
|
194
|
+
|
195
|
+
{
|
196
|
+
version: version,
|
197
|
+
description: format_description_from_response(response),
|
198
|
+
checksum: get_checksum_from_response(response),
|
199
|
+
license: get_licenses_from_response(response),
|
200
|
+
dependencies: get_dependencies_for_version(version),
|
201
|
+
homepage: scrape_frontend_for_homepage_url
|
202
|
+
}
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# Generated with gembuild (https://github.com/mfinelli/gembuild)
|
2
|
+
# Maintainer: <%= maintainer %>
|
3
|
+
<% unless contributor.count.zero? -%><% contributor.each do |c| -%>
|
4
|
+
# Contributor: <%= c %>
|
5
|
+
<% end -%><% end -%>
|
6
|
+
|
7
|
+
_gemname=<%= gemname %>
|
8
|
+
pkgname=ruby-$_gemname
|
9
|
+
pkgver=<%= pkgver %>
|
10
|
+
pkgrel=<%= pkgrel %>
|
11
|
+
<% unless epoch.zero? -%>
|
12
|
+
epoch=<%= epoch %>
|
13
|
+
<% end -%>
|
14
|
+
pkgdesc='<%= description %>'
|
15
|
+
arch=('<%= arch.join("' '") %>')
|
16
|
+
url='<%= url %>'
|
17
|
+
<% unless license.count.zero? -%>
|
18
|
+
license=('<%= license.join("' '") %>')
|
19
|
+
<% end -%>
|
20
|
+
options=(<%= options.join(' ') %>)
|
21
|
+
noextract=(<%= noextract.join(' ') %>)
|
22
|
+
depends=('<%= depends.join("' '") %>')
|
23
|
+
makedepends=('<%= makedepends.join("' '") %>')
|
24
|
+
source=("<%= source.join("\" \"") %>")
|
25
|
+
<%= checksum_type %>sums=('<%= checksum %>')
|
26
|
+
|
27
|
+
package() {
|
28
|
+
cd "$srcdir"
|
29
|
+
local _gemdir="$(ruby -e'puts Gem.default_dir')"
|
30
|
+
|
31
|
+
gem install --ignore-dependencies --no-user-install -i "$pkgdir/$_gemdir" -n "$pkgdir/usr/bin" $_gemname-$pkgver.gem
|
32
|
+
}
|
@@ -0,0 +1,283 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# Gembuild: create Arch Linux PKGBUILDs for ruby gems.
|
4
|
+
# Copyright (C) 2015 Mario Finelli <mario@finel.li>
|
5
|
+
#
|
6
|
+
# This program is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU General Public License as published by
|
8
|
+
# the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# This program is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU General Public License
|
17
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
|
19
|
+
require 'erb'
|
20
|
+
|
21
|
+
module Gembuild
|
22
|
+
# Class used to create a PKGBUILD file for a rubygem.
|
23
|
+
#
|
24
|
+
# @!attribute [rw] arch
|
25
|
+
# @see https://wiki.archlinux.org/index.php/PKGBUILD#arch
|
26
|
+
# @return [Array] the supported architectures
|
27
|
+
# @!attribute [rw] checksum
|
28
|
+
# @see https://wiki.archlinux.org/index.php/PKGBUILD#sha256sums
|
29
|
+
# @return [String] the sha256 sum of the gemfile
|
30
|
+
# @!attribute [rw] checksum_type
|
31
|
+
# @see https://wiki.archlinux.org/index.php/PKGBUILD#sha256sums
|
32
|
+
# @return [String] the type of checksum (will always be sha256)
|
33
|
+
# @!attribute [rw] contributor
|
34
|
+
# @return [Array] an array of the contributors to the pkgbuild
|
35
|
+
# @!attribute [rw] depends
|
36
|
+
# @see https://wiki.archlinux.org/index.php/PKGBUILD#depends
|
37
|
+
# @return [Array] an array of the package's dependencies (always ruby
|
38
|
+
# plus any other gems listed as dependencies)
|
39
|
+
# @!attribute [rw] description
|
40
|
+
# @see https://wiki.archlinux.org/index.php/PKGBUILD#pkgdesc
|
41
|
+
# @return [String] the package description
|
42
|
+
# @!attribute [rw] epoch
|
43
|
+
# @see https://wiki.archlinux.org/index.php/PKGBUILD#epoch
|
44
|
+
# @return [Fixnum] the package's epoch value
|
45
|
+
# @!attribute [rw] gemname
|
46
|
+
# @return [String] the ruby gem for which to generate a PKGBUILD
|
47
|
+
# @!attribute [rw] license
|
48
|
+
# @see https://wiki.archlinux.org/index.php/PKGBUILD#license
|
49
|
+
# @return [Array] an array of licenses for the gem
|
50
|
+
# @!attribute [rw] maintainer
|
51
|
+
# @return [String] the package's maintainer
|
52
|
+
# @!attribute [rw] makedepends
|
53
|
+
# @see https://wiki.archlinux.org/index.php/PKGBUILD#makedepends
|
54
|
+
# @return [Array] a list of the dependencies needed to build the package
|
55
|
+
# (normally just the package rubygems)
|
56
|
+
# @!attribute [rw] noextract
|
57
|
+
# @see https://wiki.archlinux.org/index.php/PKGBUILD#noextract
|
58
|
+
# @return [Array] a list of sources not to extract with bsdtar (namely,
|
59
|
+
# the gemfile)
|
60
|
+
# @!attribute [rw] options
|
61
|
+
# @see https://wiki.archlinux.org/index.php/PKGBUILD#options
|
62
|
+
# @return [Array] a list of options to pass to makepkg
|
63
|
+
# @!attribute [rw] pkgname
|
64
|
+
# @see https://wiki.archlinux.org/index.php/PKGBUILD#pkgname
|
65
|
+
# @return [String] the name of the package (usually ruby-gem)
|
66
|
+
# @!attribute [rw] pkgrel
|
67
|
+
# @see https://wiki.archlinux.org/index.php/PKGBUILD#pkgrel
|
68
|
+
# @return [Fixnum] the release number of the package
|
69
|
+
# @!attribute [rw] pkgver
|
70
|
+
# @see https://wiki.archlinux.org/index.php/PKGBUILD#pkgver
|
71
|
+
# @return [Gem::Version] the version of the gem
|
72
|
+
# @!attribute [rw] source
|
73
|
+
# @see https://wiki.archlinux.org/index.php/PKGBUILD#source
|
74
|
+
# @return [Array] a list of sources
|
75
|
+
# @!attribute [rw] url
|
76
|
+
# @see https://wiki.archlinux.org/index.php/PKGBUILD#url
|
77
|
+
# @return [String] the URL of the homepage of the gem
|
78
|
+
class Pkgbuild
|
79
|
+
attr_accessor :arch, :checksum, :checksum_type, :contributor, :depends,
|
80
|
+
:description, :epoch, :gemname, :license, :maintainer,
|
81
|
+
:makedepends, :noextract, :options, :pkgname, :pkgrel,
|
82
|
+
:pkgver, :source, :url
|
83
|
+
|
84
|
+
# Create a new Pkgbuild instance.
|
85
|
+
#
|
86
|
+
# @raise [Gembuild::InvalidPkgbuildError] if something other than a
|
87
|
+
# string or nil is passed as the existing pkgbuild
|
88
|
+
#
|
89
|
+
# @param gemname [String] The rubygem for which to create a PKGBUILD.
|
90
|
+
# @param existing_pkgbuild [nil, String] An old PKGBUILD that can be
|
91
|
+
# parsed for maintainer and contributor information.
|
92
|
+
# @return [Gembuild::Pkgbuild] a new Pkgbuild instance
|
93
|
+
def initialize(gemname, existing_pkgbuild = nil)
|
94
|
+
unless existing_pkgbuild.nil? || existing_pkgbuild.is_a?(String)
|
95
|
+
fail Gembuild::InvalidPkgbuildError
|
96
|
+
end
|
97
|
+
|
98
|
+
@gemname = gemname
|
99
|
+
@pkgname = "ruby-#{@gemname}"
|
100
|
+
|
101
|
+
set_package_defaults
|
102
|
+
|
103
|
+
no_parse_pkgbuild = existing_pkgbuild.nil? || existing_pkgbuild.empty?
|
104
|
+
parse_existing_pkgbuild(existing_pkgbuild) unless no_parse_pkgbuild
|
105
|
+
end
|
106
|
+
|
107
|
+
# Parse the old pkgbuild (if it exists) to get information about old
|
108
|
+
# maintainers or contributors or about other dependencies that have been
|
109
|
+
# added but that can not be scraped from rubygems.org.
|
110
|
+
#
|
111
|
+
# @param pkgbuild [String] The old PKGBUILD to parse.
|
112
|
+
# @return [Hash] a hash containing the values scraped from the PKGBUILD
|
113
|
+
def parse_existing_pkgbuild(pkgbuild)
|
114
|
+
pkgbuild.match(/^# Maintainer: (.*)$/) { |m| @maintainer = m[1] }
|
115
|
+
|
116
|
+
@contributor = pkgbuild.scan(/^# Contributor: (.*)$/).flatten
|
117
|
+
|
118
|
+
deps = parse_existing_dependencies(pkgbuild)
|
119
|
+
deps.each do |dep|
|
120
|
+
@depends << dep
|
121
|
+
end
|
122
|
+
|
123
|
+
{ maintainer: maintainer, contributor: contributor, depends: deps }
|
124
|
+
end
|
125
|
+
|
126
|
+
# Create a new Pkgbuild instance with all information from the scraped
|
127
|
+
# sources assigned.
|
128
|
+
#
|
129
|
+
# @param gemname [String] The rubygem for which to create a Pkgbuild.
|
130
|
+
# @param existing_pkgbuild [String, nil] An old PKGBUILD that can be
|
131
|
+
# parsed for maintainer information.
|
132
|
+
# @return [Gembuild::Pkgbuild] a new Pkgbuild instance
|
133
|
+
def self.create(gemname, existing_pkgbuild = nil)
|
134
|
+
pkgbuild = Pkgbuild.new(gemname, existing_pkgbuild)
|
135
|
+
|
136
|
+
pkgbuild.fetch_maintainer
|
137
|
+
|
138
|
+
gem_details = Gembuild::GemScraper.new(gemname).scrape!
|
139
|
+
aur_details = Gembuild::AurScraper.new(pkgbuild.pkgname).scrape!
|
140
|
+
|
141
|
+
pkgbuild.assign_gem_details(gem_details)
|
142
|
+
pkgbuild.assign_aur_details(aur_details)
|
143
|
+
|
144
|
+
pkgbuild
|
145
|
+
end
|
146
|
+
|
147
|
+
# Generate a PKGBUILD from the class using the pkgbuild erb template.
|
148
|
+
#
|
149
|
+
# @return [String] the PKGBUILD
|
150
|
+
def render
|
151
|
+
ERB.new(template, 0, '-').result(binding)
|
152
|
+
end
|
153
|
+
|
154
|
+
# Get the PKGBUILD erb template.
|
155
|
+
#
|
156
|
+
# @return [String] the pkgbuild erb template
|
157
|
+
def template
|
158
|
+
File.read(File.join(File.dirname(__FILE__), 'pkgbuild.erb'))
|
159
|
+
end
|
160
|
+
|
161
|
+
# Write the PKGBUILD to disk.
|
162
|
+
#
|
163
|
+
# @param path [String] The directory to write the PKGBUILD.
|
164
|
+
# @return [Fixnum] the number of bytes written
|
165
|
+
def write(path = '')
|
166
|
+
File.write(File.join(File.expand_path(path), 'PKGBUILD'), render)
|
167
|
+
end
|
168
|
+
|
169
|
+
# Obfuscate the maintainer/contributors' email addresses to (help to)
|
170
|
+
# prevent spam.
|
171
|
+
#
|
172
|
+
# @param contact_information [String] The maintainer or contributor
|
173
|
+
# byline.
|
174
|
+
# @return [String] the information with the @s and .s exchanged
|
175
|
+
def format_contact_information(contact_information)
|
176
|
+
contact_information.gsub('@', ' at ').gsub('.', ' dot ')
|
177
|
+
end
|
178
|
+
|
179
|
+
# Set the correct maintainer for the PKGBUILD.
|
180
|
+
#
|
181
|
+
# If the current maintainer is nil (no old pkgbuild was passed), then do
|
182
|
+
# nothing. If there is a maintainer then compare it to the configured
|
183
|
+
# maintainer and if they are different then make the old maintainer a
|
184
|
+
# contributor before setting the correct maintainer. If the maintainer is
|
185
|
+
# nil then just set the confgured maintainer.
|
186
|
+
#
|
187
|
+
# @return [String] the pkgbuild maintainer
|
188
|
+
def fetch_maintainer
|
189
|
+
configured_maintainer = Gembuild.configure
|
190
|
+
m = "#{configured_maintainer[:name]} <#{configured_maintainer[:email]}>"
|
191
|
+
new_maintainer = format_contact_information(m)
|
192
|
+
|
193
|
+
unless maintainer.nil? || new_maintainer == maintainer
|
194
|
+
@contributor.unshift(maintainer)
|
195
|
+
end
|
196
|
+
|
197
|
+
@maintainer = new_maintainer
|
198
|
+
end
|
199
|
+
|
200
|
+
# Add the data scraped from rubygems.org to the pkgbuild.
|
201
|
+
#
|
202
|
+
# @param details [Hash] The results from GemScraper scrape.
|
203
|
+
# @return [void]
|
204
|
+
def assign_gem_details(details)
|
205
|
+
@pkgver = details.fetch(:version)
|
206
|
+
@description = details.fetch(:description)
|
207
|
+
@checksum = details.fetch(:checksum)
|
208
|
+
@license = details.fetch(:license)
|
209
|
+
@url = details.fetch(:homepage)
|
210
|
+
|
211
|
+
details.fetch(:dependencies).each do |dependency|
|
212
|
+
@depends << "ruby-#{dependency}"
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
# Assign version information based on the information gathered from the
|
217
|
+
# AUR.
|
218
|
+
#
|
219
|
+
# @param details [Hash, nil] The results from AurScraper scrape or nil if
|
220
|
+
# the package does not yet exist on the AUR.
|
221
|
+
# @return [void]
|
222
|
+
def assign_aur_details(details)
|
223
|
+
if details.nil?
|
224
|
+
@epoch = 0
|
225
|
+
@pkgrel = 1
|
226
|
+
else
|
227
|
+
perform_version_reconciliation(details)
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
private
|
232
|
+
|
233
|
+
# Set the static variables of a new pkgbuild.
|
234
|
+
#
|
235
|
+
# @return [nil]
|
236
|
+
def set_package_defaults
|
237
|
+
@checksum_type = 'sha256'
|
238
|
+
@arch = ['any']
|
239
|
+
@makedepends = ['rubygems']
|
240
|
+
@depends = ['ruby']
|
241
|
+
@source = ['https://rubygems.org/downloads/$_gemname-$pkgver.gem']
|
242
|
+
@noextract = ['$_gemname-$pkgver.gem']
|
243
|
+
@options = ['!emptydirs']
|
244
|
+
@contributor = []
|
245
|
+
|
246
|
+
nil
|
247
|
+
end
|
248
|
+
|
249
|
+
# Scrape dependencies from an existing pkgbuild.
|
250
|
+
#
|
251
|
+
# @param pkgbuild [String] The PKGBUILD to search.
|
252
|
+
# @return [Array] all existing dependencies that are not ruby or gems
|
253
|
+
def parse_existing_dependencies(pkgbuild)
|
254
|
+
match = pkgbuild.match(/^depends=\((.*?)\)$/m)[1]
|
255
|
+
|
256
|
+
# First step is to remove the leading and trailing quotes. Then convert
|
257
|
+
# all whitespace (newlines, tabs, multiple spaces, etc.) to single
|
258
|
+
# spaces. Then, make sure that strings are quoted with ' not ".
|
259
|
+
# Finally, split the packages into an array.
|
260
|
+
deps = match[1..-2].gsub(/[[:space:]]+/, ' ').tr('"', "'").split("' '")
|
261
|
+
|
262
|
+
deps.reject { |e| e.match(/^ruby/) }
|
263
|
+
rescue
|
264
|
+
[]
|
265
|
+
end
|
266
|
+
|
267
|
+
# Assign the correct pkgrel and epoch depending on the current pkgver on
|
268
|
+
# the AUR and the version of the gem from rubygems.org.
|
269
|
+
#
|
270
|
+
# @param details [Hash] The results from AurScraper scrape
|
271
|
+
# @return [void]
|
272
|
+
def perform_version_reconciliation(details)
|
273
|
+
@epoch = details.fetch(:epoch)
|
274
|
+
@pkgrel = 1
|
275
|
+
|
276
|
+
if pkgver < details.fetch(:pkgver)
|
277
|
+
@epoch += 1
|
278
|
+
elsif @pkgver == details.fetch(:pkgver)
|
279
|
+
@pkgrel = details.fetch(:pkgrel) + 1
|
280
|
+
end
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|