Class: Vcs
- Inherits:
-
Object
- Object
- Vcs
- Defined in:
- lib/vcs/add.rb,
lib/vcs/url.rb,
lib/vcs/back.rb,
lib/vcs/diff.rb,
lib/vcs/edit.rb,
lib/vcs/form.rb,
lib/vcs/junk.rb,
lib/vcs/mail.rb,
lib/vcs/news.rb,
lib/vcs/delete.rb,
lib/vcs/script.rb,
lib/vcs/message.rb,
lib/vcs/conflict.rb,
lib/vcs/diffstat.rb,
lib/vcs/changelog.rb,
lib/vcs/opt_parse.rb,
lib/vcs/environment.rb,
lib/vcs/common_commit.rb,
lib/vcs/last_changed_date.rb
Overview
- Author
-
Nicolas Pouillard <[email protected]>.
- Copyright
-
Copyright © 2004, 2005 LRDE. All rights reserved.
- License
-
GNU General Public License (GPL).
- Revision
-
$Id$
Defined Under Namespace
Classes: OptParse
Constant Summary collapse
- IForm =
',iform'.to_path
- Form =
',form'.to_path
- MAIL =
Sendmail::MAIL_FILE
- NEWS =
',news'.to_path
- Message =
',message'.to_path
- LogEntry =
',log'.to_path
- @@diffstat =
'diffstat'.to_cmd
Class Method Summary collapse
- .editor ⇒ Object
- .env(name, &block) ⇒ Object
- .full_email ⇒ Object
- .fullname ⇒ Object
- .method_missing(meth) ⇒ Object
- .pager ⇒ Object
Instance Method Summary collapse
- #add!(files = [], options = {}) ⇒ Object
-
#back!(files = [], options = {}) ⇒ Object
This command take a command as argument and search the last revision where this command success.
- #check_diffstat ⇒ Object
-
#check_env ⇒ Object
class << self.
- #check_gnu_diff ⇒ Object
- #commit_failed(ex = nil) ⇒ Object
- #commited? ⇒ Boolean
-
#concat_changelog!(*args) ⇒ Object
Same switches as mk_changelog_entry.
- #concat_changelog_failed ⇒ Object
- #delete!(files = [], options = {}) ⇒ Object
-
#diffstat!(*a) ⇒ Object
Use the diffstat command to display statitics on your patch.
- #diffw!(*args) ⇒ Object
- #edit!(files = [], options = {}) ⇒ Object
- #edit_conflicts!(files, options = {}) ⇒ Object
- #edit_form!(*args) ⇒ Object
-
#junk!(files = [], options = {}) ⇒ Object
This command removes all junk files (by default all files begining with ‘,’).
- #last_changed_date!(*args) ⇒ Object
-
#mail!(files = [], options = {}) ⇒ Object
Mail.
- #mail_conf_checker ⇒ Object
- #mail_failed ⇒ Object
-
#mk_changelog_entry!(*args) ⇒ Object
Same switches as mk_log_entry.
- #mk_form!(files = [], options = {}) ⇒ Object
- #mk_iform!(*args) ⇒ Object
-
#mk_log_entry!(*args) ⇒ Object
Same switches as status.
- #mk_message!(files = [], options = {}) ⇒ Object
-
#mk_message_entry!(*args) ⇒ Object
Same switches as mk_log_entry.
-
#news!(*args) ⇒ Object
Post the news.
- #news_conf_checker ⇒ Object
- #news_failed ⇒ Object
- #resolve_conflicts!(files, options = {}) ⇒ Object
- #script(files = [], options = {}) ⇒ Object
- #script!(files = [], options = {}) ⇒ Object
- #url!(*args) ⇒ Object
Class Method Details
.editor ⇒ Object
14 15 16 |
# File 'lib/vcs/environment.rb', line 14 def editor env('EDITOR').to_cmd end |
.env(name, &block) ⇒ Object
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# 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 |
.full_email ⇒ Object
22 23 24 |
# File 'lib/vcs/environment.rb', line 22 def full_email "#{fullname} <#{email}>" end |
.fullname ⇒ Object
10 11 12 |
# File 'lib/vcs/environment.rb', line 10 def fullname env('FULLNAME') { Etc.getpwnam(user).gecos } end |
.method_missing(meth) ⇒ Object
26 27 28 |
# File 'lib/vcs/environment.rb', line 26 def method_missing ( meth ) env meth.to_s.upcase end |
.pager ⇒ Object
18 19 20 |
# File 'lib/vcs/environment.rb', line 18 def pager env('PAGER').to_cmd end |
Instance Method Details
#add!(files = [], options = {}) ⇒ Object
10 11 12 13 14 15 16 17 18 19 |
# File 'lib/vcs/add.rb', line 10 def add! ( files=[], ={} ) if [:auto] .delete(:auto) list!(files, :unrecognize => true) do |path_list| add_!(path_list.stringify, ) unless path_list.empty? end else add_!(files, ) end end |
#back!(files = [], options = {}) ⇒ Object
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)’
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/vcs/back.rb', line 14 def back! ( files=[], ={} ) 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 = [: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 [: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 |
#check_diffstat ⇒ Object
19 20 21 22 23 |
# File 'lib/vcs/diffstat.rb', line 19 def check_diffstat unless `diffstat -V` =~ /diffstat version/ raise ArgumentError, 'diffstat: diffstat is required' end end |
#check_env ⇒ Object
class << self
52 53 54 |
# File 'lib/vcs/environment.rb', line 52 def check_env %w[ email fullname editor pager ].each { |m| Vcs.send(m) } end |
#check_gnu_diff ⇒ Object
12 13 14 15 16 |
# File 'lib/vcs/diff.rb', line 12 def check_gnu_diff unless `diff --version` =~ /GNU/ raise ArgumentError, 'diffw: Gnu diff is required' end end |
#commit_failed(ex = nil) ⇒ Object
99 100 101 102 103 |
# File 'lib/vcs/common_commit.rb', line 99 def commit_failed ( ex=nil ) logger.error "Aborting #{ex}" logger.info 'You can rerun the same command to resume the commit' raise 'Commit failed' end |
#commited? ⇒ Boolean
106 107 108 |
# File 'lib/vcs/common_commit.rb', line 106 def commited? Vcs.commited end |
#concat_changelog!(*args) ⇒ Object
Same switches as mk_changelog_entry
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/vcs/changelog.rb', line 82 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 |
#concat_changelog_failed ⇒ Object
100 101 102 103 104 105 |
# File 'lib/vcs/changelog.rb', line 100 def concat_changelog_failed if TMP_CL.exist? logger.info "Restoring `#{CL}' from `#{TMP_CL}' ..." TMP_CL.rename(CL) end end |
#delete!(files = [], options = {}) ⇒ Object
10 11 12 13 14 15 16 17 18 19 |
# File 'lib/vcs/delete.rb', line 10 def delete! ( files=[], ={} ) if [:auto] .delete(:auto) list!(files, :missing => true) do |path_list| delete_!(path_list.stringify, ) unless path_list.empty? end else delete_!(files, ) end end |
#diffstat!(*a) ⇒ Object
Use the diffstat command to display statitics on your patch.
13 14 15 16 |
# File 'lib/vcs/diffstat.rb', line 13 def diffstat! ( *a ) check_diffstat (diffw(*a) | @@diffstat).run(@runner) end |
#diffw!(*args) ⇒ Object
8 9 10 |
# File 'lib/vcs/diff.rb', line 8 def diffw! ( *args ) diff_!(*args) end |
#edit!(files = [], options = {}) ⇒ Object
10 11 12 13 |
# File 'lib/vcs/edit.rb', line 10 def edit! ( files=[], ={} ) cmd = Vcs.editor + files > [STDOUT, STDERR] cmd.run(@runner) end |
#edit_conflicts!(files, options = {}) ⇒ Object
15 16 17 |
# File 'lib/vcs/conflict.rb', line 15 def edit_conflicts! ( files, ={} ) edit! mk_conflicts_list end |
#edit_form!(*args) ⇒ Object
8 9 10 11 12 13 14 15 16 17 |
# File 'lib/vcs/form.rb', line 8 def edit_form! ( *args ) mk_form(*args) edit! Form if Form.read =~ /\A---/ if Form.read =~ /\A---/ raise Failure, "You must fill this file: `#{Form}' (and remove the first line)" else mk_iform(*args) return YAML.load(IForm.read)['commited'] end end |
#junk!(files = [], options = {}) ⇒ Object
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.
14 15 16 17 18 19 20 21 22 23 24 |
# File 'lib/vcs/junk.rb', line 14 def junk! ( files=[], ={} ) list!(files, .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 |
#last_changed_date!(*args) ⇒ Object
8 9 10 |
# File 'lib/vcs/last_changed_date.rb', line 8 def last_changed_date! ( *args ) puts info(*args).read[/^Last Changed Date:.*?\(([^)]*)\).*$/, 1] end |
#mail!(files = [], options = {}) ⇒ Object
Mail.
FIXME handle options properly. Delegate the option parsing to Sendmail.
21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/vcs/mail.rb', line 21 def mail! ( files=[], ={} ) # Backward compatiblity files, = [], files if files.is_a? Hash error_handling :mail_failed unless MAIL.exist? = @@default_options.merge() [:signed] = Vcs.user_conf.sign print_body(MAIL, @@mailer.(), files) end @@mailer.sendmail puts 'Mail: Sent.' end |
#mail_conf_checker ⇒ Object
43 44 45 46 47 48 49 50 51 52 |
# File 'lib/vcs/mail.rb', line 43 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 |
#mail_failed ⇒ Object
36 37 38 39 40 41 |
# File 'lib/vcs/mail.rb', line 36 def mail_failed if defined? @@mail and @@mail.exist? logger.info { "#{MAIL}: Contains the generated mail" } logger.info { " AND information to send it (smtpserver, port...)" } end end |
#mk_changelog_entry!(*args) ⇒ Object
Same switches as mk_log_entry
62 63 64 65 66 |
# File 'lib/vcs/changelog.rb', line 62 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 |
#mk_form!(files = [], options = {}) ⇒ Object
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/vcs/form.rb', line 49 def mk_form! ( files=[], ={} ) with_cache! Form, 'complete form (title, subject, ChangeLog entry, diff)' do puts " |--- | ########## Fill this file correctly and remove this line ########## | --- |title: |subject: #{@@subject_format} | |--- | ###################### Your ChangeLog entry ############### 80c| # | --- |<%= title %> | |".head_cut! mk_log_entry!(files) puts "| |--- | ########### This line, and those below, will be ignored #### 80c| # | --- |Instructions: |- The first line must be removed when this file is filled. |- After you must specify a title, for the news/mail subject. | The line containing <%= title %> will be 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. |- Tabulations and stars ('*') will be added in the ChangeLog before each line. |- The '80c|' on the fourth line is here to show you where will be the | limit. The '|' is the 79th char. | |".head_cut! diffw!(files) end end |
#mk_iform!(*args) ⇒ Object
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/vcs/form.rb', line 20 def mk_iform! ( *args ) with_cache! IForm, 'instanciated form (title, subject, ChangeLog entry, diff)' do cl = mk_form(*args).read ls = [] YAML.each_document("--- |\n" + cl) { |x| (ls.size == 2)? break : ls << x } title_subject, input = ls header = { 'title' => title_subject[/^title: (.*)$/, 1], 'subject' => title_subject[/^subject: (.*)$/, 1] } rev = revision.read.to_i + 1 header.merge!('revision' => rev, 'commited' => false) if header['title'].nil? or header['title'].blank? raise Failure, "No title found. Reopen `#{Form}' and add it" end header['title'] += '.' unless header['title'] =~ /[.?!]$/ b = getBinding(header.merge(:rev => rev)) input = ERB.new(input, nil, '<-%->', '$erbout_').result(b) LogEntry.open('w') { |f| f.print input } 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 |
#mk_log_entry!(*args) ⇒ Object
Same switches as status
40 41 42 43 44 45 46 |
# File 'lib/vcs/changelog.rb', line 40 def mk_log_entry! ( *args ) with_cache! LogEntry, 'Log entry' do mk_log_entry_contents(*args).each do |se| puts "- #{se.file}: #{se.comment}." end end end |
#mk_message!(files = [], options = {}) ⇒ Object
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/vcs/message.rb', line 21 def ( files=[], ={} ) with_cache! Message, 'generated message (ChangeLog, diffstat, diff)' do url! if defined? COLLABOA puts puts 'You can also view this changeset here:' puts next_rev = rev.output.read.to_i next_rev += 1 unless commited? puts "http://#{COLLABOA}/repository/changesets/#{next_rev}" end puts flush (files) puts flush diffstat!(files) puts flush diffw(files).each_line do |line| print line if line !~ /^=+$/ end end end |
#mk_message_entry!(*args) ⇒ Object
Same switches as mk_log_entry
71 72 73 74 75 76 |
# File 'lib/vcs/changelog.rb', line 71 def ( *args ) puts 'Index: ChangeLog' puts "from #{Vcs.full_email}" puts mk_log_entry(*args).each_line(&method(:log_to_changelog)) end |
#news!(*args) ⇒ Object
Post the news.
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/vcs/news.rb', line 61 def news! ( *args ) error_handling :news_failed print_body(NEWS, (*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 |
#news_conf_checker ⇒ Object
107 108 109 110 111 112 113 |
# 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 |
#news_failed ⇒ Object
100 101 102 103 104 105 |
# 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 |
#resolve_conflicts!(files, options = {}) ⇒ Object
19 20 21 22 23 24 25 |
# File 'lib/vcs/conflict.rb', line 19 def resolve_conflicts! ( files, ={} ) conflicts = mk_conflicts_list question = "Resolve these conflicts?: \n - #{conflicts.join("\n - ")}\n(y/n)" if @h.agree question, true return resolved(conflicts) end end |
#script(files = [], options = {}) ⇒ Object
10 11 12 |
# File 'lib/vcs/script.rb', line 10 def script ( files=[], ={} ) puts script!(files, ) end |
#script!(files = [], options = {}) ⇒ Object
14 15 16 17 18 19 20 21 22 23 |
# File 'lib/vcs/script.rb', line 14 def script! ( files=[], ={} ) 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 |
#url!(*args) ⇒ Object
8 9 10 |
# File 'lib/vcs/url.rb', line 8 def url! ( *args ) puts info(*args).read[/^URL:\s+(.*)$/, 1] end |