/[gentoo-x86]/eclass/ruby-fakegem.eclass
Gentoo

Contents of /eclass/ruby-fakegem.eclass

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.42 - (show annotations) (download)
Sun Dec 7 07:23:12 2014 UTC (3 years, 9 months ago) by graaff
Branch: MAIN
Changes since 1.41: +9 -5 lines
Allow additional content to be injected in the ruby bin wrapper.

1 # Copyright 1999-2014 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
3 # $Header: /var/cvsroot/gentoo-x86/eclass/ruby-fakegem.eclass,v 1.41 2014/04/21 07:35:43 graaff Exp $
4
5 # @ECLASS: ruby-fakegem.eclass
6 # @MAINTAINER:
7 # Ruby herd <ruby@gentoo.org>
8 # @AUTHOR:
9 # Author: Diego E. Pettenò <flameeyes@gentoo.org>
10 # Author: Alex Legler <a3li@gentoo.org>
11 # @BLURB: An eclass for installing Ruby packages to behave like RubyGems.
12 # @DESCRIPTION:
13 # This eclass allows to install arbitrary Ruby libraries (including Gems),
14 # providing integration into the RubyGems system even for "regular" packages.
15
16 inherit ruby-ng
17
18 # @ECLASS-VARIABLE: RUBY_FAKEGEM_NAME
19 # @DESCRIPTION:
20 # Sets the Gem name for the generated fake gemspec.
21 # RUBY_FAKEGEM_NAME="${PN}"
22
23 # @ECLASS-VARIABLE: RUBY_FAKEGEM_VERSION
24 # @DESCRIPTION:
25 # Sets the Gem version for the generated fake gemspec.
26 # RUBY_FAKEGEM_VERSION="${PV}"
27
28 # @ECLASS-VARIABLE: RUBY_FAKEGEM_TASK_DOC
29 # @DESCRIPTION:
30 # Specify the rake(1) task to run to generate documentation.
31 # RUBY_FAKEGEM_TASK_DOC="rdoc"
32
33 # @ECLASS-VARIABLE: RUBY_FAKEGEM_RECIPE_TEST
34 # @DESCRIPTION:
35 # Specify one of the default testing function for ruby-fakegem:
36 # - rake (default; see also RUBY_FAKEGEM_TASK_TEST)
37 # - rspec (calls ruby-ng_rspec, adds dev-ruby/rspec:2 to the dependencies)
38 # - cucumber (calls ruby-ng_cucumber, adds dev-util/cucumber to the
39 # dependencies; does not work on JRuby).
40 # - none
41 # RUBY_FAKEGEM_RECIPE_TEST="rake"
42
43 # @ECLASS-VARIABLE: RUBY_FAKEGEM_TASK_TEST
44 # @DESCRIPTION:
45 # Specify the rake(1) task used for executing tests. Only valid
46 # if RUBY_FAKEGEM_RECIPE_TEST is set to "rake" (the default).
47 # RUBY_FAKEGEM_TASK_TEST="test"
48
49 # @ECLASS-VARIABLE: RUBY_FAKEGEM_RECIPE_DOC
50 # @DESCRIPTION:
51 # Specify one of the default API doc building function for ruby-fakegem:
52 # - rake (default; see also RUBY_FAKEGEM_TASK_DOC)
53 # - rdoc (calls `rdoc-2`, adds dev-ruby/rdoc to the dependencies);
54 # - yard (calls `yard`, adds dev-ruby/yard to the dependencies);
55 # - none
56 # RUBY_FAKEGEM_RECIPE_DOC="rake"
57
58 # @ECLASS-VARIABLE: RUBY_FAKEGEM_DOCDIR
59 # @DESCRIPTION:
60 # Specify the directory under which the documentation is built;
61 # if empty no documentation will be installed automatically.
62 # Note: if RUBY_FAKEGEM_RECIPE_DOC is set to `rdoc`, this variable is
63 # hardwired to `doc`.
64 # RUBY_FAKEGEM_DOCDIR=""
65
66 # @ECLASS-VARIABLE: RUBY_FAKEGEM_EXTRADOC
67 # @DESCRIPTION:
68 # Extra documentation to install (readme, changelogs, …).
69 # RUBY_FAKEGEM_EXTRADOC=""
70
71 # @ECLASS-VARIABLE: RUBY_FAKEGEM_DOC_SOURCES
72 # @DESCRIPTION:
73 # Allow settings defined sources to scan for documentation.
74 # This only applies if RUBY_FAKEGEM_DOC_TASK is set to `rdoc`.
75 # RUBY_FAKEGEM_DOC_SOURCES="lib"
76
77 # @ECLASS-VARIABLE: RUBY_FAKEGEM_BINWRAP
78 # @DESCRIPTION:
79 # Binaries to wrap around (relative to the bin/ directory)
80 # RUBY_FAKEGEM_BINWRAP="*"
81
82 # @ECLASS-VARIABLE: RUBY_FAKEGEM_REQUIRE_PATHS
83 # @DESCRIPTION:
84 # Extra require paths (beside lib) to add to the specification
85 # RUBY_FAKEGEM_REQUIRE_PATHS=""
86
87 # @ECLASS-VARIABLE: RUBY_FAKEGEM_GEMSPEC
88 # @DESCRIPTION:
89 # Filename of .gemspec file to install instead of generating a generic one.
90 # RUBY_FAKEGEM_GEMSPEC=""
91
92 # @ECLASS-VARIABLE: RUBY_FAKEGEM_EXTRAINSTALL
93 # @DESCRIPTION:
94 # List of files and directories relative to the top directory that also
95 # get installed. Some gems provide extra files such as version information,
96 # Rails generators, or data that needs to be installed as well.
97 # RUBY_FAKEGEM_EXTRAINSTALL=""
98
99 RUBY_FAKEGEM_NAME="${RUBY_FAKEGEM_NAME:-${PN}}"
100 RUBY_FAKEGEM_VERSION="${RUBY_FAKEGEM_VERSION:-${PV/_pre/.pre}}"
101 RUBY_FAKEGEM_SUFFIX="${RUBY_FAKEGEM_SUFFIX:-}"
102
103 RUBY_FAKEGEM_RECIPE_DOC="${RUBY_FAKEGEM_RECIPE_DOC-rake}"
104 RUBY_FAKEGEM_TASK_DOC="${RUBY_FAKEGEM_TASK_DOC-rdoc}"
105 RUBY_FAKEGEM_DOC_SOURCES="${RUBY_FAKEGEM_DOC_SOURCES-lib}"
106
107 RUBY_FAKEGEM_RECIPE_TEST="${RUBY_FAKEGEM_RECIPE_TEST-rake}"
108 RUBY_FAKEGEM_TASK_TEST="${RUBY_FAKEGEM_TASK_TEST-test}"
109
110 RUBY_FAKEGEM_BINWRAP="${RUBY_FAKEGEM_BINWRAP-*}"
111
112 [[ ${RUBY_FAKEGEM_TASK_DOC} == "" ]] && RUBY_FAKEGEM_RECIPE_DOC="none"
113
114 case ${RUBY_FAKEGEM_RECIPE_DOC} in
115 rake)
116 IUSE+=" doc"
117 ruby_add_bdepend "doc? ( dev-ruby/rake )"
118 RUBY_FAKEGEM_DOCDIR="doc"
119 ;;
120 rdoc)
121 IUSE+=" doc"
122 ruby_add_bdepend "doc? ( dev-ruby/rdoc )"
123 RUBY_FAKEGEM_DOCDIR="doc"
124 ;;
125 yard)
126 IUSE+="doc"
127 ruby_add_bdepend "doc? ( dev-ruby/yard )"
128 RUBY_FAKEGEM_DOCDIR="doc"
129 ;;
130 none)
131 [[ -n ${RUBY_FAKEGEM_DOCDIR} ]] && IUSE+=" doc"
132 ;;
133 esac
134
135 [[ ${RUBY_FAKEGEM_TASK_TEST} == "" ]] && RUBY_FAKEGEM_RECIPE_TEST="none"
136
137 case ${RUBY_FAKEGEM_RECIPE_TEST} in
138 rake)
139 IUSE+=" test"
140 ruby_add_bdepend "test? ( dev-ruby/rake )"
141 ;;
142 rspec)
143 IUSE+=" test"
144 ruby_add_bdepend "test? ( dev-ruby/rspec:2 )"
145 ;;
146 cucumber)
147 IUSE+=" test"
148 # Unfortunately as of August 2012, cucumber is not supported on
149 # JRuby. We work it around here to avoid repeating the same
150 # code over and over again.
151 USE_RUBY="${USE_RUBY/jruby/}" ruby_add_bdepend "test? ( dev-util/cucumber )"
152 ;;
153 *)
154 RUBY_FAKEGEM_RECIPE_TEST="none"
155 ;;
156 esac
157
158 SRC_URI="mirror://rubygems/${RUBY_FAKEGEM_NAME}-${RUBY_FAKEGEM_VERSION}${RUBY_FAKEGEM_SUFFIX:+-${RUBY_FAKEGEM_SUFFIX}}.gem"
159
160 ruby_add_bdepend virtual/rubygems
161 ruby_add_rdepend virtual/rubygems
162
163 # @FUNCTION: ruby_fakegem_gemsdir
164 # @RETURN: Returns the gem data directory
165 # @DESCRIPTION:
166 # This function returns the gems data directory for the ruby
167 # implementation in question.
168 ruby_fakegem_gemsdir() {
169 has "${EAPI}" 2 && ! use prefix && EPREFIX=
170
171 local _gemsitedir=$(ruby_rbconfig_value 'sitelibdir')
172 _gemsitedir=${_gemsitedir//site_ruby/gems}
173 _gemsitedir=${_gemsitedir#${EPREFIX}}
174
175 [[ -z ${_gemsitedir} ]] && {
176 eerror "Unable to find the gems dir"
177 die "Unable to find the gems dir"
178 }
179
180 echo "${_gemsitedir}"
181 }
182
183 # @FUNCTION: ruby_fakegem_doins
184 # @USAGE: file [file...]
185 # @DESCRIPTION:
186 # Installs the specified file(s) into the gems directory.
187 ruby_fakegem_doins() {
188 (
189 insinto $(ruby_fakegem_gemsdir)/gems/${RUBY_FAKEGEM_NAME}-${RUBY_FAKEGEM_VERSION}
190 doins "$@"
191 ) || die "failed $0 $@"
192 }
193
194 # @FUNCTION: ruby_fakegem_newsins()
195 # @USAGE: file filename
196 # @DESCRIPTION:
197 # Installs the specified file into the gems directory using the provided filename.
198 ruby_fakegem_newins() {
199 (
200 # Since newins does not accept full paths but just basenames
201 # for the target file, we want to extend it here.
202 local newdirname=/$(dirname "$2")
203 [[ ${newdirname} == "/." ]] && newdirname=
204
205 local newbasename=$(basename "$2")
206
207 insinto $(ruby_fakegem_gemsdir)/gems/${RUBY_FAKEGEM_NAME}-${RUBY_FAKEGEM_VERSION}${newdirname}
208 newins "$1" ${newbasename}
209 ) || die "failed $0 $@"
210 }
211
212 # @FUNCTION: ruby_fakegem_install_gemspec
213 # @DESCRIPTION:
214 # Install a .gemspec file for this package. Either use the file indicated
215 # by the RUBY_FAKEGEM_GEMSPEC variable, or generate one using
216 # ruby_fakegem_genspec.
217 ruby_fakegem_install_gemspec() {
218 local gemspec="${T}"/${RUBY_FAKEGEM_NAME}-${_ruby_implementation}
219
220 (
221 if [[ ${RUBY_FAKEGEM_GEMSPEC} != "" ]]; then
222 ruby_fakegem_gemspec_gemspec ${RUBY_FAKEGEM_GEMSPEC} ${gemspec}
223 else
224 local metadata="${WORKDIR}"/${_ruby_implementation}/metadata
225
226 if [[ -e ${metadata} ]]; then
227 ruby_fakegem_metadata_gemspec ${metadata} ${gemspec}
228 else
229 ruby_fakegem_genspec ${gemspec}
230 fi
231 fi
232 ) || die "Unable to generate gemspec file."
233
234 insinto $(ruby_fakegem_gemsdir)/specifications
235 newins ${gemspec} ${RUBY_FAKEGEM_NAME}-${RUBY_FAKEGEM_VERSION}.gemspec || die "Unable to install gemspec file."
236 }
237
238 # @FUNCTION: ruby_fakegem_gemspec_gemspec
239 # @USAGE: gemspec-input gemspec-output
240 # @DESCRIPTION:
241 # Generates an installable version of the specification indicated by
242 # RUBY_FAKEGEM_GEMSPEC. This file is eval'ed to produce a final specification
243 # in a way similar to packaging the gemspec file.
244 ruby_fakegem_gemspec_gemspec() {
245 ${RUBY} -e "puts eval(File::open('$1').read).to_ruby" > $2
246 }
247
248 # @FUNCTION: ruby_fakegem_metadata_gemspec
249 # @USAGE: gemspec-metadata gemspec-output
250 # @DESCRIPTION:
251 # Generates an installable version of the specification indicated by
252 # the metadata distributed by the gem itself. This is similar to how
253 # rubygems creates an installation from a .gem file.
254 ruby_fakegem_metadata_gemspec() {
255 case ${RUBY} in
256 *jruby)
257 ${RUBY} -r yaml -e "puts Gem::Specification.from_yaml(File::open('$1').read).to_ruby" > $2
258 ;;
259 *)
260 ${RUBY} -r yaml -e "puts Gem::Specification.from_yaml(File::open('$1', :encoding => 'UTF-8').read).to_ruby" > $2
261 ;;
262 esac
263 }
264
265 # @FUNCTION: ruby_fakegem_genspec
266 # @USAGE: output-gemspec
267 # @DESCRIPTION:
268 # Generates a gemspec for the package and places it into the "specifications"
269 # directory of RubyGems.
270 # If the metadata normally distributed with a gem is present then that is
271 # used to generate the gemspec file.
272 #
273 # As a fallback we can generate our own version.
274 # In the gemspec, the following values are set: name, version, summary,
275 # homepage, and require_paths=["lib"].
276 # See RUBY_FAKEGEM_NAME and RUBY_FAKEGEM_VERSION for setting name and version.
277 # See RUBY_FAKEGEM_REQUIRE_PATHS for setting extra require paths.
278 ruby_fakegem_genspec() {
279 local required_paths="'lib'"
280 for path in ${RUBY_FAKEGEM_REQUIRE_PATHS}; do
281 required_paths="${required_paths}, '${path}'"
282 done
283
284 # We use the _ruby_implementation variable to avoid having stray
285 # copies with different implementations; while for now we're using
286 # the same exact content, we might have differences in the future,
287 # so better taking this into consideration.
288 local quoted_description=${DESCRIPTION//\"/\\\"}
289 cat - > $1 <<EOF
290 # generated by ruby-fakegem.eclass $Revision: 1.41 $
291 Gem::Specification.new do |s|
292 s.name = "${RUBY_FAKEGEM_NAME}"
293 s.version = "${RUBY_FAKEGEM_VERSION}"
294 s.summary = "${quoted_description}"
295 s.homepage = "${HOMEPAGE}"
296 s.require_paths = [${required_paths}]
297 end
298 EOF
299 }
300
301 # @FUNCTION: ruby_fakegem_binwrapper
302 # @USAGE: command [path] [content]
303 # @DESCRIPTION:
304 # Creates a new binary wrapper for a command installed by the RubyGem.
305 # path defaults to /usr/bin/$command content is optional and can be used
306 # to inject additional ruby code into the wrapper. This may be useful to
307 # e.g. force a specific version using the gem command.
308 ruby_fakegem_binwrapper() {
309 (
310 local gembinary=$1
311 local newbinary=${2:-/usr/bin/$gembinary}
312 local content=$3
313 local relativegembinary=${RUBY_FAKEGEM_NAME}-${RUBY_FAKEGEM_VERSION}/bin/${gembinary}
314 local binpath=$(dirname $newbinary)
315 [[ ${binpath} = . ]] && binpath=/usr/bin
316
317 # Try to find out whether the package is going to install for
318 # one or multiple implementations; if we're installing for a
319 # *single* implementation, no need to use “/usr/bin/env ruby”
320 # in the shebang, and we can actually avoid errors when
321 # calling the script by default (see for instance the
322 # JRuby-specific commands).
323 local rubycmd=
324 for implementation in ${USE_RUBY}; do
325 # ignore non-enabled implementations
326 use ruby_targets_${implementation} || continue
327 if [ -z $rubycmd ]; then
328 # if no other implementation was set before, set it.
329 rubycmd="$(ruby_implementation_command ${implementation})"
330 else
331 # if another implementation already arrived, then make
332 # it generic and break out of the loop. This ensures
333 # that we do at most two iterations.
334 rubycmd="/usr/bin/env ruby"
335 break
336 fi
337 done
338
339 cat - > "${T}"/gembin-wrapper-${gembinary} <<EOF
340 #!${rubycmd}
341 # This is a simplified version of the RubyGems wrapper
342 #
343 # Generated by ruby-fakegem.eclass $Revision: 1.41 $
344
345 require 'rubygems'
346
347 ${content}
348 load Gem::default_path[-1] + "/gems/${relativegembinary}"
349
350 EOF
351
352 exeinto ${binpath:-/usr/bin}
353 newexe "${T}"/gembin-wrapper-${gembinary} $(basename $newbinary)
354 ) || die "Unable to create fakegem wrapper"
355 }
356
357 # @FUNCTION: all_fakegem_compile
358 # @DESCRIPTION:
359 # Build documentation for the package if indicated by the doc USE flag
360 # and if there is a documetation task defined.
361 all_fakegem_compile() {
362 if [[ -n ${RUBY_FAKEGEM_DOCDIR} ]] && use doc; then
363 case ${RUBY_FAKEGEM_RECIPE_DOC} in
364 rake)
365 rake ${RUBY_FAKEGEM_TASK_DOC} || die "failed to (re)build documentation"
366 ;;
367 rdoc)
368 rdoc ${RUBY_FAKEGEM_DOC_SOURCES} || die "failed to (re)build documentation"
369 ;;
370 yard)
371 yard doc ${RUBY_FAKEGEM_DOC_SOURCES} || die "failed to (re)build documentation"
372 ;;
373 esac
374 fi
375 }
376
377 # @FUNCTION: all_ruby_unpack
378 # @DESCRIPTION:
379 # Unpack the source archive, including support for unpacking gems.
380 all_ruby_unpack() {
381 # Special support for extracting .gem files; the file need to be
382 # extracted twice and the mtime from the archive _has_ to be
383 # ignored (it's always set to epoch 0).
384 for archive in ${A}; do
385 case "${archive}" in
386 *.gem)
387 # Make sure that we're not running unpack for more than
388 # one .gem file, since we won't support that at all.
389 [[ -d "${S}" ]] && die "Unable to unpack ${archive}, ${S} exists"
390
391 ebegin "Unpacking .gem file..."
392 tar -mxf "${DISTDIR}"/${archive} || die
393 eend $?
394
395 ebegin "Uncompressing metadata"
396 gunzip metadata.gz || die
397 eend $?
398
399 mkdir "${S}"
400 pushd "${S}" &>/dev/null
401
402 ebegin "Unpacking data.tar.gz"
403 tar -mxf "${my_WORKDIR}"/data.tar.gz || die
404 eend $?
405
406 popd &>/dev/null
407 ;;
408 *.patch.bz2)
409 # We apply the patches with RUBY_PATCHES directly from DISTDIR,
410 # as the WORKDIR variable changes value between the global-scope
411 # and the time all_ruby_unpack/_prepare are called. Since we can
412 # simply decompress them when applying, this is much easier to
413 # deal with for us.
414 einfo "Keeping ${archive} as-is"
415 ;;
416 *)
417 unpack ${archive}
418 ;;
419 esac
420 done
421 }
422
423 # @FUNCTION: all_ruby_compile
424 # @DESCRIPTION:
425 # Compile the package.
426 all_ruby_compile() {
427 all_fakegem_compile
428 }
429
430 # @FUNCTION: each_fakegem_test
431 # @DESCRIPTION:
432 # Run tests for the package for each ruby target if the test task is defined.
433 each_fakegem_test() {
434 case ${RUBY_FAKEGEM_RECIPE_TEST} in
435 rake)
436 ${RUBY} -S rake ${RUBY_FAKEGEM_TASK_TEST} || die "tests failed"
437 ;;
438 rspec)
439 ruby-ng_rspec
440 ;;
441 cucumber)
442 ruby-ng_cucumber
443 ;;
444 none)
445 ewarn "each_fakegem_test called, but \${RUBY_FAKEGEM_RECIPE_TEST} is 'none'"
446 ;;
447 esac
448 }
449
450 if [[ ${RUBY_FAKEGEM_RECIPE_TEST} != none ]]; then
451 # @FUNCTION: each_ruby_test
452 # @DESCRIPTION:
453 # Run the tests for this package.
454 each_ruby_test() {
455 each_fakegem_test
456 }
457 fi
458
459 # @FUNCTION: each_fakegem_install
460 # @DESCRIPTION:
461 # Install the package for each ruby target.
462 each_fakegem_install() {
463 ruby_fakegem_install_gemspec
464
465 local _gemlibdirs="${RUBY_FAKEGEM_EXTRAINSTALL}"
466 for directory in bin lib; do
467 [[ -d ${directory} ]] && _gemlibdirs="${_gemlibdirs} ${directory}"
468 done
469
470 [[ -n ${_gemlibdirs} ]] && \
471 ruby_fakegem_doins -r ${_gemlibdirs}
472 }
473
474 # @FUNCTION: each_ruby_install
475 # @DESCRIPTION:
476 # Install the package for each target.
477 each_ruby_install() {
478 each_fakegem_install
479 }
480
481 # @FUNCTION: all_fakegem_install
482 # @DESCRIPTION:
483 # Install files common to all ruby targets.
484 all_fakegem_install() {
485 if [[ -n ${RUBY_FAKEGEM_DOCDIR} ]] && use doc; then
486 for dir in ${RUBY_FAKEGEM_DOCDIR}; do
487 [[ -d ${dir} ]] || continue
488
489 pushd ${dir} &>/dev/null
490 dohtml -r * || die "failed to install documentation"
491 popd &>/dev/null
492 done
493 fi
494
495 if [[ -n ${RUBY_FAKEGEM_EXTRADOC} ]]; then
496 dodoc ${RUBY_FAKEGEM_EXTRADOC} || die "failed to install further documentation"
497 fi
498
499 # binary wrappers; we assume that all the implementations get the
500 # same binaries, or something is wrong anyway, so...
501 if [[ -n ${RUBY_FAKEGEM_BINWRAP} ]]; then
502 local bindir=$(find "${D}" -type d -path "*/gems/${RUBY_FAKEGEM_NAME}-${RUBY_FAKEGEM_VERSION}/bin" -print -quit)
503
504 if [[ -d "${bindir}" ]]; then
505 pushd "${bindir}" &>/dev/null
506 local binaries=$(eval ls ${RUBY_FAKEGEM_BINWRAP})
507 for binary in $binaries; do
508 ruby_fakegem_binwrapper $binary
509 done
510 popd &>/dev/null
511 fi
512 fi
513 }
514
515 # @FUNCTION: all_ruby_install
516 # @DESCRIPTION:
517 # Install files common to all ruby targets.
518 all_ruby_install() {
519 all_fakegem_install
520 }

  ViewVC Help
Powered by ViewVC 1.1.20