| Author: | Nicolas Pouillard <ertai@lrde.epita.fr>. |
| Copyright: | Copyright © 2006 LRDE. All rights reserved. |
| License: | GNU General Public License (GPL). |
| Revision: | $Id$ |
| Message | = | ',message'.to_path unless defined? Message |
| = | Sendmail::MAIL_FILE unless defined? MAIL | |
| IForm | = | ',iform'.to_path unless defined? Vcs::IForm |
| Form | = | ',form'.to_path unless defined? Vcs::Form |
| NEWS | = | ',news'.to_path unless defined? NEWS |
| CL | = | Pathname.new('ChangeLog') unless defined? CL |
| TMP_CL | = | Pathname.new(',,ChangeLog') unless defined? TMP_CL |
| LogEntry | = | ',log'.to_path unless defined? LogEntry |
| Version | = | ::Version.parse("dev-util/vcs-0.5_beta4") |
| cmd_data | [R] |
# File lib/vcs/vcs.rb, line 354 def self.add_basic_method ( meth ) class_eval "def \#{meth}! ( *args )\nrun!(\"\#{meth}\", *args)\nend\ndef \#{meth}_! ( *args )\nrun!(\"\#{meth}\", *args)\nend\n" end
# File lib/vcs/vcs.rb, line 665 def add_conf_checker ( meth=nil, &block ) @@checkers << ((block.nil?)? meth : block) end
# File lib/vcs/vcs.rb, line 369 def self.alias_command ( m1, m2 ) m2 = m2.to_s @@all_commands[m2] ||= Set.new @@all_commands[m2] << m1.to_s @@all_aliases << m1 class_eval "def \#{m1} ( *args )\n\#{m2}(*args)\nend\nunless method_defined? :\#{m1}\ndef \#{m1}_ ( *args )\n\#{m2}_(*args)\nend\nend\ndef \#{m1}! ( *args )\n\#{m2}!(*args)\nend\nunless method_defined? :\#{m1}!\ndef \#{m1}_! ( *args )\n\#{m2}_!(*args)\nend\nend\n" end
# File lib/vcs/vcs.rb, line 679 def classify ( file, status=nil ) if status and category = Vcs.symbol_category[status] return category unless category == :unrecognize end Vcs.user_defined_categories.each do |category| return category if Vcs.user_conf_match(category, file) end return :unrecognize end
# File lib/vcs/vcs.rb, line 689 def color? ( &auto_block ) case color = Vcs.user_conf.color when :never then return false when :auto, :xmas_tree return (auto_block.nil?)? false : auto_block[] when :always then return true else raise ArgumentError, "Bad value for `color' (#{color})" end end
Set the given method as default commit action, use commit_ for the old one This method can be called just once to avoid conflicts
# File lib/vcs/vcs.rb, line 728 def default_commit ( meth ) just_once do alias_command :commit, meth alias_command :ci, meth end end
# File lib/vcs/vcs.rb, line 406 def self.delegate_to_cmd_data ( *syms ) syms.flatten.each do |meth| define_method(meth) do |*a| raise if block_given? @cmd_data.out_io.send(meth, *a) end end end
# File lib/vcs/environment.rb, line 33 def env ( name, &block ) return @@vars[name] if @@vars.has_key? name @@vars[name] = if var = ENV[name] var elsif block.nil? logger.error "Need #{name} in the environement" @@env_status = false "!!! #{name} not set !!!" else default = block[] logger.warn "Need #{name} in the environement (default: #{default})" ENV[name] = default default end end
# File lib/vcs/environment.rb, line 10 def fullname env('FULLNAME') { Etc.getpwnam(user).gecos.gsub(/,+$/, '') } end
# File lib/vcs/vcs.rb, line 711 def merge_user_conf ( conf ) conf = YAML.load(conf.read) if conf.is_a? Pathname conf.each do |k, v| v = v.to_sym if v.is_a? String user_conf.send("#{k}=", (v.is_a? Array)? ((user_conf.send(k) || []) + v) : v) end end
# File lib/vcs/vcs.rb, line 318 def initialize ( aCmd ) @cmd = aCmd.to_cmd @runner = Commands::Runners::System.new @h = HighLine.new self.cmd_data_factory = VcsCmdDataFactory.new(:output => STDOUT, :error => STDERR) unless is_a? Cvs @runner.subscribe_hook(:failure) do |command, data| data = command if data.nil? # Backward compatiblity logger.error { 'command: ' + command.to_s.gsub('"', '') } logger.error { "exit: #{data.status.exitstatus}" } suppress(IOError) do o = data.output.read logger.error { o.gsub!(/^/, 'stdout: ') ; o } unless o.empty? end suppress(IOError) do o = data.error.read logger.error { o.gsub!(/^/, 'stderr: ') ; o } unless o.empty? end # logger.error { 'data: ' + data.to_yaml } if data.output == STDOUT exit((data.status)? data.status.exitstatus : 1) else raise 'command failed' end end end @runner.subscribe_hook(:display_command) do |cmd| logger.debug { "running: #{cmd.to_sh}" } end @runner.subscribe_hook(:before_exec) do STDOUT.flush STDERR.flush end end
Here we can handle version conflicts with vcs extensions
# File lib/vcs/vcs.rb, line 720 def protocol_version ( aVersion ) if aVersion != '0.1' raise ArgumentError, "Bad protocol version #{aVersion} but 0.1 is needed" end end
# File lib/vcs/vcs.rb, line 707 def regex_list @@regex_list ||= RegexList.new(user_conf.sorting) end
# File lib/vcs/vcs.rb, line 669 def user_conf_match ( sym, file ) if user_conf.nil? or (regexps = user_conf.send(sym)).nil? return false end regexps.each do |re| return true if re.match(file) or re.match(file.basename) end return false end
# File lib/vcs/add.rb, line 10 def add! ( files=[], options={} ) if options[:auto] options.delete(:auto) list!(files, :unrecognize => true) do |path_list| add_!(path_list.stringify, options) unless path_list.empty? end else add_!(files, options) end end
This command take a command as argument and search the last revision where this command success.
Example:
* this dummy example success only if the revision is equal to 0 modulo X * replace X by the success revision and Y by a greater revision
vcs-svn back -r Y vcs-svn script ‘exit(rev.read.to_i % X)’
# File lib/vcs/back.rb, line 14 def back! ( files=[], options={} ) sub_vcs = sub_vcs_with_name('checkout-4-vcs-back') dir = TempPath.new('checkout-dir-4-vcs-back') cmd = files.to_cmd cmd.dir = dir rev = options[:revision] || revision.read.chomp raise ArgumentError, "Just integers are supported for revisions" if rev !~ /^\d+$/ rev = rev.to_i target_url = url.read.chomp while not rev.zero? sub_vcs.checkout([target_url, dir], :quiet => true, :revision => rev) data = cmd.system data.display if options[:verbose] if data.status.success? logger.info { "Your command success on revision #{rev}"} break else logger.warn { "Your command fail on revision #{rev}" } end rev -= 1 end end
# File lib/vcs/vcs.rb, line 659 def call_conf_checkers @@checkers.each { |x| (x.is_a? Proc)? x[] : send(x) } end
# File lib/vcs/vcs.rb, line 655 def call_handlers @@handlers.each { |k, v| (v.arity.abs == 1)? v[k] : v[] } end
# File lib/vcs/diffstat.rb, line 19 def check_diffstat unless `diffstat -V` =~ /diffstat version/ raise ArgumentError, 'diffstat: diffstat is required' end end
# File lib/vcs/environment.rb, line 52 def check_env %w[ email fullname editor pager ].each { |m| Vcs.send(m) } end
# File lib/vcs/diff.rb, line 12 def check_gnu_diff unless `diff --version` =~ /GNU/ raise ArgumentError, 'diffw: Gnu diff is required' end end
# File lib/vcs/vcs.rb, line 399 def cmd_data_factory= ( aFactory ) @runner.command_data_factory = aFactory @cmd_data = aFactory.new_command_data end
# File lib/vcs/vcs.rb, line 584 def color ( aString, *someStyles ) if color? @h.color(aString, *someStyles) else aString end end
# File lib/vcs/status.rb, line 59 def color_status! ( *args ) status(*args) do |status_entry| status_entry.colorize! puts status_entry.line end end
# File lib/vcs/common_commit.rb, line 132 def commit_failed ( ex=nil ) Message.unlink if defined? Message and Message.exist? and not committed? logger.error { "Aborting #{ex}" } logger.info { 'You can rerun the same command to resume the commit' } raise 'Commit failed' end
# File lib/vcs/common_commit.rb, line 151 def committing? [:editing, :committing, :sending].include? Vcs.commit_state end
Same switches as mk_changelog_entry
# File lib/vcs/changelog.rb, line 98 def concat_changelog! ( *args ) error_handling :concat_changelog_failed unless TMP_CL.exist? logger.info "Backup your `#{CL}' to `#{TMP_CL}' ..." CL.rename(TMP_CL) end CL.open('w') do |file| logger.info "#{CL}: Writing your new entry ..." with(file).mk_changelog_entry!(*args) file.puts logger.info "#{CL}: Writing the others ..." file.print TMP_CL.read end end
# File lib/vcs/changelog.rb, line 116 def concat_changelog_failed if TMP_CL.exist? logger.info "Restoring `#{CL}' from `#{TMP_CL}' ..." TMP_CL.rename(CL) end end
# File lib/vcs/delete.rb, line 10 def delete! ( files=[], options={} ) if options[:auto] options.delete(:auto) list!(files, :missing => true) do |path_list| delete_!(path_list.stringify, options) unless path_list.empty? end else delete_!(files, options) end end
Use the diffstat command to display statitics on your patch.
# File lib/vcs/diffstat.rb, line 13 def diffstat! ( *a ) check_diffstat (diffw(*a) | @@diffstat).run(@runner) end
# File lib/vcs/diff.rb, line 19 def diffw_base ( files_orig=[], options={} ) files = [] status(files_orig, just_standard_options(options)) do |se| next if se.file_st.chr =~ /[?X\\,+D]/ next if se.file.to_s == 'ChangeLog' next if se.file.directory? files << se.file unless files.include? se.file end files end
# File lib/vcs/edit.rb, line 10 def edit! ( files=[], options={} ) cmd = Vcs.editor + files > [STDOUT, STDERR] cmd.run(@runner) end
# File lib/vcs/conflict.rb, line 18 def edit_conflicts! ( files=[], options={} ) edit! mk_conflicts_list(files, options) resolve_conflicts! files, options end
# File lib/vcs/form.rb, line 8 def edit_form! ( *args ) mk_form(*args) edit! Form mk_iform(*args) return YAML.load(IForm.read)['Revision'] || :committing end
# File lib/vcs/vcs.rb, line 651 def error_handling ( meth_or_path, &block ) @@handlers[meth_or_path] = (block.nil?)? method(meth_or_path) : block end
# File lib/vcs/vcs.rb, line 550 def help! ( files=[], options={} ) return help_!(files, options) unless files.empty? and options.empty? puts "usage: #{@cmd.command} <subcommand> [options] [args] |Type '#{@cmd.command} help <subcommand>' for help on a specific subcommand. | |Most subcommands take file and/or directory arguments, recursing |on the directories. If no arguments are supplied to such a |command, it recurses on the current directory (inclusive) by default. | |Available subcommands:".head_cut! cmds = [] public_methods.each do |meth| next if meth =~ /_!?$/ next unless meth =~ /^(.+)!$/ cmd = $1 next if cmd == 'run' next if @@all_aliases.include? cmd.to_sym cmds << cmd end cmds.sort! cmds.each do |cmd| if @@all_commands.has_key? cmd aliases = @@all_commands[cmd].sort.join(', ') puts " - #{cmd} (alias #{aliases})" else puts " - #{cmd}" end end end
This command removes all junk files (by default all files begining with `,’). Warning: this command removes some files that may contains some important information. For example during a commit the information that you type is stored in one of these `,files’. So be careful using this command. See the user configuration to customize what is considered a junk file.
# File lib/vcs/junk.rb, line 14 def junk! ( files=[], options={} ) list!(files, options.merge(:junk => true)) do |path_list| path_list.each { |path| logger.info { "Remove #{path}" } } if @h.agree('Are you sure? (y/n)', true) path_list.each do |path| logger.info { "Removing #{path}..." } path.rm_f end end end end
# File lib/vcs/vcs.rb, line 596 def just_standard_options ( options ) result = {} options.each do |k, v| result[k] = v if standard_option? k end result end
# File lib/vcs/last_changed_date.rb, line 8 def last_changed_date! ( *args ) puts info(*args).read[/^Last Changed Date:.*?\(([^)]*)\).*$/, 1] end
Mail.
FIXME handle options properly. Delegate the option parsing to Sendmail.
# File lib/vcs/mail.rb, line 24 def mail! ( files=[], options={} ) # Backward compatiblity files, options = [], files if files.is_a? Hash or files.is_a? OpenStruct options = @@default_options.merge(options) options[:signed] = Vcs.user_conf.sign options = @@mailer.parse_mail_options(options) if editing? Vcs.mail_options = options return end header = YAML.load(IForm.read) %w[ Log ChangeLog YamlLog Message Title ].each { |x| header.delete x } options.to = header['To'] from = header['From'] options.from = from[/<(.*)>/, 1] || from options.header.merge! header options.header.symbolize_keys! return if header['To'].nil? rev = header['Revision'] unless MAIL.exist? print_body(MAIL, options, files) end if sending? mail = MAIL.read.gsub(/<%= rev %>/, rev.to_s) MAIL.open('w') { |f| f.puts mail } @@mailer.sendmail puts 'Mail: Sent.' end end
# File lib/vcs/mail.rb, line 56 def mail_conf_checker if Vcs.user_conf.sign unless `gpg --version` =~ /^gpg \(GnuPG\)/ logger.error 'mail: gunpg is required' end unless File.exist?("#{ENV['HOME']}/.gnupg/secring.gpg") logger.error 'no private key: in your ~/.gnupg' end end end
# File lib/vcs/vcs.rb, line 496 def method_missing ( meth, *args ) meth = meth.to_s if meth =~ /^(.*)!$/ no_bang = $1 if respond_to? no_bang puts send(no_bang, *args) else run_missing!(no_bang, meth, *args) end else with_bang = meth + '!' return run_missing!(meth, meth, *args) unless respond_to? with_bang copy = sub_vcs_with_name(meth) copy.send(with_bang, *args) out = copy.cmd_data out.out_io.close out end end
Same switches as mk_log_entry
# File lib/vcs/changelog.rb, line 77 def mk_changelog_entry! ( *args ) puts Time.now.strftime("%Y-%m-%d #{Vcs.full_email}") puts mk_log_entry(*args).each_line(&method(:log_to_changelog)) end
# File lib/vcs/form.rb, line 61 def mk_form! ( files=[], options={} ) with_cache! Form, 'complete form (title, subject, ChangeLog entry, diff)' do puts " |--You must fill this file correctly to continue--#{' '*13}-*- vcs -*- |Title: \"\" |Subject: #{@@subject_format.dump} |From: \"#{Vcs.full_email}\" |To: [#{options[:to].join(', ')}] |".head_cut! options = just_standard_options options case Vcs.user_conf.log_mode.to_sym when :change_log puts " |ChangeLog: |".head_cut! mk_log_entry(files, options).each_line(&method(:log_to_changelog)) when :log puts " |Log: |2 |".head_cut! mk_log_entry(files, options).each_line { |line| puts " #{line}" } when :yaml_log puts " |YamlLog: |".head_cut! mk_yaml_log_entry!(files, options) end puts " |#{@@message_line} | |#{@@last_line} |".head_cut! if Vcs.user_conf.new_user puts "| |Instructions: |- Fill the changelog/log entry. |- The first line must be removed when this file is filled. |- After you must specify a title, for the news/mail subject. | The tag <%= Title %> will be automatically replaced by your title, | <%= Subject %> by the subject line, <%= Rev %> by the revision... |- Everywhere in the document you can get/compute some values with | these tags <%= aRubyExpression %> even some vcs specific call. | For example <%= status.read %> will include the 'svn status' output. |- The Title will be automatically added on the top of your ChangeLog | entry. The line with the date and your name will be added too. | |".head_cut! case Vcs.user_conf.log_mode.to_sym when :log puts "- Tabulations and stars ('*') will be added in the ChangeLog before each line." end end mk_message!(files, options) Message.unlink end end
# File lib/vcs/form.rb, line 17 def mk_iform! ( *args ) with_cache! IForm, 'instanciated form' do form = mk_form(*args).read # Remove the first info line if present form.gsub!(/\A--.*\n/, '') # Get the message between the `message line' and the `last line' message = form[/^#{@@message_line}$(.*)^#{@@last_line}$/m, 1] # Remove every thing after the `message line' form.gsub!(/^#{@@message_line}$.*\Z/m, '') # Handle ChangeLog entries to make it Yaml compliant form.gsub!(/^(ChangeLog:)$/, '\1 |2') form.gsub!(/^\t/, " \t") form.gsub!(/^ {8}/, " \t") header = YAML.load(form) input = header['Log'] || header['ChangeLog'] if header['Title'].nil? or header['Title'].blank? raise Failure, "No title found. Reopen `#{Form}' and add it" end header['Title'] += '.' unless header['Title'] =~ /[.?!]$/ rev = '<%= rev %>' # make the revision substitution afterward b = getBinding(header.merge(:rev => rev, :revision => rev)) input = ERB.new(input, nil, '<-%->', '$erbout_').result(b) LogEntry.open('w') { |f| f.print input } header['Message'] = message header.each_value do |v| next unless v.is_a? String v.replace(ERB.new(v, nil, '<-%->', '$erbout_').result(b)) end puts header.to_yaml end end
Same switches as status
# File lib/vcs/changelog.rb, line 40 def mk_log_entry! ( *args ) with_cache! LogEntry, 'Log entry' do puts '<%= Title %>' puts mk_log_entry_contents(*args).each do |se| puts "- #{se.file}: #{se.comment}." end end end
# File lib/vcs/message.rb, line 22 def mk_message! ( files=[], options={} ) with_cache! Message, 'generated message (ChangeLog, diffstat, diff)' do url! if msg = options['Message'] puts msg end options = just_standard_options options if defined? COLLABOA puts 'You can also view this changeset here:' puts puts "http://#{COLLABOA}/repository/changesets/<%= rev %>" end puts flush mk_message_entry!(files, options) puts flush diffstat!(files, options) puts flush diffw(files, options).each_line do |line| print line if line !~ /^=+$/ end end end
Same switches as mk_log_entry
# File lib/vcs/changelog.rb, line 86 def mk_message_entry! ( *args ) puts 'Index: ChangeLog' puts "from #{Vcs.full_email}" puts puts "\tDo not fill this draft entry!" if editing? mk_log_entry(*args).each_line(&method(:log_to_changelog)) end
Same switches as status
# File lib/vcs/changelog.rb, line 54 def mk_yaml_log_entry! ( *args ) raise NotImplentedError # with_cache! LogEntry, 'Log entry' do # mk_log_entry_contents(*args).each do |se| # puts " - #{se.file}: >2\n #{se.comment}." # end # end end
Post the news.
# File lib/vcs/news.rb, line 61 def news! ( *args ) error_handling :news_failed print_body(NEWS, parse_news_options(*args)) unless NEWS.exist? @news_status = 'Sent.' NEWS.open('r') do |file| opt = YAML::chop_header(file) server, port = opt[:server].split(/:/) port ||= 119 logger.info('news') { "Nntp Server: #{server}:#{port}" } unless @h.agree("Post a news, with this subject: #{opt[:subject]}\n" + " to #{opt[:groups].join(', ')}\n from #{opt[:from]}\n" + 'Are you sure? (y/n)', true) logger.error('news') { 'Aborting' } exit end require 'socket' TCPSocket.open(server, port) do |f| check_line(f, /^200/) f.puts 'post' check_line(f, /^340/) f.puts "Newsgroups: #{opt[:groups].join(', ')}" f.puts "From: #{opt[:from]}" f.puts "Subject: #{opt[:subject]}" f.puts file.each do |line| f.print line.gsub(/^\./, ' .') end f.puts '.' check_line(f, /^240/) f.puts 'quit' check_line(f, /^205/) end end NEWS.delete puts @news_status end
# File lib/vcs/news.rb, line 107 def news_conf_checker %w[ NNTPSERVER ].each do |var| if ENV[var].nil? or ENV[var].empty? logger.error "environment variable `#{var}' not set" end end end
# File lib/vcs/news.rb, line 100 def news_failed if defined? NEWS and NEWS.exist? logger.info "#{NEWS}: Contains the generated news" + "(generated from #{@@message})" end end
# File lib/vcs/edit.rb, line 15 def paginate! ( files=[], options={} ) cmd = Vcs.pager + files > [STDOUT, STDERR] cmd.run(@runner) end
# File lib/vcs/conflict.rb, line 23 def resolve_conflicts! ( files=[], options={} ) conflicts = mk_conflicts_list(files, options) question = "Resolve these conflicts?: \n - #{conflicts.join("\n - ")}\n(y/n)" if @h.agree question, true return resolved(conflicts) end end
# File lib/vcs/vcs.rb, line 421 def run! ( command, files=[], options={} ) flush pre_cmd_options, cmd_options = option_controller.to_strings(options) (@cmd + pre_cmd_options + command + cmd_options + '--' + files).run(@runner) end
# File lib/vcs/vcs.rb, line 471 def run_argv ( argv ) options, files = option_controller.parse(argv) if options[:help] meth = :help! options.delete(:help) elsif files.empty? if options[:version] meth = '--version' options.delete(:version) else options.delete(:help) meth = :help! end else meth = files.shift.dup meth.sub!(/([^!])$/, '\1!') if meth != 'script' end logger.debug { "meth: #{meth}, files: #{files.inspect}, options: #{options.inspect}" } send(meth, files, options) end
# File lib/vcs/script.rb, line 10 def script ( files=[], options={} ) puts script!(files, options) end
# File lib/vcs/script.rb, line 14 def script! ( files=[], options={} ) begin eval(files.join(' ')) rescue SystemExit => ex raise ex rescue Exception => ex logger.error { 'Vcs#script: during the client execution' } logger.error { ex.long_pp } end end
# File lib/vcs/status.rb, line 76 def spawn_status_entries ( status_data, &block ) result = PathList.new status_data.each_line do |line| next unless line =~ /^.{5} / status_entry = StatusEntry.new(@h, line) next if status_entry.category == :exclude result << status_entry end result.sort_with_regex_list! Vcs.regex_list result.each(&block) end
# File lib/vcs/status.rb, line 66 def status! ( *args ) if color? color_status!(*args) else status(*args) do |status_entry| puts status_entry.line end end end
# File lib/vcs/vcs.rb, line 427 def sub_vcs ( out, err, vcs_class=nil, &block ) copy = (vcs_class || self.class).new(@cmd) copy.cmd_data_factory = VcsCmdDataFactory.new(:output => out, :error => err) if block.nil? copy else copy.instance_eval(&block) end end
# File lib/vcs/vcs.rb, line 437 def sub_vcs_with_name ( name, vcs_class=nil, &block ) sub_vcs(TempPath.new("#{name}-out"), TempPath.new("#{name}-err"), vcs_class, &block) end
# File lib/vcs/vcs.rb, line 442 def with ( io, vcs_class=nil, &block ) io.flush if io.respond_to? :flush sub_vcs(io, io, vcs_class, &block) end
# File lib/vcs/common_commit.rb, line 10 def common_commit! ( subject_format, files=[], commit_opts={}, &block ) unless CL.exist? raise Failure, "No `#{CL}', you are probably not in a valid directory." end Vcs.commit_state = :editing force = commit_opts[:force] commit_opts.delete :force opts = just_standard_options commit_opts @@subject_format = subject_format logger.info { 'Updating your working copy...' } update! [], opts have_unrecognized_files = false status(files, opts) do |se| if se.category == :unrecognize have_unrecognized_files = true se.colorize! if color? puts se.line end end if have_unrecognized_files message = 'You have unrecognized files in your working copy!' if Vcs.user_conf.new_user message << " |This meant that these files won't be committed! |You have some solutions to comply with the rule: |- You must put these files in some categories. | For instance you can rename these files and put a `+' before | to make it `precious': | put `,' for `junk' | put `\\' for `unmask' | put `-' for `exclude' |- You can also edit your configuration file (.vcs) to customize | these categories. For example add this: | ------------ .vcs ------------ | precious: | - !re my_precious_file[0-9]* | - !re .*\.patch | ------------ .vcs ------------ |- You can also perform a partial commit and specify which files | and directories commit. For example this command: | #{@cmd.command} commit foo.c bar/ | |".head_cut! end if force logger.warn { message } else logger.error { message } commit_failed end end block['empty subject'] if block_given? Vcs.commit_state = edit_form!(files, opts.merge(:to => Vcs.mail_options.to)) iform = YAML.load(IForm.read) Message.unlink if Message.exist? and not committed? mk_message(files, opts.merge(iform)) block[iform['Subject']] if block_given? paginate! Message unless committed? if Vcs.interactive? question = 'Committing, are you sure?' begin response = @h.agree "#{question} (y/n)", true rescue NoMethodError response = @h.agree "#{question} (yes/no)" end unless response commit_failed end end concat_changelog!(files, opts) files << 'ChangeLog' unless files.empty? begin commit_!(files, commit_opts.merge(:message => mk_log_entry(files).read)) update! revision = rev.read.to_i iform = YAML.load(IForm.read).merge('Revision' => revision) IForm.open('w') { |f| f.print iform.to_yaml } Vcs.commit_state = revision TMP_CL.delete if TMP_CL.exist? rescue Exception => ex commit_failed ex end end Vcs.commit_state = :sending block[iform['Subject']] if block_given? logger.info { 'Deleting junk files...' } TMP_CL.delete if TMP_CL.exist? # Backward typo compatibility '+commited'.to_path.mv('+committed') if '+commited'.to_path.exist? destdir = '+committed'.to_path/iform['Revision'].to_s destdir.mkpath unless destdir.directory? moved = PathList.new [LogEntry, Form, IForm, Message].each do |path| next unless path.exist? dest = destdir/path moved << path path.rename(dest) end logger.info { "Moving `#{moved.join('\', `')}' to `#{destdir}'..." } end
# File lib/vcs/form.rb, line 125 def getBinding ( header ) code = ['module GetBinding'] header.each do |k, v| code << "#{k.to_s.capitalize} = #{v.inspect}" code << "#{k.to_s.downcase} = #{v.inspect}" end code << 'binding' << 'end' eval(code.join('; ')) end
# File lib/vcs/conflict.rb, line 8 def mk_conflicts_list ( files=[], options={} ) conflicts = [] status(files, options) do |se| conflicts << se.file if se.category == :conflict end raise "no conflicts" if conflicts.empty? conflicts end
# File lib/vcs/news.rb, line 14 def parse_news_options ( *args ) require 'optparse' result = { :from => Vcs.full_email, :groups => [], :server => Vcs.nntpserver, } if !args.nil? and !args.empty? and args[0].is_a?(Hash) return result.merge!(args[0]) end OptionParser.new do |opts| opts.separator '' opts.on('-g', '--group NAME', 'Choose a news group') do |aString| result[:groups] << aString end opts.on('-s', '--server NAME', 'Choose a news server') do |aString| result[:server] = aString end opts.on('-S', '--subject NAME', 'Choose your news subject') do |aString| result[:subject] = aString.sub(/\.?$/, '.') end opts.on_tail('-h', '--help', 'Show this message') do puts opts exit end end.parse!(args) raise Failure, 'No news group' if result[:groups].empty? raise Failure, 'No news server' if result[:server].nil? raise Failure, 'No news subject' if result[:subject].nil? result end
# File lib/vcs/vcs.rb, line 459 def run_missing! ( name, orig, *args ) if name =~ /^(.*)_$/ run!($1, *args) elsif name =~ /^--/ run!(name, *args) else logger.warn { "Unknown command: '#{orig.gsub('!', '')}'" } run!(name, *args) end end
# File lib/vcs/vcs.rb, line 518 def with_cache ( path=nil, description=nil, &block ) loc = block.source_location # FIXME verify that this type of cache is working return @@cache[loc].dup if @@cache.has_key? loc unless path.nil? if description.nil? raise ArgumentError, "need a description for #{path}" end error_handling(path) do logger.info "#{path}: Contains your #{description}" if path.exist? end end if path.exist? logger.info "#{path} already exists" return path.read end begin logger.info "Creating a new `#{path}' file..." path.open('w') { |f| result = with(f, &block) } rescue Exception => ex logger.error "Removing `#{path}'..." path.unlink raise ex end path.read end