gembuild 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|