comma 0.4.1 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -1,4 +1,10 @@
1
1
  source :rubygems
2
2
 
3
- # Include dependencies from gemspec.
4
- gemspec
3
+ gem "activesupport", ">= 2.2.2"
4
+ gem "rspec", "~> 2.3.0"
5
+ gem "fastercsv"
6
+
7
+ group :development do
8
+ gem "jeweler", "~> 1.6"
9
+ gem "activerecord", ">= 2.2.2"
10
+ end
@@ -1,29 +1,32 @@
1
- PATH
2
- remote: .
3
- specs:
4
- comma (0.4.0)
5
- activesupport (>= 2.2.2)
6
-
7
1
  GEM
8
2
  remote: http://rubygems.org/
9
3
  specs:
10
- activesupport (3.0.1)
4
+ activerecord (2.3.10)
5
+ activesupport (= 2.3.10)
6
+ activesupport (2.3.10)
11
7
  diff-lcs (1.1.2)
12
- rspec (2.0.1)
13
- rspec-core (~> 2.0.1)
14
- rspec-expectations (~> 2.0.1)
15
- rspec-mocks (~> 2.0.1)
16
- rspec-core (2.0.1)
17
- rspec-expectations (2.0.1)
18
- diff-lcs (>= 1.1.2)
19
- rspec-mocks (2.0.1)
20
- rspec-core (~> 2.0.1)
21
- rspec-expectations (~> 2.0.1)
8
+ fastercsv (1.5.4)
9
+ git (1.2.5)
10
+ jeweler (1.6.0)
11
+ bundler (~> 1.0.0)
12
+ git (>= 1.2.5)
13
+ rake
14
+ rake (0.8.7)
15
+ rspec (2.3.0)
16
+ rspec-core (~> 2.3.0)
17
+ rspec-expectations (~> 2.3.0)
18
+ rspec-mocks (~> 2.3.0)
19
+ rspec-core (2.3.1)
20
+ rspec-expectations (2.3.0)
21
+ diff-lcs (~> 1.1.2)
22
+ rspec-mocks (2.3.0)
22
23
 
23
24
  PLATFORMS
24
25
  ruby
25
26
 
26
27
  DEPENDENCIES
28
+ activerecord (>= 2.2.2)
27
29
  activesupport (>= 2.2.2)
28
- comma!
29
- rspec (>= 1.2.9)
30
+ fastercsv
31
+ jeweler (~> 1.6)
32
+ rspec (~> 2.3.0)
@@ -125,6 +125,10 @@ You can pass the :filename option and have Comma writes the CSV output to this f
125
125
 
126
126
  Book.limited(10).to_comma(:filename => 'books.csv')
127
127
 
128
+ You also can pass the :write_header option to hide the header line (true is default):
129
+
130
+ Book.limited(10).to_comma(:write_headers => false)
131
+
128
132
  == Using blocks
129
133
 
130
134
  For more complex relationships you can pass blocks for calculated values, or related values. Following the previous example here is a comma set using blocks (both with and without labels for your CSV headings):
@@ -183,6 +187,17 @@ When used with Rails (ie. add 'comma' as a gem dependency), Comma automatically
183
187
 
184
188
  end
185
189
 
190
+ You can specify which output format you would like to use by specifying a style parameter:
191
+ class BooksController < ApplicationController
192
+
193
+ def index
194
+ respond_to do |format|
195
+ format.csv { render :csv => Book.limited(50), :style => :brief }
196
+ end
197
+ end
198
+
199
+ end
200
+
186
201
  When used with Rails 2.3.*, Comma also adds support for exporting named scopes:
187
202
 
188
203
  class Book < ActiveRecord::Base
data/Rakefile CHANGED
@@ -1,39 +1,37 @@
1
1
  require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
2
10
  require 'rake'
3
11
 
4
- begin
5
- require 'jeweler'
6
- Jeweler::Tasks.new do |gem|
7
- gem.name = "comma"
8
- gem.summary = "Ruby Comma Seperated Values generation library"
9
- gem.description = "Ruby Comma Seperated Values generation library"
10
- gem.email = "crafterm@redartisan.com"
11
- gem.rubyforge_project = 'comma'
12
- gem.homepage = "http://github.com/crafterm/comma"
13
- gem.authors = ["Marcus Crafter"]
14
- gem.add_development_dependency "rspec", ">= 1.2.9"
15
- gem.add_dependency("activesupport", ">= 2.2.2")
16
- # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
17
- end
18
- Jeweler::GemcutterTasks.new
19
- rescue LoadError
20
- puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
12
+ require 'jeweler'
13
+ Jeweler::Tasks.new do |gem|
14
+ gem.name = "comma"
15
+ gem.summary = "Ruby Comma Seperated Values generation library"
16
+ gem.description = "Ruby Comma Seperated Values generation library"
17
+ gem.email = "crafterm@redartisan.com"
18
+ gem.rubyforge_project = 'comma'
19
+ gem.homepage = "http://github.com/crafterm/comma"
20
+ gem.authors = ["Marcus Crafter"]
21
21
  end
22
+ Jeweler::RubygemsDotOrgTasks.new
22
23
 
23
- require 'spec/rake/spectask'
24
- Spec::Rake::SpecTask.new(:spec) do |spec|
25
- spec.libs << 'lib' << 'spec'
26
- spec.spec_files = FileList['spec/**/*_spec.rb']
24
+ require 'rspec/core'
25
+ require 'rspec/core/rake_task'
26
+ RSpec::Core::RakeTask.new(:spec) do |spec|
27
+ spec.pattern = FileList['spec/**/*_spec.rb']
27
28
  end
28
29
 
29
- Spec::Rake::SpecTask.new(:rcov) do |spec|
30
- spec.libs << 'lib' << 'spec'
30
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
31
31
  spec.pattern = 'spec/**/*_spec.rb'
32
32
  spec.rcov = true
33
33
  end
34
34
 
35
- task :spec => :check_dependencies
36
-
37
35
  task :default => :spec
38
36
 
39
37
  require 'rake/rdoctask'
@@ -41,7 +39,7 @@ Rake::RDocTask.new do |rdoc|
41
39
  version = File.exist?('VERSION') ? File.read('VERSION') : ""
42
40
 
43
41
  rdoc.rdoc_dir = 'rdoc'
44
- rdoc.title = "comma #{version}"
42
+ rdoc.title = "awesome #{version}"
45
43
  rdoc.rdoc_files.include('README*')
46
44
  rdoc.rdoc_files.include('lib/**/*.rb')
47
45
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.1
1
+ 0.4.2
@@ -1,72 +1,71 @@
1
1
  # Generated by jeweler
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{comma}
8
- s.version = "0.4.1"
8
+ s.version = "0.4.2"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Marcus Crafter"]
12
- s.date = %q{2010-10-19}
12
+ s.date = %q{2011-10-14}
13
13
  s.description = %q{Ruby Comma Seperated Values generation library}
14
14
  s.email = %q{crafterm@redartisan.com}
15
15
  s.extra_rdoc_files = [
16
16
  "README.rdoc"
17
17
  ]
18
18
  s.files = [
19
- ".gitignore",
20
- "Gemfile",
21
- "Gemfile.lock",
22
- "MIT-LICENSE",
23
- "README.rdoc",
24
- "Rakefile",
25
- "VERSION",
26
- "comma.gemspec",
27
- "init.rb",
28
- "lib/comma.rb",
29
- "lib/comma/array.rb",
30
- "lib/comma/association_proxy.rb",
31
- "lib/comma/extractors.rb",
32
- "lib/comma/generator.rb",
33
- "lib/comma/named_scope.rb",
34
- "lib/comma/object.rb",
35
- "lib/comma/render_as_csv.rb",
36
- "spec/comma/ar_spec.rb",
37
- "spec/comma/comma_spec.rb",
38
- "spec/comma/extractors_spec.rb",
39
- "spec/spec.opts",
40
- "spec/spec_helper.rb",
41
- "sudo"
19
+ "Gemfile",
20
+ "Gemfile.lock",
21
+ "MIT-LICENSE",
22
+ "README.rdoc",
23
+ "Rakefile",
24
+ "VERSION",
25
+ "comma.gemspec",
26
+ "init.rb",
27
+ "lib/comma.rb",
28
+ "lib/comma/array.rb",
29
+ "lib/comma/association_proxy.rb",
30
+ "lib/comma/extractors.rb",
31
+ "lib/comma/generator.rb",
32
+ "lib/comma/named_scope.rb",
33
+ "lib/comma/object.rb",
34
+ "lib/comma/render_as_csv.rb",
35
+ "spec/comma/ar_spec.rb",
36
+ "spec/comma/comma_spec.rb",
37
+ "spec/comma/extractors_spec.rb",
38
+ "spec/spec.opts",
39
+ "spec/spec_helper.rb"
42
40
  ]
43
41
  s.homepage = %q{http://github.com/crafterm/comma}
44
- s.rdoc_options = ["--charset=UTF-8"]
45
42
  s.require_paths = ["lib"]
46
43
  s.rubyforge_project = %q{comma}
47
- s.rubygems_version = %q{1.3.6}
44
+ s.rubygems_version = %q{1.4.2}
48
45
  s.summary = %q{Ruby Comma Seperated Values generation library}
49
- s.test_files = [
50
- "spec/comma/ar_spec.rb",
51
- "spec/comma/comma_spec.rb",
52
- "spec/comma/extractors_spec.rb",
53
- "spec/spec_helper.rb"
54
- ]
55
46
 
56
47
  if s.respond_to? :specification_version then
57
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
58
48
  s.specification_version = 3
59
49
 
60
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
61
- s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
50
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
62
51
  s.add_runtime_dependency(%q<activesupport>, [">= 2.2.2"])
52
+ s.add_runtime_dependency(%q<rspec>, ["~> 2.3.0"])
53
+ s.add_runtime_dependency(%q<fastercsv>, [">= 0"])
54
+ s.add_development_dependency(%q<jeweler>, ["~> 1.6"])
55
+ s.add_development_dependency(%q<activerecord>, [">= 2.2.2"])
63
56
  else
64
- s.add_dependency(%q<rspec>, [">= 1.2.9"])
65
57
  s.add_dependency(%q<activesupport>, [">= 2.2.2"])
58
+ s.add_dependency(%q<rspec>, ["~> 2.3.0"])
59
+ s.add_dependency(%q<fastercsv>, [">= 0"])
60
+ s.add_dependency(%q<jeweler>, ["~> 1.6"])
61
+ s.add_dependency(%q<activerecord>, [">= 2.2.2"])
66
62
  end
67
63
  else
68
- s.add_dependency(%q<rspec>, [">= 1.2.9"])
69
64
  s.add_dependency(%q<activesupport>, [">= 2.2.2"])
65
+ s.add_dependency(%q<rspec>, ["~> 2.3.0"])
66
+ s.add_dependency(%q<fastercsv>, [">= 0"])
67
+ s.add_dependency(%q<jeweler>, ["~> 1.6"])
68
+ s.add_dependency(%q<activerecord>, [">= 2.2.2"])
70
69
  end
71
70
  end
72
71
 
@@ -35,6 +35,6 @@ if defined?(ActiveRecord)
35
35
  require 'comma/association_proxy'
36
36
  end
37
37
 
38
- if defined?(ActionController)
38
+ if defined?(RenderAsCSV) && defined?(ActionController)
39
39
  ActionController::Base.send :include, RenderAsCSV
40
40
  end
@@ -8,9 +8,9 @@ module Comma
8
8
  @options = {}
9
9
 
10
10
  if @style.is_a? Hash
11
- @options = @style.clone
12
- @style = @options.delete(:style) || :default
13
- @filename = @options.delete(:filename)
11
+ @options = @style.clone
12
+ @style = @options.delete(:style) || :default
13
+ @filename = @options.delete(:filename)
14
14
  end
15
15
  end
16
16
 
@@ -25,7 +25,10 @@ module Comma
25
25
  private
26
26
  def append_csv(csv, iterator_method)
27
27
  return '' if @instance.empty?
28
- csv << @instance.first.to_comma_headers(@style) # REVISIT: request to optionally include headers
28
+ unless @options.has_key?(:write_headers) && !@options[:write_headers]
29
+ csv << @instance.first.to_comma_headers(@style)
30
+ end
31
+
29
32
  @instance.send(iterator_method) do |object|
30
33
  csv << object.to_comma(@style)
31
34
  end
@@ -1,42 +1,57 @@
1
- module RenderAsCSV
2
- def self.included(base)
3
- base.alias_method_chain :render, :csv
1
+ if defined?(ActionController::Renderers) && ActionController::Renderers.respond_to?(:add)
2
+ ActionController::Renderers.add :csv do |obj, options|
3
+ filename = options[:filename] || 'data'
4
+ send_data obj.to_comma, :type => Mime::CSV, :disposition => "attachment; filename=#{filename}.csv"
4
5
  end
5
-
6
- def render_with_csv(options = nil, extra_options = {}, &block)
7
- return render_without_csv(options, extra_options, &block) unless options.is_a?(Hash) and options[:csv].present?
8
-
9
- content = options.delete(:csv)
10
- style = options.delete(:style) || :default
11
- filename = options.delete(:filename)
12
-
13
- headers.merge!(
14
- 'Content-Transfer-Encoding' => 'binary',
15
- 'Content-Type' => 'text/csv; charset=utf-8'
16
- )
17
- filename_header_value = "attachment"
18
- filename_header_value += "; filename=\"#{filename}\"" if filename.present?
19
- headers.merge!('Content-Disposition' => filename_header_value)
20
-
21
- @performed_render = false
22
-
23
- render_stream :status => 200,
24
- :content => Array(content),
25
- :style => style
26
- end
27
-
28
- protected
29
-
30
- def render_stream(options)
31
- status = options[:status]
32
- content = options[:content]
33
- style = options[:style]
34
-
35
- render :status => status, :text => Proc.new { |response, output|
36
- output.write FasterCSV.generate_line(content.first.to_comma_headers(style))
37
- content.each { |line| output.write FasterCSV.generate_line(line.to_comma(style)) }
38
- }
6
+ else
7
+ module RenderAsCSV
8
+ def self.included(base)
9
+ base.alias_method_chain :render, :csv
10
+ end
11
+
12
+ def render_with_csv(options = nil, extra_options = {}, &block)
13
+ return render_without_csv(options, extra_options, &block) unless options.is_a?(Hash) and options[:csv].present?
14
+
15
+ content = options.delete(:csv)
16
+ style = options.delete(:style) || :default
17
+ filename = options.delete(:filename)
18
+
19
+ headers.merge!(
20
+ 'Content-Transfer-Encoding' => 'binary',
21
+ 'Content-Type' => 'text/csv; charset=utf-8'
22
+ )
23
+ filename_header_value = "attachment"
24
+ filename_header_value += "; filename=\"#{filename}\"" if filename.present?
25
+ headers.merge!('Content-Disposition' => filename_header_value)
26
+
27
+ @performed_render = false
28
+
29
+ render_stream :status => 200,
30
+ :content => Array(content),
31
+ :style => style
32
+ end
33
+
34
+ protected
35
+
36
+ def render_stream(options)
37
+ status = options[:status]
38
+ content = options[:content]
39
+ style = options[:style]
40
+
41
+ # If Rails 2.x
42
+ if defined? Rails and (Rails.version.split('.').map(&:to_i) <=> [2,3,5]) < 0
43
+ render :status => status, :text => Proc.new { |response, output|
44
+ output.write FasterCSV.generate_line(content.first.to_comma_headers(style))
45
+ content.each { |line| output.write FasterCSV.generate_line(line.to_comma(style)) }
46
+ }
47
+ else # If Rails 3.x
48
+ self.status = status
49
+ self.response_body = proc { |response, output|
50
+ output.write FasterCSV.generate_line(content.first.to_comma_headers(style))
51
+ content.each { |line| output.write FasterCSV.generate_line(line.to_comma(style)) }
52
+ }
53
+ end
54
+ end
39
55
  end
56
+ #credit : http://ramblingsonrails.com/download-a-large-amount-of-data-in-csv-from-rails
40
57
  end
41
-
42
- #credit : http://ramblingsonrails.com/download-a-large-amount-of-data-in-csv-from-rails
@@ -201,6 +201,16 @@ describe Comma, 'to_comma data/headers object extensions' do
201
201
  header, foo = Array(@foo).to_comma.split("\n")
202
202
  header.should == ['Content', 'Truncated Content', 'Created at', 'Updated at', 'Created Custom Label', 'Updated at Custom Label'].join(',')
203
203
  end
204
+
205
+ it 'should put headers in place when forced' do
206
+ header, foo = Array(@foo).to_comma(:write_headers => true).split("\n")
207
+ header.should == ['Content', 'Truncated Content', 'Created at', 'Updated at', 'Created Custom Label', 'Updated at Custom Label'].join(',')
208
+ end
209
+
210
+ it 'should not write headers if specified' do
211
+ header, foo = Array(@foo).to_comma(:write_headers => false).split("\n")
212
+ header.should == [@content, @content[0..10], @time.to_s(:db), @time.to_s(:db), @time.to_s(:short), @time.to_s(:short)].join(',')
213
+ end
204
214
 
205
215
  end
206
216
 
@@ -1,6 +1,6 @@
1
1
  require 'rubygems'
2
- require 'spec'
3
- require 'activerecord'
2
+ require 'rspec'
3
+ require 'active_record'
4
4
  ActiveRecord::ActiveRecordError # http://tinyurl.com/24f84gf
5
5
 
6
6
  $:.unshift(File.dirname(__FILE__) + '/../lib')
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: comma
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: false
4
+ hash: 11
5
+ prerelease:
5
6
  segments:
6
7
  - 0
7
8
  - 4
8
- - 1
9
- version: 0.4.1
9
+ - 2
10
+ version: 0.4.2
10
11
  platform: ruby
11
12
  authors:
12
13
  - Marcus Crafter
@@ -14,37 +15,86 @@ autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2010-10-19 00:00:00 +11:00
18
+ date: 2011-10-14 00:00:00 +11:00
18
19
  default_executable:
19
20
  dependencies:
20
21
  - !ruby/object:Gem::Dependency
21
- name: rspec
22
- prerelease: false
22
+ name: activesupport
23
23
  requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
24
25
  requirements:
25
26
  - - ">="
26
27
  - !ruby/object:Gem::Version
28
+ hash: 3
27
29
  segments:
28
- - 1
29
30
  - 2
30
- - 9
31
- version: 1.2.9
32
- type: :development
31
+ - 2
32
+ - 2
33
+ version: 2.2.2
34
+ type: :runtime
33
35
  version_requirements: *id001
34
- - !ruby/object:Gem::Dependency
35
- name: activesupport
36
36
  prerelease: false
37
+ - !ruby/object:Gem::Dependency
38
+ name: rspec
37
39
  requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ~>
43
+ - !ruby/object:Gem::Version
44
+ hash: 3
45
+ segments:
46
+ - 2
47
+ - 3
48
+ - 0
49
+ version: 2.3.0
50
+ type: :runtime
51
+ version_requirements: *id002
52
+ prerelease: false
53
+ - !ruby/object:Gem::Dependency
54
+ name: fastercsv
55
+ requirement: &id003 !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ hash: 3
61
+ segments:
62
+ - 0
63
+ version: "0"
64
+ type: :runtime
65
+ version_requirements: *id003
66
+ prerelease: false
67
+ - !ruby/object:Gem::Dependency
68
+ name: jeweler
69
+ requirement: &id004 !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ~>
73
+ - !ruby/object:Gem::Version
74
+ hash: 3
75
+ segments:
76
+ - 1
77
+ - 6
78
+ version: "1.6"
79
+ type: :development
80
+ version_requirements: *id004
81
+ prerelease: false
82
+ - !ruby/object:Gem::Dependency
83
+ name: activerecord
84
+ requirement: &id005 !ruby/object:Gem::Requirement
85
+ none: false
38
86
  requirements:
39
87
  - - ">="
40
88
  - !ruby/object:Gem::Version
89
+ hash: 3
41
90
  segments:
42
91
  - 2
43
92
  - 2
44
93
  - 2
45
94
  version: 2.2.2
46
- type: :runtime
47
- version_requirements: *id002
95
+ type: :development
96
+ version_requirements: *id005
97
+ prerelease: false
48
98
  description: Ruby Comma Seperated Values generation library
49
99
  email: crafterm@redartisan.com
50
100
  executables: []
@@ -54,7 +104,6 @@ extensions: []
54
104
  extra_rdoc_files:
55
105
  - README.rdoc
56
106
  files:
57
- - .gitignore
58
107
  - Gemfile
59
108
  - Gemfile.lock
60
109
  - MIT-LICENSE
@@ -76,39 +125,39 @@ files:
76
125
  - spec/comma/extractors_spec.rb
77
126
  - spec/spec.opts
78
127
  - spec/spec_helper.rb
79
- - sudo
80
128
  has_rdoc: true
81
129
  homepage: http://github.com/crafterm/comma
82
130
  licenses: []
83
131
 
84
132
  post_install_message:
85
- rdoc_options:
86
- - --charset=UTF-8
133
+ rdoc_options: []
134
+
87
135
  require_paths:
88
136
  - lib
89
137
  required_ruby_version: !ruby/object:Gem::Requirement
138
+ none: false
90
139
  requirements:
91
140
  - - ">="
92
141
  - !ruby/object:Gem::Version
142
+ hash: 3
93
143
  segments:
94
144
  - 0
95
145
  version: "0"
96
146
  required_rubygems_version: !ruby/object:Gem::Requirement
147
+ none: false
97
148
  requirements:
98
149
  - - ">="
99
150
  - !ruby/object:Gem::Version
151
+ hash: 3
100
152
  segments:
101
153
  - 0
102
154
  version: "0"
103
155
  requirements: []
104
156
 
105
157
  rubyforge_project: comma
106
- rubygems_version: 1.3.6
158
+ rubygems_version: 1.4.2
107
159
  signing_key:
108
160
  specification_version: 3
109
161
  summary: Ruby Comma Seperated Values generation library
110
- test_files:
111
- - spec/comma/ar_spec.rb
112
- - spec/comma/comma_spec.rb
113
- - spec/comma/extractors_spec.rb
114
- - spec/spec_helper.rb
162
+ test_files: []
163
+
data/.gitignore DELETED
@@ -1,4 +0,0 @@
1
- pkg/*
2
- .*.swp
3
- *~
4
- .bundle
data/sudo DELETED
@@ -1,384 +0,0 @@
1
- #!/usr/bin/env ruby
2
- #
3
- # This file, hub, is generated code.
4
- # Please DO NOT EDIT or send patches for it.
5
- #
6
- # Please take a look at the source from
7
- # http://github.com/defunkt/hub
8
- # and submit patches against the individual files
9
- # that build hub.
10
- #
11
-
12
- module Hub
13
- class Args < Array
14
- def after(command = nil, &block)
15
- @after ||= block ? block : command
16
- end
17
-
18
- def after?
19
- !!@after
20
- end
21
- end
22
- end
23
- module Hub
24
- module Commands
25
- instance_methods.each { |m| undef_method(m) unless m =~ /(^__|send|to\?$)/ }
26
- extend self
27
-
28
- PRIVATE = 'git@github.com:%s/%s.git'
29
- PUBLIC = 'git://github.com/%s/%s.git'
30
- USER = `git config --global github.user`.chomp
31
- REPO = `basename $(pwd)`.chomp
32
- LGHCONF = "http://github.com/guides/local-github-config"
33
-
34
- def clone(args)
35
- ssh = args.delete('-p')
36
- args[1..-1].each_with_index do |arg, i|
37
- i += 1
38
- if arg.scan('/').size == 1 && !arg.include?(':')
39
- url = ssh ? PRIVATE : PUBLIC
40
- args[i] = url % arg.split('/')
41
- break
42
- elsif arg !~ /:|\//
43
- url = ssh ? PRIVATE : PUBLIC
44
- args[i] = url % [ github_user, arg ]
45
- break
46
- end
47
- end
48
- end
49
-
50
- def remote(args)
51
- return unless args[1] == 'add'
52
-
53
- if args[-1] !~ /:|\//
54
- ssh = args.delete('-p')
55
- user = args.last
56
- url = ssh ? PRIVATE : PUBLIC
57
- args << url % [ user, REPO ]
58
- end
59
- end
60
-
61
- def init(args)
62
- if args.delete('-g')
63
-
64
- url = PRIVATE % [ github_user, REPO ]
65
- args.after "git remote add origin #{url}"
66
- end
67
- end
68
-
69
- def alias(args)
70
- shells = {
71
- 'sh' => 'alias git=hub',
72
- 'bash' => 'alias git=hub',
73
- 'zsh' => 'alias git=hub',
74
- 'csh' => 'alias git hub',
75
- 'fish' => 'alias git hub'
76
- }
77
-
78
- silent = args.delete('-s')
79
-
80
- if shell = args[1]
81
- if silent.nil?
82
- puts "Run this in your shell to start using `hub` as `git`:"
83
- print " "
84
- end
85
- else
86
- puts "usage: hub alias [-s] SHELL", ""
87
- puts "You already have hub installed and available in your PATH,"
88
- puts "but to get the full experience you'll want to alias it to"
89
- puts "`git`.", ""
90
- puts "To see how to accomplish this for your shell, run the alias"
91
- puts "command again with the name of your shell.", ""
92
- puts "Known shells:"
93
- shells.map { |key, _| key }.sort.each do |key|
94
- puts " " + key
95
- end
96
- puts "", "Options:"
97
- puts " -s Silent. Useful when using the output with eval, e.g."
98
- puts " $ eval `hub alias -s bash`"
99
-
100
- exit
101
- end
102
-
103
- if shells[shell]
104
- puts shells[shell]
105
- else
106
- abort "fatal: never heard of `#{shell}'"
107
- end
108
-
109
- exit
110
- end
111
-
112
- def version(args)
113
- args.after do
114
- puts "hub version %s" % Version
115
- end
116
- end
117
- alias_method "--version", :version
118
-
119
- def help(args)
120
- if args[1] == 'hub'
121
- puts hub_manpage
122
- exit
123
- elsif args.size == 1
124
- puts improved_help_text
125
- exit
126
- end
127
- end
128
-
129
- def improved_help_text
130
- <<-help
131
- usage: git [--version] [--exec-path[=GIT_EXEC_PATH]] [--html-path]
132
- [-p|--paginate|--no-pager] [--bare] [--git-dir=GIT_DIR]
133
- [--work-tree=GIT_WORK_TREE] [--help] COMMAND [ARGS]
134
-
135
- Basic Commands:
136
- init Create an empty git repository or reinitialize an existing one
137
- add Add new or modified files to the staging area
138
- rm Remove files from the working directory and staging area
139
- mv Move or rename a file, a directory, or a symlink
140
- status Show the status of the working directory and staging area
141
- commit Record changes to the repository
142
-
143
- History Commands:
144
- log Show the commit history log
145
- diff Show changes between commits, commit and working tree, etc
146
- show Show information about commits, tags or files
147
-
148
- Branching Commands:
149
- branch List, create, or delete branches
150
- checkout Switch the active branch to another branch
151
- merge Join two or more development histories (branches) together
152
- tag Create, list, delete, sign or verify a tag object
153
-
154
- Remote Commands:
155
- clone Clone a remote repository into a new directory
156
- fetch Download data, tags and branches from a remote repository
157
- pull Fetch from and merge with another repository or a local branch
158
- push Upload data, tags and branches to a remote repository
159
- remote View and manage a set of remote repositories
160
-
161
- Advanced commands:
162
- reset Reset your staging area or working directory to another point
163
- rebase Re-apply a series of patches in one branch onto another
164
- bisect Find by binary search the change that introduced a bug
165
- grep Print files with lines matching a pattern in your codebase
166
-
167
- See 'git help COMMAND' for more information on a specific command.
168
- help
169
- end
170
-
171
- private
172
-
173
- def github_user
174
- if USER.empty?
175
- abort "** No GitHub user set. See #{LGHCONF}"
176
- else
177
- USER
178
- end
179
- end
180
-
181
- def hub_manpage
182
- return "** Can't find groff(1)" unless groff?
183
-
184
- require 'open3'
185
- out = nil
186
- Open3.popen3(groff_command) do |stdin, stdout, _|
187
- stdin.puts hub_raw_manpage
188
- stdin.close
189
- out = stdout.read.strip
190
- end
191
- out
192
- end
193
-
194
- def groff?
195
- system("which groff")
196
- end
197
-
198
- def groff_command
199
- "groff -Wall -mtty-char -mandoc -Tascii"
200
- end
201
-
202
- def hub_raw_manpage
203
- if File.exists? file = File.dirname(__FILE__) + '/../../man/hub.1'
204
- File.read(file)
205
- else
206
- DATA.read
207
- end
208
- end
209
-
210
- def puts(*args)
211
- page_stdout
212
- super
213
- end
214
-
215
- def page_stdout
216
- return unless $stdout.tty?
217
-
218
- read, write = IO.pipe
219
-
220
- if Kernel.fork
221
- $stdin.reopen(read)
222
- read.close
223
- write.close
224
-
225
- ENV['LESS'] = 'FSRX'
226
-
227
- Kernel.select [STDIN]
228
-
229
- pager = ENV['PAGER'] || 'less -isr'
230
- exec pager rescue exec "/bin/sh", "-c", pager
231
- else
232
- $stdout.reopen(write)
233
- $stderr.reopen(write) if $stderr.tty?
234
- read.close
235
- write.close
236
- end
237
- end
238
- end
239
- end
240
- module Hub
241
- class Runner
242
- attr_reader :args
243
- def initialize(*args)
244
- @args = Args.new(args)
245
-
246
- @args[0] = 'help' if @args.empty?
247
-
248
- if Commands.respond_to?(@args[0])
249
- Commands.send(@args[0], @args)
250
- end
251
- end
252
-
253
- def self.execute(*args)
254
- new(*args).execute
255
- end
256
-
257
- def after
258
- args.after.to_s
259
- end
260
-
261
- def command
262
- "git #{args.join(' ')}"
263
- end
264
-
265
- def execute
266
- if args.after?
267
- execute_with_after_callback
268
- else
269
- exec "git", *args
270
- end
271
- end
272
-
273
- def execute_with_after_callback
274
- after = args.after
275
- if system("git", *args)
276
- after.respond_to?(:call) ? after.call : exec(after)
277
- exit
278
- else
279
- exit 1
280
- end
281
- end
282
- end
283
- end
284
- module Hub
285
- Version = '0.1.3'
286
- end
287
- Hub::Runner.execute(*ARGV)
288
- __END__
289
- .\" generated with Ron/v0.3
290
- .\" http://github.com/rtomayko/ron/
291
- .
292
- .TH "HUB" "1" "December 2009" "DEFUNKT" "Git Manual"
293
- .
294
- .SH "NAME"
295
- \fBhub\fR \-\- git + hub = github
296
- .
297
- .SH "SYNOPSIS"
298
- \fBhub\fR \fICOMMAND\fR \fIOPTIONS\fR
299
- .
300
- .br
301
- \fBhub alias\fR [\fB\-s\fR] \fISHELL\fR
302
- .
303
- .P
304
- \fBgit init \-g\fR \fIOPTIONS\fR
305
- .
306
- .br
307
- \fBgit clone\fR [\fB\-p\fR] \fIOPTIONS\fR [\fIUSER\fR/]\fIREPOSITORY\fR \fIDIRECTORY\fR
308
- .
309
- .br
310
- \fBgit remote add\fR [\fB\-p\fR] \fIOPTIONS\fR \fIUSER\fR[/\fIREPOSITORY\fR]
311
- .
312
- .br
313
- .
314
- .SH "DESCRIPTION"
315
- \fBhub\fR enhances various \fBgit\fR commands with GitHub remote expansion. The
316
- alias command displays information on configuring your environment:
317
- .
318
- .TP
319
- \fBhub alias\fR [\fB\-s\fR] \fISHELL\fR
320
- Writes shell aliasing code for \fISHELL\fR (\fBbash\fR, \fBsh\fR, \fBzsh\fR, \fBcsh\fR) to standard output. With the \fB\-s\fR option, the output of
321
- this command can be evaluated directly within the shell: \fBeval $(hub alias \-s bash)\fR
322
- .
323
- .P
324
- After configuring the alias, the following commands have superpowers:
325
- .
326
- .TP
327
- \fBgit init\fR \fB\-g\fR \fIOPTIONS\fR
328
- Create a git repository as with git\-init(1) and add remote \fBorigin\fR at
329
- "git@github.com:\fIUSER\fR/\fIREPOSITORY\fR.git"; \fIUSER\fR is your GitHub username and \fIREPOSITORY\fR is the current working directory's basename.
330
- .
331
- .TP
332
- \fBgit clone\fR [\fB\-p\fR] \fIOPTIONS\fR [\fIUSER\fR\fB/\fR]\fIREPOSITORY\fR \fIDIRECTORY\fR
333
- Clone repository "git://github.com/\fIUSER\fR/\fIREPOSITORY\fR.git" into \fIDIRECTORY\fR as with git\-clone(1). When \fIUSER\fR/ is omitted, assumes
334
- your GitHub login. With \fB\-p\fR, use private remote
335
- "git@github.com:\fIUSER\fR/\fIREPOSITORY\fR.git".
336
- .
337
- .TP
338
- \fBgit remote add\fR [\fB\-p\fR] \fIOPTIONS\fR \fIUSER\fR[\fB/\fR\fIREPOSITORY\fR]
339
- Add remote "git://github.com/\fIUSER\fR/\fIREPOSITORY\fR.git" as with
340
- git\-remote(1). When /\fIREPOSITORY\fR is omitted, the basename of the
341
- current working directory is used. With \fB\-p\fR, use private remote
342
- "git@github.com:\fIUSER\fR/\fIREPOSITORY\fR.git".
343
- .
344
- .TP
345
- \fBgit help\fR
346
- Display enhanced git\-help(1).
347
- .
348
- .SH "CONFIGURATION"
349
- Use git\-config(1) to display the currently configured GitHub username:
350
- .
351
- .IP "" 4
352
- .
353
- .nf
354
-
355
- $ git config \-\-global github.user
356
- .
357
- .fi
358
- .
359
- .IP "" 0
360
- .
361
- .P
362
- Or, set the GitHub username with:
363
- .
364
- .IP "" 4
365
- .
366
- .nf
367
-
368
- $ git config \-\-global github.user <username>
369
- .
370
- .fi
371
- .
372
- .IP "" 0
373
- .
374
- .P
375
- See \fIhttp://github.com/guides/local\-github\-config\fR for more information.
376
- .
377
- .SH "BUGS"
378
- \fIhttp://github.com/defunkt/hub/issues\fR
379
- .
380
- .SH "AUTHOR"
381
- Chris Wanstrath :: chris@ozmm.org :: @defunkt
382
- .
383
- .SH "SEE ALSO"
384
- git(1), git\-clone(1), git\-remote(1), git\-init(1),\fIhttp://github.com\fR, \fIhttp://github.com/defunkt/hub\fR