Merge lp:~antono/quickly/ruby-templates into lp:quickly

Proposed by Antono Vasiljev
Status: Rejected
Rejected by: Didier Roche-Tolomelli
Proposed branch: lp:~antono/quickly/ruby-templates
Merge into: lp:quickly
Diff against target: 1690 lines (+1653/-1)
5 files modified
data/templates/ubuntu-cli-ruby/commandsconfig (+10/-0)
data/templates/ubuntu-cli-ruby/project_root/AUTHORS (+1/-0)
data/templates/ubuntu-cli-ruby/project_root/bin/project_name (+55/-0)
data/templates/ubuntu-cli-ruby/project_root/setup.rb (+1585/-0)
debian/control (+2/-1)
To merge this branch: bzr merge lp:~antono/quickly/ruby-templates
Reviewer Review Type Date Requested Status
Didier Roche-Tolomelli Needs Fixing
Review via email: mp+24952@code.launchpad.net

Description of the change

Added ubuntu-cli-ruby template

To post a comment you must log in.
Revision history for this message
Shane Fagan (shanepatrickfagan) wrote :

Looks good to me but ill wait for didrocks to make sure.

Revision history for this message
Antono Vasiljev (antono) wrote :

I think template package should be splitted by languages.
I going to add javascript (gjs/seed) template

It would be great to have good naming conventions for packages

 * quickly-ubuntu-template-python
 * quickly-ubuntu-template-ruby
 * quickly-ubuntu-template-javascript
 * quickly-ubuntu-template-$LANG

Revision history for this message
Shane Fagan (shanepatrickfagan) wrote :

I get what you mean but id say we should use CLI or GTK in the name of the template.
So if the template doesnt use GTK or Qt or Clutter..etc then it should be named like this IMO
quickly-template-cli-LANG
quickly-template-gtk-LANG
quickly-template-qt-LANG

Revision history for this message
Antono Vasiljev (antono) wrote :

Yep. And maybe metapackage for each language

+ quickly-templates-ruby
-> quickly-template-qt-ruby
-> quickly-template-gtk-ruby
-> quickly-template-cli-ruby

Revision history for this message
Didier Roche-Tolomelli (didrocks) wrote :

Thanks for your work there. It seems cool, even if I haven't ruby knowledge.

Looking at it, I guess you want to change (and not import) the package/share/release commands to build ruby package and making the package dependency detection working properly.

review: Needs Fixing
Revision history for this message
Shane Fagan (shanepatrickfagan) wrote :

Has this been worked on since it was marked as "Needs Fixing"?

Revision history for this message
Didier Roche-Tolomelli (didrocks) wrote :

I think this MR doesn't apply anymore, cleaning the list :)

Unmerged revisions

508. By Antono Vasiljev

Add ruby as dependency for quickly-ubuntu-template

Maybe package should be splitted to

 * quickly-ubuntu-template-python
 * quickly-ubuntu-template-ruby
 * quickly-ubuntu-template-otherlang

507. By Antono Vasiljev

Files for ubuntu-cli-ruby template

506. By Antono Vasiljev

Quicliy template ubuntu-cli-ruby

Template for simple ruby command line appication...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory 'data/templates/ubuntu-cli-ruby'
2=== added file 'data/templates/ubuntu-cli-ruby/commandsconfig'
3--- data/templates/ubuntu-cli-ruby/commandsconfig 1970-01-01 00:00:00 +0000
4+++ data/templates/ubuntu-cli-ruby/commandsconfig 2010-05-09 02:46:22 +0000
5@@ -0,0 +1,10 @@
6+# define parameters for commands, putting them in a list seperated
7+# by ';'
8+# if nothing specified, default is to launch command inside a project
9+# only and not be followed by a template
10+#COMMANDS_LAUNCHED_IN_OR_OUTSIDE_PROJECT =
11+COMMANDS_LAUNCHED_OUTSIDE_PROJECT_ONLY = create
12+#COMMANDS_FOLLOWED_BY_COMMAND =
13+
14+[ubuntu-application]
15+IMPORT=configure;create;debug;edit;license;package;release;run;save;share
16
17=== added directory 'data/templates/ubuntu-cli-ruby/project_root'
18=== added file 'data/templates/ubuntu-cli-ruby/project_root/AUTHORS'
19--- data/templates/ubuntu-cli-ruby/project_root/AUTHORS 1970-01-01 00:00:00 +0000
20+++ data/templates/ubuntu-cli-ruby/project_root/AUTHORS 2010-05-09 02:46:22 +0000
21@@ -0,0 +1,1 @@
22+Copyright (C) YYYY <Your Name> <Your E-mail>
23
24=== added directory 'data/templates/ubuntu-cli-ruby/project_root/bin'
25=== added file 'data/templates/ubuntu-cli-ruby/project_root/bin/project_name'
26--- data/templates/ubuntu-cli-ruby/project_root/bin/project_name 1970-01-01 00:00:00 +0000
27+++ data/templates/ubuntu-cli-ruby/project_root/bin/project_name 2010-05-09 02:46:22 +0000
28@@ -0,0 +1,55 @@
29+#!/usr/bin/env ruby
30+# -*- coding: utf-8 -*-
31+### BEGIN LICENSE
32+# This file is in the public domain
33+### END LICENSE
34+
35+require 'optparse'
36+
37+options = {}
38+
39+optparse = OptionParser.new do|opts|
40+
41+ # Set a banner, displayed at the top
42+ # of the help screen.
43+ opts.banner = "Usage: project_name [options] file1 file2 ..."
44+
45+ # Define the options, and what they do
46+ options[:verbose] = false
47+ opts.on( '-v', '--verbose', 'Output more information' ) do
48+ options[:verbose] = true
49+ end
50+
51+ options[:quick] = false
52+ opts.on( '-q', '--quick', 'Perform the task quickly' ) do
53+ options[:quick] = true
54+ end
55+
56+ options[:logfile] = nil
57+ opts.on( '-l', '--logfile FILE', 'Write log to FILE' ) do |file|
58+ options[:logfile] = file
59+ end
60+
61+ # This displays the help screen, all programs are
62+ # assumed to have this option.
63+ opts.on( '-h', '--help', 'Display this screen' ) do
64+ puts opts
65+ exit
66+ end
67+end
68+
69+# Parse the command-line. Remember there are two forms
70+# of the parse method. The 'parse' method simply parses
71+# ARGV, while the 'parse!' method parses ARGV and removes
72+# any options found there, as well as any parameters for
73+# the options. What's left is the list of files to resize.
74+optparse.parse!
75+
76+puts "Being verbose" if options[:verbose]
77+puts "Being quick" if options[:quick]
78+puts "Logging to file #{options[:logfile]}" if options[:logfile]
79+
80+ARGV.each do |file|
81+ puts "Doing something with file #{file}..."
82+ sleep 0.5
83+end
84
85=== added directory 'data/templates/ubuntu-cli-ruby/project_root/lib'
86=== added directory 'data/templates/ubuntu-cli-ruby/project_root/lib/python_name'
87=== added file 'data/templates/ubuntu-cli-ruby/project_root/lib/python_name.rb'
88=== added file 'data/templates/ubuntu-cli-ruby/project_root/setup.rb'
89--- data/templates/ubuntu-cli-ruby/project_root/setup.rb 1970-01-01 00:00:00 +0000
90+++ data/templates/ubuntu-cli-ruby/project_root/setup.rb 2010-05-09 02:46:22 +0000
91@@ -0,0 +1,1585 @@
92+#
93+# setup.rb
94+#
95+# Copyright (c) 2000-2005 Minero Aoki
96+#
97+# This program is free software.
98+# You can distribute/modify this program under the terms of
99+# the GNU LGPL, Lesser General Public License version 2.1.
100+#
101+
102+unless Enumerable.method_defined?(:map) # Ruby 1.4.6
103+ module Enumerable
104+ alias map collect
105+ end
106+end
107+
108+unless File.respond_to?(:read) # Ruby 1.6
109+ def File.read(fname)
110+ open(fname) {|f|
111+ return f.read
112+ }
113+ end
114+end
115+
116+unless Errno.const_defined?(:ENOTEMPTY) # Windows?
117+ module Errno
118+ class ENOTEMPTY
119+ # We do not raise this exception, implementation is not needed.
120+ end
121+ end
122+end
123+
124+def File.binread(fname)
125+ open(fname, 'rb') {|f|
126+ return f.read
127+ }
128+end
129+
130+# for corrupted Windows' stat(2)
131+def File.dir?(path)
132+ File.directory?((path[-1,1] == '/') ? path : path + '/')
133+end
134+
135+
136+class ConfigTable
137+
138+ include Enumerable
139+
140+ def initialize(rbconfig)
141+ @rbconfig = rbconfig
142+ @items = []
143+ @table = {}
144+ # options
145+ @install_prefix = nil
146+ @config_opt = nil
147+ @verbose = true
148+ @no_harm = false
149+ end
150+
151+ attr_accessor :install_prefix
152+ attr_accessor :config_opt
153+
154+ attr_writer :verbose
155+
156+ def verbose?
157+ @verbose
158+ end
159+
160+ attr_writer :no_harm
161+
162+ def no_harm?
163+ @no_harm
164+ end
165+
166+ def [](key)
167+ lookup(key).resolve(self)
168+ end
169+
170+ def []=(key, val)
171+ lookup(key).set val
172+ end
173+
174+ def names
175+ @items.map {|i| i.name }
176+ end
177+
178+ def each(&block)
179+ @items.each(&block)
180+ end
181+
182+ def key?(name)
183+ @table.key?(name)
184+ end
185+
186+ def lookup(name)
187+ @table[name] or setup_rb_error "no such config item: #{name}"
188+ end
189+
190+ def add(item)
191+ @items.push item
192+ @table[item.name] = item
193+ end
194+
195+ def remove(name)
196+ item = lookup(name)
197+ @items.delete_if {|i| i.name == name }
198+ @table.delete_if {|name, i| i.name == name }
199+ item
200+ end
201+
202+ def load_script(path, inst = nil)
203+ if File.file?(path)
204+ MetaConfigEnvironment.new(self, inst).instance_eval File.read(path), path
205+ end
206+ end
207+
208+ def savefile
209+ '.config'
210+ end
211+
212+ def load_savefile
213+ begin
214+ File.foreach(savefile()) do |line|
215+ k, v = *line.split(/=/, 2)
216+ self[k] = v.strip
217+ end
218+ rescue Errno::ENOENT
219+ setup_rb_error $!.message + "\n#{File.basename($0)} config first"
220+ end
221+ end
222+
223+ def save
224+ @items.each {|i| i.value }
225+ File.open(savefile(), 'w') {|f|
226+ @items.each do |i|
227+ f.printf "%s=%s\n", i.name, i.value if i.value? and i.value
228+ end
229+ }
230+ end
231+
232+ def load_standard_entries
233+ standard_entries(@rbconfig).each do |ent|
234+ add ent
235+ end
236+ end
237+
238+ def standard_entries(rbconfig)
239+ c = rbconfig
240+
241+ rubypath = File.join(c['bindir'], c['ruby_install_name'] + c['EXEEXT'])
242+
243+ major = c['MAJOR'].to_i
244+ minor = c['MINOR'].to_i
245+ teeny = c['TEENY'].to_i
246+ version = "#{major}.#{minor}"
247+
248+ # ruby ver. >= 1.4.4?
249+ newpath_p = ((major >= 2) or
250+ ((major == 1) and
251+ ((minor >= 5) or
252+ ((minor == 4) and (teeny >= 4)))))
253+
254+ if c['rubylibdir']
255+ # V > 1.6.3
256+ libruby = "#{c['prefix']}/lib/ruby"
257+ librubyver = c['rubylibdir']
258+ librubyverarch = c['archdir']
259+ siteruby = c['sitedir']
260+ siterubyver = c['sitelibdir']
261+ siterubyverarch = c['sitearchdir']
262+ elsif newpath_p
263+ # 1.4.4 <= V <= 1.6.3
264+ libruby = "#{c['prefix']}/lib/ruby"
265+ librubyver = "#{c['prefix']}/lib/ruby/#{version}"
266+ librubyverarch = "#{c['prefix']}/lib/ruby/#{version}/#{c['arch']}"
267+ siteruby = c['sitedir']
268+ siterubyver = "$siteruby/#{version}"
269+ siterubyverarch = "$siterubyver/#{c['arch']}"
270+ else
271+ # V < 1.4.4
272+ libruby = "#{c['prefix']}/lib/ruby"
273+ librubyver = "#{c['prefix']}/lib/ruby/#{version}"
274+ librubyverarch = "#{c['prefix']}/lib/ruby/#{version}/#{c['arch']}"
275+ siteruby = "#{c['prefix']}/lib/ruby/#{version}/site_ruby"
276+ siterubyver = siteruby
277+ siterubyverarch = "$siterubyver/#{c['arch']}"
278+ end
279+ parameterize = lambda {|path|
280+ path.sub(/\A#{Regexp.quote(c['prefix'])}/, '$prefix')
281+ }
282+
283+ if arg = c['configure_args'].split.detect {|arg| /--with-make-prog=/ =~ arg }
284+ makeprog = arg.sub(/'/, '').split(/=/, 2)[1]
285+ else
286+ makeprog = 'make'
287+ end
288+
289+ [
290+ ExecItem.new('installdirs', 'std/site/home',
291+ 'std: install under libruby; site: install under site_ruby; home: install under $HOME')\
292+ {|val, table|
293+ case val
294+ when 'std'
295+ table['rbdir'] = '$librubyver'
296+ table['sodir'] = '$librubyverarch'
297+ when 'site'
298+ table['rbdir'] = '$siterubyver'
299+ table['sodir'] = '$siterubyverarch'
300+ when 'home'
301+ setup_rb_error '$HOME was not set' unless ENV['HOME']
302+ table['prefix'] = ENV['HOME']
303+ table['rbdir'] = '$libdir/ruby'
304+ table['sodir'] = '$libdir/ruby'
305+ end
306+ },
307+ PathItem.new('prefix', 'path', c['prefix'],
308+ 'path prefix of target environment'),
309+ PathItem.new('bindir', 'path', parameterize.call(c['bindir']),
310+ 'the directory for commands'),
311+ PathItem.new('libdir', 'path', parameterize.call(c['libdir']),
312+ 'the directory for libraries'),
313+ PathItem.new('datadir', 'path', parameterize.call(c['datadir']),
314+ 'the directory for shared data'),
315+ PathItem.new('mandir', 'path', parameterize.call(c['mandir']),
316+ 'the directory for man pages'),
317+ PathItem.new('sysconfdir', 'path', parameterize.call(c['sysconfdir']),
318+ 'the directory for system configuration files'),
319+ PathItem.new('localstatedir', 'path', parameterize.call(c['localstatedir']),
320+ 'the directory for local state data'),
321+ PathItem.new('libruby', 'path', libruby,
322+ 'the directory for ruby libraries'),
323+ PathItem.new('librubyver', 'path', librubyver,
324+ 'the directory for standard ruby libraries'),
325+ PathItem.new('librubyverarch', 'path', librubyverarch,
326+ 'the directory for standard ruby extensions'),
327+ PathItem.new('siteruby', 'path', siteruby,
328+ 'the directory for version-independent aux ruby libraries'),
329+ PathItem.new('siterubyver', 'path', siterubyver,
330+ 'the directory for aux ruby libraries'),
331+ PathItem.new('siterubyverarch', 'path', siterubyverarch,
332+ 'the directory for aux ruby binaries'),
333+ PathItem.new('rbdir', 'path', '$siterubyver',
334+ 'the directory for ruby scripts'),
335+ PathItem.new('sodir', 'path', '$siterubyverarch',
336+ 'the directory for ruby extentions'),
337+ PathItem.new('rubypath', 'path', rubypath,
338+ 'the path to set to #! line'),
339+ ProgramItem.new('rubyprog', 'name', rubypath,
340+ 'the ruby program using for installation'),
341+ ProgramItem.new('makeprog', 'name', makeprog,
342+ 'the make program to compile ruby extentions'),
343+ SelectItem.new('shebang', 'all/ruby/never', 'ruby',
344+ 'shebang line (#!) editing mode'),
345+ BoolItem.new('without-ext', 'yes/no', 'no',
346+ 'does not compile/install ruby extentions')
347+ ]
348+ end
349+ private :standard_entries
350+
351+ def load_multipackage_entries
352+ multipackage_entries().each do |ent|
353+ add ent
354+ end
355+ end
356+
357+ def multipackage_entries
358+ [
359+ PackageSelectionItem.new('with', 'name,name...', '', 'ALL',
360+ 'package names that you want to install'),
361+ PackageSelectionItem.new('without', 'name,name...', '', 'NONE',
362+ 'package names that you do not want to install')
363+ ]
364+ end
365+ private :multipackage_entries
366+
367+ ALIASES = {
368+ 'std-ruby' => 'librubyver',
369+ 'stdruby' => 'librubyver',
370+ 'rubylibdir' => 'librubyver',
371+ 'archdir' => 'librubyverarch',
372+ 'site-ruby-common' => 'siteruby', # For backward compatibility
373+ 'site-ruby' => 'siterubyver', # For backward compatibility
374+ 'bin-dir' => 'bindir',
375+ 'bin-dir' => 'bindir',
376+ 'rb-dir' => 'rbdir',
377+ 'so-dir' => 'sodir',
378+ 'data-dir' => 'datadir',
379+ 'ruby-path' => 'rubypath',
380+ 'ruby-prog' => 'rubyprog',
381+ 'ruby' => 'rubyprog',
382+ 'make-prog' => 'makeprog',
383+ 'make' => 'makeprog'
384+ }
385+
386+ def fixup
387+ ALIASES.each do |ali, name|
388+ @table[ali] = @table[name]
389+ end
390+ @items.freeze
391+ @table.freeze
392+ @options_re = /\A--(#{@table.keys.join('|')})(?:=(.*))?\z/
393+ end
394+
395+ def parse_opt(opt)
396+ m = @options_re.match(opt) or setup_rb_error "config: unknown option #{opt}"
397+ m.to_a[1,2]
398+ end
399+
400+ def dllext
401+ @rbconfig['DLEXT']
402+ end
403+
404+ def value_config?(name)
405+ lookup(name).value?
406+ end
407+
408+ class Item
409+ def initialize(name, template, default, desc)
410+ @name = name.freeze
411+ @template = template
412+ @value = default
413+ @default = default
414+ @description = desc
415+ end
416+
417+ attr_reader :name
418+ attr_reader :description
419+
420+ attr_accessor :default
421+ alias help_default default
422+
423+ def help_opt
424+ "--#{@name}=#{@template}"
425+ end
426+
427+ def value?
428+ true
429+ end
430+
431+ def value
432+ @value
433+ end
434+
435+ def resolve(table)
436+ @value.gsub(%r<\$([^/]+)>) { table[$1] }
437+ end
438+
439+ def set(val)
440+ @value = check(val)
441+ end
442+
443+ private
444+
445+ def check(val)
446+ setup_rb_error "config: --#{name} requires argument" unless val
447+ val
448+ end
449+ end
450+
451+ class BoolItem < Item
452+ def config_type
453+ 'bool'
454+ end
455+
456+ def help_opt
457+ "--#{@name}"
458+ end
459+
460+ private
461+
462+ def check(val)
463+ return 'yes' unless val
464+ case val
465+ when /\Ay(es)?\z/i, /\At(rue)?\z/i then 'yes'
466+ when /\An(o)?\z/i, /\Af(alse)\z/i then 'no'
467+ else
468+ setup_rb_error "config: --#{@name} accepts only yes/no for argument"
469+ end
470+ end
471+ end
472+
473+ class PathItem < Item
474+ def config_type
475+ 'path'
476+ end
477+
478+ private
479+
480+ def check(path)
481+ setup_rb_error "config: --#{@name} requires argument" unless path
482+ path[0,1] == '$' ? path : File.expand_path(path)
483+ end
484+ end
485+
486+ class ProgramItem < Item
487+ def config_type
488+ 'program'
489+ end
490+ end
491+
492+ class SelectItem < Item
493+ def initialize(name, selection, default, desc)
494+ super
495+ @ok = selection.split('/')
496+ end
497+
498+ def config_type
499+ 'select'
500+ end
501+
502+ private
503+
504+ def check(val)
505+ unless @ok.include?(val.strip)
506+ setup_rb_error "config: use --#{@name}=#{@template} (#{val})"
507+ end
508+ val.strip
509+ end
510+ end
511+
512+ class ExecItem < Item
513+ def initialize(name, selection, desc, &block)
514+ super name, selection, nil, desc
515+ @ok = selection.split('/')
516+ @action = block
517+ end
518+
519+ def config_type
520+ 'exec'
521+ end
522+
523+ def value?
524+ false
525+ end
526+
527+ def resolve(table)
528+ setup_rb_error "$#{name()} wrongly used as option value"
529+ end
530+
531+ undef set
532+
533+ def evaluate(val, table)
534+ v = val.strip.downcase
535+ unless @ok.include?(v)
536+ setup_rb_error "invalid option --#{@name}=#{val} (use #{@template})"
537+ end
538+ @action.call v, table
539+ end
540+ end
541+
542+ class PackageSelectionItem < Item
543+ def initialize(name, template, default, help_default, desc)
544+ super name, template, default, desc
545+ @help_default = help_default
546+ end
547+
548+ attr_reader :help_default
549+
550+ def config_type
551+ 'package'
552+ end
553+
554+ private
555+
556+ def check(val)
557+ unless File.dir?("packages/#{val}")
558+ setup_rb_error "config: no such package: #{val}"
559+ end
560+ val
561+ end
562+ end
563+
564+ class MetaConfigEnvironment
565+ def initialize(config, installer)
566+ @config = config
567+ @installer = installer
568+ end
569+
570+ def config_names
571+ @config.names
572+ end
573+
574+ def config?(name)
575+ @config.key?(name)
576+ end
577+
578+ def bool_config?(name)
579+ @config.lookup(name).config_type == 'bool'
580+ end
581+
582+ def path_config?(name)
583+ @config.lookup(name).config_type == 'path'
584+ end
585+
586+ def value_config?(name)
587+ @config.lookup(name).config_type != 'exec'
588+ end
589+
590+ def add_config(item)
591+ @config.add item
592+ end
593+
594+ def add_bool_config(name, default, desc)
595+ @config.add BoolItem.new(name, 'yes/no', default ? 'yes' : 'no', desc)
596+ end
597+
598+ def add_path_config(name, default, desc)
599+ @config.add PathItem.new(name, 'path', default, desc)
600+ end
601+
602+ def set_config_default(name, default)
603+ @config.lookup(name).default = default
604+ end
605+
606+ def remove_config(name)
607+ @config.remove(name)
608+ end
609+
610+ # For only multipackage
611+ def packages
612+ raise '[setup.rb fatal] multi-package metaconfig API packages() called for single-package; contact application package vendor' unless @installer
613+ @installer.packages
614+ end
615+
616+ # For only multipackage
617+ def declare_packages(list)
618+ raise '[setup.rb fatal] multi-package metaconfig API declare_packages() called for single-package; contact application package vendor' unless @installer
619+ @installer.packages = list
620+ end
621+ end
622+
623+end # class ConfigTable
624+
625+
626+# This module requires: #verbose?, #no_harm?
627+module FileOperations
628+
629+ def mkdir_p(dirname, prefix = nil)
630+ dirname = prefix + File.expand_path(dirname) if prefix
631+ $stderr.puts "mkdir -p #{dirname}" if verbose?
632+ return if no_harm?
633+
634+ # Does not check '/', it's too abnormal.
635+ dirs = File.expand_path(dirname).split(%r<(?=/)>)
636+ if /\A[a-z]:\z/i =~ dirs[0]
637+ disk = dirs.shift
638+ dirs[0] = disk + dirs[0]
639+ end
640+ dirs.each_index do |idx|
641+ path = dirs[0..idx].join('')
642+ Dir.mkdir path unless File.dir?(path)
643+ end
644+ end
645+
646+ def rm_f(path)
647+ $stderr.puts "rm -f #{path}" if verbose?
648+ return if no_harm?
649+ force_remove_file path
650+ end
651+
652+ def rm_rf(path)
653+ $stderr.puts "rm -rf #{path}" if verbose?
654+ return if no_harm?
655+ remove_tree path
656+ end
657+
658+ def remove_tree(path)
659+ if File.symlink?(path)
660+ remove_file path
661+ elsif File.dir?(path)
662+ remove_tree0 path
663+ else
664+ force_remove_file path
665+ end
666+ end
667+
668+ def remove_tree0(path)
669+ Dir.foreach(path) do |ent|
670+ next if ent == '.'
671+ next if ent == '..'
672+ entpath = "#{path}/#{ent}"
673+ if File.symlink?(entpath)
674+ remove_file entpath
675+ elsif File.dir?(entpath)
676+ remove_tree0 entpath
677+ else
678+ force_remove_file entpath
679+ end
680+ end
681+ begin
682+ Dir.rmdir path
683+ rescue Errno::ENOTEMPTY
684+ # directory may not be empty
685+ end
686+ end
687+
688+ def move_file(src, dest)
689+ force_remove_file dest
690+ begin
691+ File.rename src, dest
692+ rescue
693+ File.open(dest, 'wb') {|f|
694+ f.write File.binread(src)
695+ }
696+ File.chmod File.stat(src).mode, dest
697+ File.unlink src
698+ end
699+ end
700+
701+ def force_remove_file(path)
702+ begin
703+ remove_file path
704+ rescue
705+ end
706+ end
707+
708+ def remove_file(path)
709+ File.chmod 0777, path
710+ File.unlink path
711+ end
712+
713+ def install(from, dest, mode, prefix = nil)
714+ $stderr.puts "install #{from} #{dest}" if verbose?
715+ return if no_harm?
716+
717+ realdest = prefix ? prefix + File.expand_path(dest) : dest
718+ realdest = File.join(realdest, File.basename(from)) if File.dir?(realdest)
719+ str = File.binread(from)
720+ if diff?(str, realdest)
721+ verbose_off {
722+ rm_f realdest if File.exist?(realdest)
723+ }
724+ File.open(realdest, 'wb') {|f|
725+ f.write str
726+ }
727+ File.chmod mode, realdest
728+
729+ File.open("#{objdir_root()}/InstalledFiles", 'a') {|f|
730+ if prefix
731+ f.puts realdest.sub(prefix, '')
732+ else
733+ f.puts realdest
734+ end
735+ }
736+ end
737+ end
738+
739+ def diff?(new_content, path)
740+ return true unless File.exist?(path)
741+ new_content != File.binread(path)
742+ end
743+
744+ def command(*args)
745+ $stderr.puts args.join(' ') if verbose?
746+ system(*args) or raise RuntimeError,
747+ "system(#{args.map{|a| a.inspect }.join(' ')}) failed"
748+ end
749+
750+ def ruby(*args)
751+ command config('rubyprog'), *args
752+ end
753+
754+ def make(task = nil)
755+ command(*[config('makeprog'), task].compact)
756+ end
757+
758+ def extdir?(dir)
759+ File.exist?("#{dir}/MANIFEST") or File.exist?("#{dir}/extconf.rb")
760+ end
761+
762+ def files_of(dir)
763+ Dir.open(dir) {|d|
764+ return d.select {|ent| File.file?("#{dir}/#{ent}") }
765+ }
766+ end
767+
768+ DIR_REJECT = %w( . .. CVS SCCS RCS CVS.adm .svn )
769+
770+ def directories_of(dir)
771+ Dir.open(dir) {|d|
772+ return d.select {|ent| File.dir?("#{dir}/#{ent}") } - DIR_REJECT
773+ }
774+ end
775+
776+end
777+
778+
779+# This module requires: #srcdir_root, #objdir_root, #relpath
780+module HookScriptAPI
781+
782+ def get_config(key)
783+ @config[key]
784+ end
785+
786+ alias config get_config
787+
788+ # obsolete: use metaconfig to change configuration
789+ def set_config(key, val)
790+ @config[key] = val
791+ end
792+
793+ #
794+ # srcdir/objdir (works only in the package directory)
795+ #
796+
797+ def curr_srcdir
798+ "#{srcdir_root()}/#{relpath()}"
799+ end
800+
801+ def curr_objdir
802+ "#{objdir_root()}/#{relpath()}"
803+ end
804+
805+ def srcfile(path)
806+ "#{curr_srcdir()}/#{path}"
807+ end
808+
809+ def srcexist?(path)
810+ File.exist?(srcfile(path))
811+ end
812+
813+ def srcdirectory?(path)
814+ File.dir?(srcfile(path))
815+ end
816+
817+ def srcfile?(path)
818+ File.file?(srcfile(path))
819+ end
820+
821+ def srcentries(path = '.')
822+ Dir.open("#{curr_srcdir()}/#{path}") {|d|
823+ return d.to_a - %w(. ..)
824+ }
825+ end
826+
827+ def srcfiles(path = '.')
828+ srcentries(path).select {|fname|
829+ File.file?(File.join(curr_srcdir(), path, fname))
830+ }
831+ end
832+
833+ def srcdirectories(path = '.')
834+ srcentries(path).select {|fname|
835+ File.dir?(File.join(curr_srcdir(), path, fname))
836+ }
837+ end
838+
839+end
840+
841+
842+class ToplevelInstaller
843+
844+ Version = '3.4.1'
845+ Copyright = 'Copyright (c) 2000-2005 Minero Aoki'
846+
847+ TASKS = [
848+ [ 'all', 'do config, setup, then install' ],
849+ [ 'config', 'saves your configurations' ],
850+ [ 'show', 'shows current configuration' ],
851+ [ 'setup', 'compiles ruby extentions and others' ],
852+ [ 'install', 'installs files' ],
853+ [ 'test', 'run all tests in test/' ],
854+ [ 'clean', "does `make clean' for each extention" ],
855+ [ 'distclean',"does `make distclean' for each extention" ]
856+ ]
857+
858+ def ToplevelInstaller.invoke
859+ config = ConfigTable.new(load_rbconfig())
860+ config.load_standard_entries
861+ config.load_multipackage_entries if multipackage?
862+ config.fixup
863+ klass = (multipackage?() ? ToplevelInstallerMulti : ToplevelInstaller)
864+ klass.new(File.dirname($0), config).invoke
865+ end
866+
867+ def ToplevelInstaller.multipackage?
868+ File.dir?(File.dirname($0) + '/packages')
869+ end
870+
871+ def ToplevelInstaller.load_rbconfig
872+ if arg = ARGV.detect {|arg| /\A--rbconfig=/ =~ arg }
873+ ARGV.delete(arg)
874+ load File.expand_path(arg.split(/=/, 2)[1])
875+ $".push 'rbconfig.rb'
876+ else
877+ require 'rbconfig'
878+ end
879+ ::Config::CONFIG
880+ end
881+
882+ def initialize(ardir_root, config)
883+ @ardir = File.expand_path(ardir_root)
884+ @config = config
885+ # cache
886+ @valid_task_re = nil
887+ end
888+
889+ def config(key)
890+ @config[key]
891+ end
892+
893+ def inspect
894+ "#<#{self.class} #{__id__()}>"
895+ end
896+
897+ def invoke
898+ run_metaconfigs
899+ case task = parsearg_global()
900+ when nil, 'all'
901+ parsearg_config
902+ init_installers
903+ exec_config
904+ exec_setup
905+ exec_install
906+ else
907+ case task
908+ when 'config', 'test'
909+ ;
910+ when 'clean', 'distclean'
911+ @config.load_savefile if File.exist?(@config.savefile)
912+ else
913+ @config.load_savefile
914+ end
915+ __send__ "parsearg_#{task}"
916+ init_installers
917+ __send__ "exec_#{task}"
918+ end
919+ end
920+
921+ def run_metaconfigs
922+ @config.load_script "#{@ardir}/metaconfig"
923+ end
924+
925+ def init_installers
926+ @installer = Installer.new(@config, @ardir, File.expand_path('.'))
927+ end
928+
929+ #
930+ # Hook Script API bases
931+ #
932+
933+ def srcdir_root
934+ @ardir
935+ end
936+
937+ def objdir_root
938+ '.'
939+ end
940+
941+ def relpath
942+ '.'
943+ end
944+
945+ #
946+ # Option Parsing
947+ #
948+
949+ def parsearg_global
950+ while arg = ARGV.shift
951+ case arg
952+ when /\A\w+\z/
953+ setup_rb_error "invalid task: #{arg}" unless valid_task?(arg)
954+ return arg
955+ when '-q', '--quiet'
956+ @config.verbose = false
957+ when '--verbose'
958+ @config.verbose = true
959+ when '--help'
960+ print_usage $stdout
961+ exit 0
962+ when '--version'
963+ puts "#{File.basename($0)} version #{Version}"
964+ exit 0
965+ when '--copyright'
966+ puts Copyright
967+ exit 0
968+ else
969+ setup_rb_error "unknown global option '#{arg}'"
970+ end
971+ end
972+ nil
973+ end
974+
975+ def valid_task?(t)
976+ valid_task_re() =~ t
977+ end
978+
979+ def valid_task_re
980+ @valid_task_re ||= /\A(?:#{TASKS.map {|task,desc| task }.join('|')})\z/
981+ end
982+
983+ def parsearg_no_options
984+ unless ARGV.empty?
985+ task = caller(0).first.slice(%r<`parsearg_(\w+)'>, 1)
986+ setup_rb_error "#{task}: unknown options: #{ARGV.join(' ')}"
987+ end
988+ end
989+
990+ alias parsearg_show parsearg_no_options
991+ alias parsearg_setup parsearg_no_options
992+ alias parsearg_test parsearg_no_options
993+ alias parsearg_clean parsearg_no_options
994+ alias parsearg_distclean parsearg_no_options
995+
996+ def parsearg_config
997+ evalopt = []
998+ set = []
999+ @config.config_opt = []
1000+ while i = ARGV.shift
1001+ if /\A--?\z/ =~ i
1002+ @config.config_opt = ARGV.dup
1003+ break
1004+ end
1005+ name, value = *@config.parse_opt(i)
1006+ if @config.value_config?(name)
1007+ @config[name] = value
1008+ else
1009+ evalopt.push [name, value]
1010+ end
1011+ set.push name
1012+ end
1013+ evalopt.each do |name, value|
1014+ @config.lookup(name).evaluate value, @config
1015+ end
1016+ # Check if configuration is valid
1017+ set.each do |n|
1018+ @config[n] if @config.value_config?(n)
1019+ end
1020+ end
1021+
1022+ def parsearg_install
1023+ @config.no_harm = false
1024+ @config.install_prefix = ''
1025+ while a = ARGV.shift
1026+ case a
1027+ when '--no-harm'
1028+ @config.no_harm = true
1029+ when /\A--prefix=/
1030+ path = a.split(/=/, 2)[1]
1031+ path = File.expand_path(path) unless path[0,1] == '/'
1032+ @config.install_prefix = path
1033+ else
1034+ setup_rb_error "install: unknown option #{a}"
1035+ end
1036+ end
1037+ end
1038+
1039+ def print_usage(out)
1040+ out.puts 'Typical Installation Procedure:'
1041+ out.puts " $ ruby #{File.basename $0} config"
1042+ out.puts " $ ruby #{File.basename $0} setup"
1043+ out.puts " # ruby #{File.basename $0} install (may require root privilege)"
1044+ out.puts
1045+ out.puts 'Detailed Usage:'
1046+ out.puts " ruby #{File.basename $0} <global option>"
1047+ out.puts " ruby #{File.basename $0} [<global options>] <task> [<task options>]"
1048+
1049+ fmt = " %-24s %s\n"
1050+ out.puts
1051+ out.puts 'Global options:'
1052+ out.printf fmt, '-q,--quiet', 'suppress message outputs'
1053+ out.printf fmt, ' --verbose', 'output messages verbosely'
1054+ out.printf fmt, ' --help', 'print this message'
1055+ out.printf fmt, ' --version', 'print version and quit'
1056+ out.printf fmt, ' --copyright', 'print copyright and quit'
1057+ out.puts
1058+ out.puts 'Tasks:'
1059+ TASKS.each do |name, desc|
1060+ out.printf fmt, name, desc
1061+ end
1062+
1063+ fmt = " %-24s %s [%s]\n"
1064+ out.puts
1065+ out.puts 'Options for CONFIG or ALL:'
1066+ @config.each do |item|
1067+ out.printf fmt, item.help_opt, item.description, item.help_default
1068+ end
1069+ out.printf fmt, '--rbconfig=path', 'rbconfig.rb to load',"running ruby's"
1070+ out.puts
1071+ out.puts 'Options for INSTALL:'
1072+ out.printf fmt, '--no-harm', 'only display what to do if given', 'off'
1073+ out.printf fmt, '--prefix=path', 'install path prefix', ''
1074+ out.puts
1075+ end
1076+
1077+ #
1078+ # Task Handlers
1079+ #
1080+
1081+ def exec_config
1082+ @installer.exec_config
1083+ @config.save # must be final
1084+ end
1085+
1086+ def exec_setup
1087+ @installer.exec_setup
1088+ end
1089+
1090+ def exec_install
1091+ @installer.exec_install
1092+ end
1093+
1094+ def exec_test
1095+ @installer.exec_test
1096+ end
1097+
1098+ def exec_show
1099+ @config.each do |i|
1100+ printf "%-20s %s\n", i.name, i.value if i.value?
1101+ end
1102+ end
1103+
1104+ def exec_clean
1105+ @installer.exec_clean
1106+ end
1107+
1108+ def exec_distclean
1109+ @installer.exec_distclean
1110+ end
1111+
1112+end # class ToplevelInstaller
1113+
1114+
1115+class ToplevelInstallerMulti < ToplevelInstaller
1116+
1117+ include FileOperations
1118+
1119+ def initialize(ardir_root, config)
1120+ super
1121+ @packages = directories_of("#{@ardir}/packages")
1122+ raise 'no package exists' if @packages.empty?
1123+ @root_installer = Installer.new(@config, @ardir, File.expand_path('.'))
1124+ end
1125+
1126+ def run_metaconfigs
1127+ @config.load_script "#{@ardir}/metaconfig", self
1128+ @packages.each do |name|
1129+ @config.load_script "#{@ardir}/packages/#{name}/metaconfig"
1130+ end
1131+ end
1132+
1133+ attr_reader :packages
1134+
1135+ def packages=(list)
1136+ raise 'package list is empty' if list.empty?
1137+ list.each do |name|
1138+ raise "directory packages/#{name} does not exist"\
1139+ unless File.dir?("#{@ardir}/packages/#{name}")
1140+ end
1141+ @packages = list
1142+ end
1143+
1144+ def init_installers
1145+ @installers = {}
1146+ @packages.each do |pack|
1147+ @installers[pack] = Installer.new(@config,
1148+ "#{@ardir}/packages/#{pack}",
1149+ "packages/#{pack}")
1150+ end
1151+ with = extract_selection(config('with'))
1152+ without = extract_selection(config('without'))
1153+ @selected = @installers.keys.select {|name|
1154+ (with.empty? or with.include?(name)) \
1155+ and not without.include?(name)
1156+ }
1157+ end
1158+
1159+ def extract_selection(list)
1160+ a = list.split(/,/)
1161+ a.each do |name|
1162+ setup_rb_error "no such package: #{name}" unless @installers.key?(name)
1163+ end
1164+ a
1165+ end
1166+
1167+ def print_usage(f)
1168+ super
1169+ f.puts 'Inluded packages:'
1170+ f.puts ' ' + @packages.sort.join(' ')
1171+ f.puts
1172+ end
1173+
1174+ #
1175+ # Task Handlers
1176+ #
1177+
1178+ def exec_config
1179+ run_hook 'pre-config'
1180+ each_selected_installers {|inst| inst.exec_config }
1181+ run_hook 'post-config'
1182+ @config.save # must be final
1183+ end
1184+
1185+ def exec_setup
1186+ run_hook 'pre-setup'
1187+ each_selected_installers {|inst| inst.exec_setup }
1188+ run_hook 'post-setup'
1189+ end
1190+
1191+ def exec_install
1192+ run_hook 'pre-install'
1193+ each_selected_installers {|inst| inst.exec_install }
1194+ run_hook 'post-install'
1195+ end
1196+
1197+ def exec_test
1198+ run_hook 'pre-test'
1199+ each_selected_installers {|inst| inst.exec_test }
1200+ run_hook 'post-test'
1201+ end
1202+
1203+ def exec_clean
1204+ rm_f @config.savefile
1205+ run_hook 'pre-clean'
1206+ each_selected_installers {|inst| inst.exec_clean }
1207+ run_hook 'post-clean'
1208+ end
1209+
1210+ def exec_distclean
1211+ rm_f @config.savefile
1212+ run_hook 'pre-distclean'
1213+ each_selected_installers {|inst| inst.exec_distclean }
1214+ run_hook 'post-distclean'
1215+ end
1216+
1217+ #
1218+ # lib
1219+ #
1220+
1221+ def each_selected_installers
1222+ Dir.mkdir 'packages' unless File.dir?('packages')
1223+ @selected.each do |pack|
1224+ $stderr.puts "Processing the package `#{pack}' ..." if verbose?
1225+ Dir.mkdir "packages/#{pack}" unless File.dir?("packages/#{pack}")
1226+ Dir.chdir "packages/#{pack}"
1227+ yield @installers[pack]
1228+ Dir.chdir '../..'
1229+ end
1230+ end
1231+
1232+ def run_hook(id)
1233+ @root_installer.run_hook id
1234+ end
1235+
1236+ # module FileOperations requires this
1237+ def verbose?
1238+ @config.verbose?
1239+ end
1240+
1241+ # module FileOperations requires this
1242+ def no_harm?
1243+ @config.no_harm?
1244+ end
1245+
1246+end # class ToplevelInstallerMulti
1247+
1248+
1249+class Installer
1250+
1251+ FILETYPES = %w( bin lib ext data conf man )
1252+
1253+ include FileOperations
1254+ include HookScriptAPI
1255+
1256+ def initialize(config, srcroot, objroot)
1257+ @config = config
1258+ @srcdir = File.expand_path(srcroot)
1259+ @objdir = File.expand_path(objroot)
1260+ @currdir = '.'
1261+ end
1262+
1263+ def inspect
1264+ "#<#{self.class} #{File.basename(@srcdir)}>"
1265+ end
1266+
1267+ def noop(rel)
1268+ end
1269+
1270+ #
1271+ # Hook Script API base methods
1272+ #
1273+
1274+ def srcdir_root
1275+ @srcdir
1276+ end
1277+
1278+ def objdir_root
1279+ @objdir
1280+ end
1281+
1282+ def relpath
1283+ @currdir
1284+ end
1285+
1286+ #
1287+ # Config Access
1288+ #
1289+
1290+ # module FileOperations requires this
1291+ def verbose?
1292+ @config.verbose?
1293+ end
1294+
1295+ # module FileOperations requires this
1296+ def no_harm?
1297+ @config.no_harm?
1298+ end
1299+
1300+ def verbose_off
1301+ begin
1302+ save, @config.verbose = @config.verbose?, false
1303+ yield
1304+ ensure
1305+ @config.verbose = save
1306+ end
1307+ end
1308+
1309+ #
1310+ # TASK config
1311+ #
1312+
1313+ def exec_config
1314+ exec_task_traverse 'config'
1315+ end
1316+
1317+ alias config_dir_bin noop
1318+ alias config_dir_lib noop
1319+
1320+ def config_dir_ext(rel)
1321+ extconf if extdir?(curr_srcdir())
1322+ end
1323+
1324+ alias config_dir_data noop
1325+ alias config_dir_conf noop
1326+ alias config_dir_man noop
1327+
1328+ def extconf
1329+ ruby "#{curr_srcdir()}/extconf.rb", *@config.config_opt
1330+ end
1331+
1332+ #
1333+ # TASK setup
1334+ #
1335+
1336+ def exec_setup
1337+ exec_task_traverse 'setup'
1338+ end
1339+
1340+ def setup_dir_bin(rel)
1341+ files_of(curr_srcdir()).each do |fname|
1342+ update_shebang_line "#{curr_srcdir()}/#{fname}"
1343+ end
1344+ end
1345+
1346+ alias setup_dir_lib noop
1347+
1348+ def setup_dir_ext(rel)
1349+ make if extdir?(curr_srcdir())
1350+ end
1351+
1352+ alias setup_dir_data noop
1353+ alias setup_dir_conf noop
1354+ alias setup_dir_man noop
1355+
1356+ def update_shebang_line(path)
1357+ return if no_harm?
1358+ return if config('shebang') == 'never'
1359+ old = Shebang.load(path)
1360+ if old
1361+ $stderr.puts "warning: #{path}: Shebang line includes too many args. It is not portable and your program may not work." if old.args.size > 1
1362+ new = new_shebang(old)
1363+ return if new.to_s == old.to_s
1364+ else
1365+ return unless config('shebang') == 'all'
1366+ new = Shebang.new(config('rubypath'))
1367+ end
1368+ $stderr.puts "updating shebang: #{File.basename(path)}" if verbose?
1369+ open_atomic_writer(path) {|output|
1370+ File.open(path, 'rb') {|f|
1371+ f.gets if old # discard
1372+ output.puts new.to_s
1373+ output.print f.read
1374+ }
1375+ }
1376+ end
1377+
1378+ def new_shebang(old)
1379+ if /\Aruby/ =~ File.basename(old.cmd)
1380+ Shebang.new(config('rubypath'), old.args)
1381+ elsif File.basename(old.cmd) == 'env' and old.args.first == 'ruby'
1382+ Shebang.new(config('rubypath'), old.args[1..-1])
1383+ else
1384+ return old unless config('shebang') == 'all'
1385+ Shebang.new(config('rubypath'))
1386+ end
1387+ end
1388+
1389+ def open_atomic_writer(path, &block)
1390+ tmpfile = File.basename(path) + '.tmp'
1391+ begin
1392+ File.open(tmpfile, 'wb', &block)
1393+ File.rename tmpfile, File.basename(path)
1394+ ensure
1395+ File.unlink tmpfile if File.exist?(tmpfile)
1396+ end
1397+ end
1398+
1399+ class Shebang
1400+ def Shebang.load(path)
1401+ line = nil
1402+ File.open(path) {|f|
1403+ line = f.gets
1404+ }
1405+ return nil unless /\A#!/ =~ line
1406+ parse(line)
1407+ end
1408+
1409+ def Shebang.parse(line)
1410+ cmd, *args = *line.strip.sub(/\A\#!/, '').split(' ')
1411+ new(cmd, args)
1412+ end
1413+
1414+ def initialize(cmd, args = [])
1415+ @cmd = cmd
1416+ @args = args
1417+ end
1418+
1419+ attr_reader :cmd
1420+ attr_reader :args
1421+
1422+ def to_s
1423+ "#! #{@cmd}" + (@args.empty? ? '' : " #{@args.join(' ')}")
1424+ end
1425+ end
1426+
1427+ #
1428+ # TASK install
1429+ #
1430+
1431+ def exec_install
1432+ rm_f 'InstalledFiles'
1433+ exec_task_traverse 'install'
1434+ end
1435+
1436+ def install_dir_bin(rel)
1437+ install_files targetfiles(), "#{config('bindir')}/#{rel}", 0755
1438+ end
1439+
1440+ def install_dir_lib(rel)
1441+ install_files libfiles(), "#{config('rbdir')}/#{rel}", 0644
1442+ end
1443+
1444+ def install_dir_ext(rel)
1445+ return unless extdir?(curr_srcdir())
1446+ install_files rubyextentions('.'),
1447+ "#{config('sodir')}/#{File.dirname(rel)}",
1448+ 0555
1449+ end
1450+
1451+ def install_dir_data(rel)
1452+ install_files targetfiles(), "#{config('datadir')}/#{rel}", 0644
1453+ end
1454+
1455+ def install_dir_conf(rel)
1456+ # FIXME: should not remove current config files
1457+ # (rename previous file to .old/.org)
1458+ install_files targetfiles(), "#{config('sysconfdir')}/#{rel}", 0644
1459+ end
1460+
1461+ def install_dir_man(rel)
1462+ install_files targetfiles(), "#{config('mandir')}/#{rel}", 0644
1463+ end
1464+
1465+ def install_files(list, dest, mode)
1466+ mkdir_p dest, @config.install_prefix
1467+ list.each do |fname|
1468+ install fname, dest, mode, @config.install_prefix
1469+ end
1470+ end
1471+
1472+ def libfiles
1473+ glob_reject(%w(*.y *.output), targetfiles())
1474+ end
1475+
1476+ def rubyextentions(dir)
1477+ ents = glob_select("*.#{@config.dllext}", targetfiles())
1478+ if ents.empty?
1479+ setup_rb_error "no ruby extention exists: 'ruby #{$0} setup' first"
1480+ end
1481+ ents
1482+ end
1483+
1484+ def targetfiles
1485+ mapdir(existfiles() - hookfiles())
1486+ end
1487+
1488+ def mapdir(ents)
1489+ ents.map {|ent|
1490+ if File.exist?(ent)
1491+ then ent # objdir
1492+ else "#{curr_srcdir()}/#{ent}" # srcdir
1493+ end
1494+ }
1495+ end
1496+
1497+ # picked up many entries from cvs-1.11.1/src/ignore.c
1498+ JUNK_FILES = %w(
1499+ core RCSLOG tags TAGS .make.state
1500+ .nse_depinfo #* .#* cvslog.* ,* .del-* *.olb
1501+ *~ *.old *.bak *.BAK *.orig *.rej _$* *$
1502+
1503+ *.org *.in .*
1504+ )
1505+
1506+ def existfiles
1507+ glob_reject(JUNK_FILES, (files_of(curr_srcdir()) | files_of('.')))
1508+ end
1509+
1510+ def hookfiles
1511+ %w( pre-%s post-%s pre-%s.rb post-%s.rb ).map {|fmt|
1512+ %w( config setup install clean ).map {|t| sprintf(fmt, t) }
1513+ }.flatten
1514+ end
1515+
1516+ def glob_select(pat, ents)
1517+ re = globs2re([pat])
1518+ ents.select {|ent| re =~ ent }
1519+ end
1520+
1521+ def glob_reject(pats, ents)
1522+ re = globs2re(pats)
1523+ ents.reject {|ent| re =~ ent }
1524+ end
1525+
1526+ GLOB2REGEX = {
1527+ '.' => '\.',
1528+ '$' => '\$',
1529+ '#' => '\#',
1530+ '*' => '.*'
1531+ }
1532+
1533+ def globs2re(pats)
1534+ /\A(?:#{
1535+ pats.map {|pat| pat.gsub(/[\.\$\#\*]/) {|ch| GLOB2REGEX[ch] } }.join('|')
1536+ })\z/
1537+ end
1538+
1539+ #
1540+ # TASK test
1541+ #
1542+
1543+ TESTDIR = 'test'
1544+
1545+ def exec_test
1546+ unless File.directory?('test')
1547+ $stderr.puts 'no test in this package' if verbose?
1548+ return
1549+ end
1550+ $stderr.puts 'Running tests...' if verbose?
1551+ begin
1552+ require 'test/unit'
1553+ rescue LoadError
1554+ setup_rb_error 'test/unit cannot loaded. You need Ruby 1.8 or later to invoke this task.'
1555+ end
1556+ runner = Test::Unit::AutoRunner.new(true)
1557+ runner.to_run << TESTDIR
1558+ runner.run
1559+ end
1560+
1561+ #
1562+ # TASK clean
1563+ #
1564+
1565+ def exec_clean
1566+ exec_task_traverse 'clean'
1567+ rm_f @config.savefile
1568+ rm_f 'InstalledFiles'
1569+ end
1570+
1571+ alias clean_dir_bin noop
1572+ alias clean_dir_lib noop
1573+ alias clean_dir_data noop
1574+ alias clean_dir_conf noop
1575+ alias clean_dir_man noop
1576+
1577+ def clean_dir_ext(rel)
1578+ return unless extdir?(curr_srcdir())
1579+ make 'clean' if File.file?('Makefile')
1580+ end
1581+
1582+ #
1583+ # TASK distclean
1584+ #
1585+
1586+ def exec_distclean
1587+ exec_task_traverse 'distclean'
1588+ rm_f @config.savefile
1589+ rm_f 'InstalledFiles'
1590+ end
1591+
1592+ alias distclean_dir_bin noop
1593+ alias distclean_dir_lib noop
1594+
1595+ def distclean_dir_ext(rel)
1596+ return unless extdir?(curr_srcdir())
1597+ make 'distclean' if File.file?('Makefile')
1598+ end
1599+
1600+ alias distclean_dir_data noop
1601+ alias distclean_dir_conf noop
1602+ alias distclean_dir_man noop
1603+
1604+ #
1605+ # Traversing
1606+ #
1607+
1608+ def exec_task_traverse(task)
1609+ run_hook "pre-#{task}"
1610+ FILETYPES.each do |type|
1611+ if type == 'ext' and config('without-ext') == 'yes'
1612+ $stderr.puts 'skipping ext/* by user option' if verbose?
1613+ next
1614+ end
1615+ traverse task, type, "#{task}_dir_#{type}"
1616+ end
1617+ run_hook "post-#{task}"
1618+ end
1619+
1620+ def traverse(task, rel, mid)
1621+ dive_into(rel) {
1622+ run_hook "pre-#{task}"
1623+ __send__ mid, rel.sub(%r[\A.*?(?:/|\z)], '')
1624+ directories_of(curr_srcdir()).each do |d|
1625+ traverse task, "#{rel}/#{d}", mid
1626+ end
1627+ run_hook "post-#{task}"
1628+ }
1629+ end
1630+
1631+ def dive_into(rel)
1632+ return unless File.dir?("#{@srcdir}/#{rel}")
1633+
1634+ dir = File.basename(rel)
1635+ Dir.mkdir dir unless File.dir?(dir)
1636+ prevdir = Dir.pwd
1637+ Dir.chdir dir
1638+ $stderr.puts '---> ' + rel if verbose?
1639+ @currdir = rel
1640+ yield
1641+ Dir.chdir prevdir
1642+ $stderr.puts '<--- ' + rel if verbose?
1643+ @currdir = File.dirname(rel)
1644+ end
1645+
1646+ def run_hook(id)
1647+ path = [ "#{curr_srcdir()}/#{id}",
1648+ "#{curr_srcdir()}/#{id}.rb" ].detect {|cand| File.file?(cand) }
1649+ return unless path
1650+ begin
1651+ instance_eval File.read(path), path, 1
1652+ rescue
1653+ raise if $DEBUG
1654+ setup_rb_error "hook #{path} failed:\n" + $!.message
1655+ end
1656+ end
1657+
1658+end # class Installer
1659+
1660+
1661+class SetupError < StandardError; end
1662+
1663+def setup_rb_error(msg)
1664+ raise SetupError, msg
1665+end
1666+
1667+if $0 == __FILE__
1668+ begin
1669+ ToplevelInstaller.invoke
1670+ rescue SetupError
1671+ raise if $DEBUG
1672+ $stderr.puts $!.message
1673+ $stderr.puts "Try 'ruby #{$0} --help' for detailed usage."
1674+ exit 1
1675+ end
1676+end
1677
1678=== modified file 'debian/control'
1679--- debian/control 2010-04-06 20:23:48 +0000
1680+++ debian/control 2010-05-09 02:46:22 +0000
1681@@ -76,7 +76,8 @@
1682 bzr,
1683 python-distutils-extra (>= 2.18bzr1),
1684 python-pygame,
1685- winpdb
1686+ winpdb,
1687+ ruby
1688 Recommends: seahorse-plugins
1689 Suggests: python-quickly-widgets
1690 Description: quickly ubuntu application template

Subscribers

People subscribed via source and target branches