Fingertips-jewelry_portfolio 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc ADDED
@@ -0,0 +1,107 @@
1
+ = JewelryPortfolio
2
+
3
+ Surely also lazy developers like to showcase their jewelry portfolio on their
4
+ GitHub pages.
5
+
6
+ Imagine writing an erb template once and use <tt>rake release</tt> to release
7
+ your gem with Jeweler as usual, but in addition re-generate and push the
8
+ index.html for your GitHub pages. If that sounds good to you, you're in luck.
9
+ Because that's exactly what this add-on for
10
+ Jeweler[http://github.com/technicalpickles/jeweler/tree/master] does.
11
+
12
+ == Usage
13
+
14
+ === GitHub pages repository
15
+
16
+ First things first; create a GitHub pages repository if you haven't done so
17
+ already. See http://github.com/guides/pages for more info.
18
+
19
+ Then create the following files, and content, in the gh-pages branch of your
20
+ pages repository (<em>for a more elaborate example see:
21
+ http://github.com/alloy/alloy.github.com/tree/gh-pages</em>):
22
+
23
+ * <b>Rakefile:</b>
24
+
25
+ require 'jewelry_portfolio/tasks'
26
+ JewelryPortfolio::Tasks.new do |t|
27
+ # Only specify the account if it's different from `github.user' in the git config.
28
+ t.account = 'Fingertips'
29
+ end
30
+
31
+ * <b>template.html.erb:</b>
32
+
33
+ This is the main template file which will be used to generate the index.html
34
+ file. All repositories and their gem specifications are available as the
35
+ local variable <tt>repos</tt>. See JewelryPortfolio::Template and
36
+ JewelryPortfolio::Repo for more information.</em>.
37
+
38
+ <html>
39
+ <head>
40
+ <title>Alloy&rsquo;s jewelry</title>
41
+ </head>
42
+
43
+ <p>This is an overview of the available gems by Eloy Duran, aka `alloy'.</p>
44
+
45
+ <body>
46
+ <% repos.each do |repo| %>
47
+ <%= repo_partial(repo) %>
48
+ <% end %>
49
+ </body>
50
+ </html>
51
+
52
+ * <b>repo.html.erb:</b>
53
+
54
+ This file is completely optional; it's just a showcase of using a repo
55
+ partial.
56
+
57
+ <div>
58
+ <h1><a href="<%= repo.url %>"><%= spec.name %> <%= spec.version %></a></h1>
59
+ <p><%= spec.description %></p>
60
+ <p>Install: <code>$ <%= repo.gem_install_command %></code></p>
61
+ <p>Clone: <code>$ git clone <%= repo.clone_url %></code></p>
62
+ </div>
63
+
64
+ Now you can generate the index.html file with:
65
+
66
+ $ rake portfolio:generate
67
+
68
+ Since you haven't added any projects yet the generated index will be pretty
69
+ dull. But for now just release this version:
70
+
71
+ $ rake portfolio:release
72
+
73
+ Whenever you update the template you can use these tasks to preview and/or
74
+ release it.
75
+
76
+ === Add super-cow powers to your project's Rakefile
77
+
78
+ Update the Rakefile of the project that you would like to include in your
79
+ jewelry portfolio like so:
80
+
81
+ begin
82
+ require 'jeweler'
83
+ Jeweler::Tasks.new do |s|
84
+ # ...
85
+ end
86
+
87
+ # Add the following to your Rakefile to use JewelryPortfolio
88
+ begin
89
+ require 'jewelry_portfolio/tasks'
90
+ rescue LoadError
91
+ puts "JewelryPortfolio not available. Install it with: sudo gem install Fingertips-jewelry_portfolio -s http://gems.github.com"
92
+ end
93
+
94
+ rescue LoadError
95
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
96
+ end
97
+
98
+ From now on, whenever you use the +release+ rake task, the GitHub pages
99
+ index.html will be re-generated and pushed to GitHub after releasing the gem.
100
+
101
+ If you just want to re-generate, or release, the jewelry portfolio use the
102
+ aforementioned <tt>portfolio:generate</tt> and <tt>portfolio:release</tt> rake
103
+ tasks.
104
+
105
+ == COPYRIGHT
106
+
107
+ Copyright (c) 2009 Fingertips, Eloy Duran. See LICENSE for details.
data/VERSION.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :minor: 1
3
+ :patch: 0
4
+ :major: 0
@@ -0,0 +1,47 @@
1
+ require 'jewelry_portfolio/repo'
2
+ require 'jewelry_portfolio/repos_index'
3
+ require 'jewelry_portfolio/template'
4
+
5
+ class JewelryPortfolio
6
+ class FileMissingError < StandardError; end
7
+
8
+ attr_reader :account, :spec, :index, :template
9
+
10
+ # Initializes a JewelryPortfolio instance for the specified +account+.
11
+ #
12
+ # If an optional +spec+ is provided it will be added to, or updated in, the
13
+ # index. If no +spec+ is provided it is assumed you are working in a clone of
14
+ # your GitHub pages repo. In this case no fetching and merging will be
15
+ # performed.
16
+ def initialize(account, spec = nil)
17
+ @account = account
18
+ @spec = spec
19
+ @index = ReposIndex.new(@account, (Dir.pwd unless @spec))
20
+ @template = Template.new(File.join(@index.path, 'template'), @index.repos)
21
+
22
+ @index.add(@spec) if @spec
23
+ end
24
+
25
+ # Renders the index.html file.
26
+ def render!
27
+ puts "Generating html"
28
+ File.open(File.join(@index.path, 'index.html'), 'w') { |f| f << @template.render }
29
+ end
30
+
31
+ # Renders the index.html file, then commits and pushes it to the remote.
32
+ def release!
33
+ render!
34
+ @index.commit! commit_message
35
+ @index.push!
36
+ end
37
+
38
+ private
39
+
40
+ def commit_message
41
+ if @spec
42
+ "Updated github pages for: #{@spec.name}-#{@spec.version}"
43
+ else
44
+ "Re-generated github pages"
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,43 @@
1
+ class JewelryPortfolio
2
+ class Repo
3
+ attr_accessor :spec, :account
4
+
5
+ def initialize(spec, account)
6
+ @spec, @account = spec, account
7
+ end
8
+
9
+ # Returns the name of the gem.
10
+ def name
11
+ @spec.name
12
+ end
13
+
14
+ # Returns the URL to the project page on GitHub.
15
+ def url
16
+ "http://github.com/#{@account}/#{name}/tree/master"
17
+ end
18
+
19
+ # Returns the public clone URL.
20
+ def clone_url
21
+ "git://github.com/#{@account}/#{name}.git"
22
+ end
23
+
24
+ # Returns the name of the gem file from GitHub, which is made up of the
25
+ # account name and the gem name.
26
+ def gem_name
27
+ "#{@account}-#{name}"
28
+ end
29
+
30
+ # Returns the command to install the gem. This is a helper for your views.
31
+ def gem_install_command
32
+ "sudo gem install #{gem_name} -s http://gems.github.com"
33
+ end
34
+
35
+ def ==(other)
36
+ other.is_a?(Repo) && name == other.name
37
+ end
38
+
39
+ def inspect
40
+ "#<#{self.class.name} name=\"#{name}\">"
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,111 @@
1
+ require 'git'
2
+ require 'rubygems/specification'
3
+ require 'tempfile'
4
+ require 'yaml'
5
+
6
+ class JewelryPortfolio
7
+ class ReposIndex
8
+ attr_reader :account
9
+
10
+ def initialize(account, custom_work_directory = nil)
11
+ @account, @custom_work_directory = account, custom_work_directory
12
+ end
13
+
14
+ def url
15
+ "git@github.com:#{@account}/#{repo_name}"
16
+ end
17
+
18
+ def path
19
+ @path ||= @custom_work_directory || File.join(Dir.tmpdir, repo_name)
20
+ end
21
+
22
+ def repo_name
23
+ @repo_name ||= "#{@account}.github.com.git"
24
+ end
25
+
26
+ def pages_repo
27
+ load_pages_repo!
28
+ @pages_repo
29
+ end
30
+
31
+ def repos_file
32
+ File.join(path, 'repos.yml')
33
+ end
34
+
35
+ def specs
36
+ unless @specs
37
+ load_pages_repo!
38
+ @specs = File.exist?(repos_file) ? YAML.load(File.read(repos_file)) : []
39
+ end
40
+ @specs
41
+ end
42
+
43
+ def repos
44
+ specs.map { |spec| Repo.new(spec, @account) }
45
+ end
46
+
47
+ def add(spec)
48
+ if old_spec = specs.find { |s| s.name == spec.name }
49
+ specs[specs.index(old_spec)] = spec
50
+ else
51
+ specs << spec
52
+ end
53
+ update_repos_file!
54
+ end
55
+
56
+ def commit!(message)
57
+ pages_repo.add
58
+ reraise_with_path { pages_repo.commit(message) }
59
+ end
60
+
61
+ def push!
62
+ puts "Pushing branch `gh-pages' to remote `#{url}'"
63
+ reraise_with_path { pages_repo.push('origin', 'gh-pages') }
64
+ end
65
+
66
+ def to_yaml
67
+ specs.to_yaml
68
+ end
69
+
70
+ private
71
+
72
+ def reraise_with_path
73
+ begin
74
+ yield
75
+ rescue Git::GitExecuteError => e
76
+ raise Git::GitExecuteError, "[#{path}] #{e.message}"
77
+ end
78
+ end
79
+
80
+ def update_repos_file!
81
+ File.open(repos_file, 'w') { |f| f << to_yaml }
82
+ end
83
+
84
+ def load_pages_repo!
85
+ (File.exist?(path) ? open_existing_repo! : open_new_repo!) unless @pages_repo
86
+ end
87
+
88
+ def open_existing_repo!
89
+ reraise_with_path do
90
+ @pages_repo = Git.open(path)
91
+ unless @custom_work_directory
92
+ puts "Pulling `#{url}'"
93
+ @pages_repo.checkout('gh-pages')
94
+ @pages_repo.fetch('origin')
95
+ @pages_repo.merge('origin/gh-pages')
96
+ end
97
+ end
98
+ end
99
+
100
+ def open_new_repo!
101
+ reraise_with_path do
102
+ puts "Cloning `#{url}'"
103
+ @pages_repo = Git.clone(url, repo_name, :path => File.dirname(path))
104
+ @pages_repo.checkout('origin/gh-pages')
105
+ branch = @pages_repo.branch('gh-pages')
106
+ branch.create
107
+ branch.checkout
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,67 @@
1
+ require 'jewelry_portfolio'
2
+
3
+ if defined?(Jeweler)
4
+ class Jeweler
5
+ alias_method :release_before_jewelry_portfolio, :release
6
+ def release
7
+ release_before_jewelry_portfolio
8
+ Rake::Task['portfolio:release'].invoke
9
+ end
10
+ end
11
+ end
12
+
13
+ class JewelryPortfolio
14
+ class Tasks
15
+ # Override this if this project is on another account than the one
16
+ # specified by `github.user' in your global or local git config.
17
+ attr_accessor :account
18
+
19
+ # Initialize the JewelryPortfolio rake tasks. The instance is yielded so
20
+ # additional configuration can be performed.
21
+ #
22
+ # JewelryPortfolio::Tasks.new do |t|
23
+ # t.account = 'Fingertips'
24
+ # end
25
+ def initialize
26
+ yield self if block_given?
27
+
28
+ @account ||= github_username
29
+ unless @account
30
+ raise ArgumentError, "Unable to determine `account'. Add a github user entry to your global, or local, git config. Or explicitely set the `account' on the JewelryPortfolio::Tasks instance."
31
+ end
32
+
33
+ define
34
+ end
35
+
36
+ private
37
+
38
+ def define
39
+ namespace :portfolio do
40
+ desc "Generate the HTML"
41
+ task :generate do
42
+ portfolio.render!
43
+ sh "open '#{File.join(portfolio.index.path, 'index.html')}'"
44
+ end
45
+
46
+ desc "Generates the HTML and commits and pushes the new release"
47
+ task :release do
48
+ portfolio.release!
49
+ end
50
+ end
51
+ end
52
+
53
+ def portfolio
54
+ if @portfolio.nil?
55
+ if spec_file = Dir.glob('*.gemspec').first
56
+ spec = eval(File.read(spec_file))
57
+ end
58
+ @portfolio = JewelryPortfolio.new(@account, spec)
59
+ end
60
+ @portfolio
61
+ end
62
+
63
+ def github_username
64
+ Git.open('.').config['github.user']
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,62 @@
1
+ require 'erb'
2
+
3
+ class JewelryPortfolio
4
+ # This class is responsible for rendering a template.
5
+ class Template
6
+ attr_reader :template, :repos, :view_path
7
+
8
+ # Initialize with the path to the +template+, minus the extensions, and an
9
+ # array of JewelryPortfolio::Repo instances as +repos+.
10
+ def initialize(template, repos)
11
+ template = File.expand_path(template)
12
+ @view_path = File.dirname(template)
13
+ @template = html_template_file(File.basename(template))
14
+ @repos = repos
15
+ end
16
+
17
+ # Renders the template and returns the output.
18
+ def render
19
+ erb @template, binding
20
+ end
21
+
22
+ # Renders a partial specified by +partial_name+ minus the extension. You
23
+ # can optionally specify a hash of +local_variables+ which will be
24
+ # available while rendering the partial.
25
+ #
26
+ # Consider a partial named <tt>foo.html.erb</tt>, in the same directory as
27
+ # the template, containing the following:
28
+ #
29
+ # Text: <%= text %>
30
+ #
31
+ # This partial can now be rendered like this:
32
+ #
33
+ # partial('foo', :text => 'bar') # => "Text: bar"
34
+ def partial(partial_name, local_variables = {})
35
+ for (var_name, var_value) in local_variables
36
+ eval "#{var_name} = var_value"
37
+ end
38
+ erb html_template_file(partial_name), binding
39
+ end
40
+
41
+ # Renders a partial for the specified +repo+. This method looks for a
42
+ # partial file named <tt>repo.html.erb</tt> in the same directory as the
43
+ # template.
44
+ #
45
+ # See partial for more info.
46
+ def repo_partial(repo, local_variables = {})
47
+ partial 'repo', local_variables.merge(:repo => repo, :spec => repo.spec)
48
+ end
49
+
50
+ private
51
+
52
+ def erb(file, binding)
53
+ ERB.new(File.read(file)).result(binding)
54
+ end
55
+
56
+ def html_template_file(name)
57
+ path = File.join(view_path, "#{name}.html.erb")
58
+ raise FileMissingError, "Could not find template at path `#{path}'" unless File.exist?(path)
59
+ path
60
+ end
61
+ end
62
+ end
Binary file
@@ -0,0 +1,15 @@
1
+ Gem::Specification.new do |spec|
2
+ spec.name = 'dr-nic-magic-awesome'
3
+ spec.version = '1.0.0'
4
+
5
+ spec.author = 'John Barnette'
6
+ spec.email = 'jbarnette@example.com'
7
+
8
+ spec.description = spec.summary = %{ Magically fix your projects overnight! }
9
+
10
+ spec.files = Dir['lib/**/*.rb', 'bin/*', '[A-Z]*', 'test/**/*']
11
+
12
+ spec.has_rdoc = true
13
+ spec.extra_rdoc_files = %w{ README.rdoc LICENSE TODO }
14
+ spec.rdoc_options << '--charset=utf-8' << '--main' << 'README.rdoc'
15
+ end
@@ -0,0 +1,2 @@
1
+ <h1>dr-nic-magic-awesome</h1>
2
+ <p>Magically fix your projects overnight!</p>
@@ -0,0 +1,17 @@
1
+ --- !ruby/object:JewelryPortfolio::Repo
2
+ spec: |-
3
+ Gem::Specification.new do |spec|
4
+ spec.name = 'dr-nic-magic-awesome'
5
+ spec.version = '1.0.0'
6
+
7
+ spec.author = 'John Barnette'
8
+ spec.email = 'jbarnette@example.com'
9
+
10
+ spec.description = spec.summary = %{ Magically fix your projects overnight! }
11
+
12
+ spec.files = Dir['lib/**/*.rb', 'bin/*', '[A-Z]*', 'test/**/*']
13
+
14
+ spec.has_rdoc = true
15
+ spec.extra_rdoc_files = %w{ README.rdoc LICENSE TODO }
16
+ spec.rdoc_options << '--charset=utf-8' << '--main' << 'README.rdoc'
17
+ end
@@ -0,0 +1,19 @@
1
+ Gem::Specification.new do |spec|
2
+ spec.name = 'microgem'
3
+ spec.version = '0.2.0'
4
+
5
+ spec.author = 'Eloy Duran'
6
+ spec.email = 'eloy.de.enige@gmail.com'
7
+
8
+ spec.description = spec.summary = %{
9
+ MicroGem provides a simple naive replacement for the `gem install' command
10
+ in the form of the `mgem' commandline utility.
11
+ }
12
+
13
+ spec.executables << 'ugem'
14
+ spec.files = Dir['lib/**/*.rb', 'bin/*', '[A-Z]*', 'test/**/*']
15
+
16
+ spec.has_rdoc = true
17
+ spec.extra_rdoc_files = %w{ README.rdoc LICENSE TODO }
18
+ spec.rdoc_options << '--charset=utf-8' << '--main' << 'README.rdoc'
19
+ end
@@ -0,0 +1,2 @@
1
+ <h1><%= spec.name %></h1>
2
+ <p><%= repo.spec.description %></p>
@@ -0,0 +1,109 @@
1
+ ---
2
+ - !ruby/object:Gem::Specification
3
+ name: dr-nic-magic-awesome
4
+ version: !ruby/object:Gem::Version
5
+ version: 1.0.0
6
+ platform: ruby
7
+ authors:
8
+ - John Barnette
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: &id001 2009-02-27 00:00:00 +01:00
14
+ default_executable:
15
+ dependencies: []
16
+
17
+ description: Magically fix your projects overnight!
18
+ email: jbarnette@example.com
19
+ executables: []
20
+
21
+ extensions: []
22
+
23
+ extra_rdoc_files:
24
+ - README.rdoc
25
+ - LICENSE
26
+ - TODO
27
+ files: []
28
+
29
+ has_rdoc: true
30
+ homepage:
31
+ post_install_message:
32
+ rdoc_options:
33
+ - --charset=utf-8
34
+ - --main
35
+ - README.rdoc
36
+ require_paths:
37
+ - lib
38
+ required_ruby_version: !ruby/object:Gem::Requirement
39
+ requirements: &id002
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: "0"
43
+ version:
44
+ required_rubygems_version: !ruby/object:Gem::Requirement
45
+ requirements: &id003
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: "0"
49
+ version:
50
+ requirements: []
51
+
52
+ rubyforge_project:
53
+ rubygems_version: 1.3.1
54
+ signing_key:
55
+ specification_version: 2
56
+ summary: Magically fix your projects overnight!
57
+ test_files: []
58
+
59
+ - !ruby/object:Gem::Specification
60
+ name: microgem
61
+ version: !ruby/object:Gem::Version
62
+ version: 0.2.0
63
+ platform: ruby
64
+ authors:
65
+ - Eloy Duran
66
+ autorequire:
67
+ bindir: bin
68
+ cert_chain: []
69
+
70
+ date: *id001
71
+ default_executable:
72
+ dependencies: []
73
+
74
+ description: MicroGem provides a simple naive replacement for the `gem install' command in the form of the `mgem' commandline utility.
75
+ email: eloy.de.enige@gmail.com
76
+ executables:
77
+ - ugem
78
+ extensions: []
79
+
80
+ extra_rdoc_files:
81
+ - README.rdoc
82
+ - LICENSE
83
+ - TODO
84
+ files: []
85
+
86
+ has_rdoc: true
87
+ homepage:
88
+ post_install_message:
89
+ rdoc_options:
90
+ - --charset=utf-8
91
+ - --main
92
+ - README.rdoc
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ requirements: *id002
97
+ version:
98
+ required_rubygems_version: !ruby/object:Gem::Requirement
99
+ requirements: *id003
100
+ version:
101
+ requirements: []
102
+
103
+ rubyforge_project:
104
+ rubygems_version: 1.3.1
105
+ signing_key:
106
+ specification_version: 2
107
+ summary: MicroGem provides a simple naive replacement for the `gem install' command in the form of the `mgem' commandline utility.
108
+ test_files: []
109
+
@@ -0,0 +1,8 @@
1
+ <html>
2
+ <body>
3
+ <h1>dr-nic-magic-awesome</h1>
4
+ <p>Magically fix your projects overnight!</p>
5
+ <h1>microgem</h1>
6
+ <p>MicroGem provides a simple naive replacement for the `gem install' command in the form of the `mgem' commandline utility.</p>
7
+ </body>
8
+ </html>
@@ -0,0 +1,5 @@
1
+ <html>
2
+ <body>
3
+ <%= repos.map { |repo| repo_partial(repo) }.join("\n") %>
4
+ </body>
5
+ </html>
@@ -0,0 +1,71 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ describe "JewelryPortfolio" do
4
+ before do
5
+ JewelryPortfolio::ReposIndex.any_instance.stubs(:url).returns(fixture('alloy.github.com'))
6
+ JewelryPortfolio::ReposIndex.any_instance.stubs(:path).returns(TMP_PAGES_REPO)
7
+ JewelryPortfolio::ReposIndex.any_instance.stubs(:puts)
8
+ FileUtils.rm_rf(TMP_PAGES_REPO)
9
+
10
+ @spec = eval(fixture_read('dr-nic-magic-awesome.gemspec_'))
11
+ @portfolio = JewelryPortfolio.new('alloy', @spec)
12
+
13
+ @portfolio.stubs(:puts)
14
+ end
15
+
16
+ it "should add the spec to the index" do
17
+ JewelryPortfolio::ReposIndex.any_instance.expects(:add).with(@spec)
18
+ JewelryPortfolio.new('alloy', @spec)
19
+ end
20
+
21
+ it "should also initialize without gemspec" do
22
+ JewelryPortfolio::ReposIndex.any_instance.expects(:add).never
23
+ JewelryPortfolio.new('alloy')
24
+ end
25
+
26
+ it "should return the local pages repos index" do
27
+ index = @portfolio.index
28
+ index.should.be.instance_of JewelryPortfolio::ReposIndex
29
+ index.repos.map { |r| r.spec.name }.should == %w{ dr-nic-magic-awesome microgem }
30
+ end
31
+
32
+ it "should return the template" do
33
+ template = @portfolio.template
34
+ template.should.be.instance_of JewelryPortfolio::Template
35
+ template.template.should == File.join(@portfolio.index.path, 'template.html.erb')
36
+ template.repos.should == @portfolio.index.repos
37
+ end
38
+
39
+ it "should write out the template" do
40
+ @portfolio.render!
41
+ File.read(File.join(@portfolio.index.path, 'index.html')).should == File.read(fixture('template.html'))
42
+ end
43
+
44
+ it "should render, commit, and push the `gh-pages' branch" do
45
+ @portfolio.expects(:render!)
46
+ @portfolio.index.expects(:commit!).with("Updated github pages for: dr-nic-magic-awesome-1.0.0")
47
+ @portfolio.index.expects(:push!)
48
+
49
+ @portfolio.release!
50
+ end
51
+ end
52
+
53
+ describe "JewelryPortfolio, with a custom work_directory" do
54
+ before do
55
+ JewelryPortfolio::ReposIndex.any_instance.stubs(:load_pages_repo!)
56
+ JewelryPortfolio::Template.stubs(:new)
57
+ @portfolio = JewelryPortfolio.new('alloy')
58
+ end
59
+
60
+ it "should initialize the index with the current work directory if no spec is given" do
61
+ @portfolio.index.instance_variable_get("@custom_work_directory").should == Dir.pwd
62
+ end
63
+
64
+ it "should render, commit, and push the `gh-pages' branch" do
65
+ @portfolio.expects(:render!)
66
+ @portfolio.index.expects(:commit!).with("Re-generated github pages")
67
+ @portfolio.index.expects(:push!)
68
+
69
+ @portfolio.release!
70
+ end
71
+ end
data/test/repo_test.rb ADDED
@@ -0,0 +1,44 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ describe "JewelryPortfolio::Repo" do
4
+ before do
5
+ @spec = fixture_eval('dr-nic-magic-awesome.gemspec_')
6
+ @repo = JewelryPortfolio::Repo.new(@spec, 'alloy')
7
+ end
8
+
9
+ it "should return the Gem::Specification instance" do
10
+ @repo.spec.should == @spec
11
+ end
12
+
13
+ it "should return the name of the gem it represents" do
14
+ @repo.name.should == 'dr-nic-magic-awesome'
15
+ end
16
+
17
+ it "should return the url to the github project page" do
18
+ @repo.url.should == 'http://github.com/alloy/dr-nic-magic-awesome/tree/master'
19
+ end
20
+
21
+ it "should return the public clone url" do
22
+ @repo.clone_url.should == 'git://github.com/alloy/dr-nic-magic-awesome.git'
23
+ end
24
+
25
+ it "should return the gem name" do
26
+ @repo.gem_name.should == "alloy-dr-nic-magic-awesome"
27
+ end
28
+
29
+ it "should return the gem install command" do
30
+ @repo.gem_install_command.should == "sudo gem install #{@repo.gem_name} -s http://gems.github.com"
31
+ end
32
+
33
+ xit "should return itself serialized as YAML" do
34
+ @repo.to_yaml.should == fixture_read('dr-nic-magic-awesome_repo.yml')
35
+ end
36
+
37
+ it "should be equal if the name matches" do
38
+ JewelryPortfolio::Repo.new(fixture_eval('dr-nic-magic-awesome.gemspec_'), 'alloy').should ==
39
+ JewelryPortfolio::Repo.new(fixture_eval('dr-nic-magic-awesome.gemspec_'), 'alloy')
40
+
41
+ JewelryPortfolio::Repo.new(fixture_eval('dr-nic-magic-awesome.gemspec_'), 'alloy').should.not ==
42
+ JewelryPortfolio::Repo.new(fixture_eval('microgem.gemspec_'), 'alloy')
43
+ end
44
+ end
@@ -0,0 +1,206 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ describe "JewelryPortfolio::ReposIndex, in general" do
4
+ before do
5
+ @index = JewelryPortfolio::ReposIndex.new('alloy')
6
+ end
7
+
8
+ it "should return the account" do
9
+ @index.account.should == 'alloy'
10
+ end
11
+
12
+ it "should return the repo name" do
13
+ @index.repo_name.should == 'alloy.github.com.git'
14
+ end
15
+
16
+ it "should return the url to the pages repo" do
17
+ @index.url.should == "git@github.com:alloy/alloy.github.com.git"
18
+ end
19
+
20
+ it "should return the path to the tmp checkout of the pages repo" do
21
+ @index.path.should == File.join(Dir.tmpdir, 'alloy.github.com.git')
22
+ end
23
+
24
+ it "should return the path to the repos YAML index file" do
25
+ @index.repos_file.should == File.join(@index.path, 'repos.yml')
26
+ end
27
+ end
28
+
29
+ describe "JewelryPortfolio::ReposIndex, in general, when the user specified a work directory" do
30
+ before do
31
+ @index = JewelryPortfolio::ReposIndex.new('alloy', '/path/to/repo')
32
+ File.stubs(:exist?).with(@index.path).returns(true)
33
+ end
34
+
35
+ it "should return the path to the tmp checkout of the pages repo" do
36
+ @index.path.should == '/path/to/repo'
37
+ end
38
+
39
+ it "should return the path to the repos YAML index file" do
40
+ @index.repos_file.should == File.join(@index.path, 'repos.yml')
41
+ end
42
+
43
+ it "should not pull from the remote pages repo when opening the repo" do
44
+ @index.instance_variable_set("@pages_repo", nil)
45
+
46
+ Git.expects(:open).with(@index.path)
47
+ Git::Base.any_instance.expects(:pull).never
48
+ @index.pages_repo
49
+ end
50
+ end
51
+
52
+ describe "JewelryPortfolio::ReposIndex, when working with a pages repo" do
53
+ before do
54
+ @index = JewelryPortfolio::ReposIndex.new('alloy')
55
+ @index.stubs(:url).returns(fixture('alloy.github.com'))
56
+ @index.stubs(:path).returns(TMP_PAGES_REPO)
57
+
58
+ @index.stubs(:puts)
59
+ end
60
+
61
+ it "should create a checkout of the pages repo if it doesn't exist yet and return it" do
62
+ FileUtils.rm_rf(TMP_PAGES_REPO)
63
+
64
+ @index.pages_repo.should.be.instance_of Git::Base
65
+ File.should.exist File.join(TMP_PAGES_REPO, 'repos.yml')
66
+ end
67
+
68
+ it "should create a checkout of the pages repo if it doesn't exist when asking for the repos" do
69
+ FileUtils.rm_rf(TMP_PAGES_REPO)
70
+
71
+ @index.repos
72
+ File.should.exist File.join(TMP_PAGES_REPO, 'repos.yml')
73
+ end
74
+
75
+ it "should not create a new checkout if it already exists, but do a pull" do
76
+ @index.pages_repo # make sure it exists
77
+ @index.instance_variable_set("@pages_repo", nil)
78
+
79
+ Git.expects(:clone).never
80
+ Git::Base.any_instance.expects(:checkout).with('gh-pages')
81
+ Git::Base.any_instance.expects(:fetch).with('origin')
82
+ Git::Base.any_instance.expects(:merge).with('origin/gh-pages')
83
+ @index.pages_repo
84
+ end
85
+
86
+ it "should create and checkout the `gh-pages' branch" do
87
+ FileUtils.rm_rf(TMP_PAGES_REPO)
88
+ @index.pages_repo.branch('gh-pages').should.be.current
89
+ @index.pages_repo.config('branch.gh-pages.remote').should == 'origin'
90
+ @index.pages_repo.config('branch.gh-pages.merge').should == 'refs/heads/gh-pages'
91
+ end
92
+
93
+ it "should return the pages repo" do
94
+ repo = @index.pages_repo
95
+ repo.should.be.instance_of Git::Base
96
+ end
97
+
98
+ it "should return an array of specs" do
99
+ FileUtils.rm_rf(TMP_PAGES_REPO)
100
+
101
+ @index.specs.each { |s| s.should.be.instance_of Gem::Specification }
102
+ @index.specs.map { |s| s.name }.should == %w{ dr-nic-magic-awesome microgem }
103
+ end
104
+
105
+ it "should return an empty array if the repos.yml file does not exist yet" do
106
+ FileUtils.rm(@index.repos_file)
107
+ @index.specs.should == []
108
+ end
109
+
110
+ it "should return an array of repos with their gemspecs" do
111
+ FileUtils.rm_rf(TMP_PAGES_REPO)
112
+
113
+ @index.repos.should == [
114
+ JewelryPortfolio::Repo.new(fixture_eval('dr-nic-magic-awesome.gemspec_'), 'alloy'),
115
+ JewelryPortfolio::Repo.new(fixture_eval('microgem.gemspec_'), 'alloy')
116
+ ]
117
+ end
118
+
119
+ xit "should serialize the array of repos as YAML" do
120
+ @index.to_yaml.should == fixture_read('repos.yml')
121
+ end
122
+
123
+ it "should push the `gh-pages' branch" do
124
+ @index.pages_repo.expects(:push).with('origin', 'gh-pages')
125
+ @index.push!
126
+ end
127
+
128
+ it "should commit the changes to the pages repo" do
129
+ assert_difference('pages_repo_commits', +1) do
130
+ File.open(@index.repos_file, 'w') { |f| f << 'foo' }
131
+ @index.commit!('test commit')
132
+ end
133
+ end
134
+
135
+ it "should also commit new files to the pages repo" do
136
+ assert_difference('pages_repo_commits', +1) do
137
+ File.open(File.join(@index.path, 'foo'), 'w') { |f| f << 'foo' }
138
+ @index.commit!('test commit')
139
+ end
140
+ end
141
+
142
+ it "should push the `gh-pages' branch" do
143
+ @index.pages_repo.expects(:push).with('origin', 'gh-pages')
144
+ @index.push!
145
+ end
146
+
147
+ it "should add a new spec to the repos.yml" do
148
+ FileUtils.rm_rf(TMP_PAGES_REPO)
149
+ @index.repos # make sure its loaded
150
+
151
+ spec = eval(fixture_read('dr-nic-magic-awesome.gemspec_').
152
+ gsub('dr-nic-magic-awesome', 'dr-nic-magic-awesome-v2'))
153
+
154
+ assert_difference('repos_from_file.length', +1) do
155
+ @index.add(spec)
156
+ end
157
+
158
+ repos_from_file.last.name.should == 'dr-nic-magic-awesome-v2'
159
+ end
160
+
161
+ it "should update an existing spec in the repos.yml" do
162
+ FileUtils.rm_rf(TMP_PAGES_REPO)
163
+ @index.repos # make sure its loaded
164
+
165
+ spec = eval(fixture_read('dr-nic-magic-awesome.gemspec_').gsub('1.0.0', '1.1.1'))
166
+
167
+ assert_no_difference('repos_from_file.length') do
168
+ @index.add(spec)
169
+ end
170
+
171
+ repos_from_file.first.version.to_s.should == '1.1.1'
172
+ end
173
+
174
+ it "should re-raise Git::GitExecuteErrors with the repo path prepended" do
175
+ message = nil
176
+ @index.commit! 'clean'
177
+
178
+ begin
179
+ @index.commit! 'error'
180
+ rescue Git::GitExecuteError => e
181
+ message = e.message
182
+ end
183
+
184
+ message.should.match /^\[#{@index.path}\]/
185
+ end
186
+
187
+ private
188
+
189
+ def repos_from_file
190
+ YAML.load(File.read(@index.repos_file))
191
+ end
192
+
193
+ def pages_repo_commits
194
+ @index.pages_repo.log.size
195
+ end
196
+
197
+ def assert_difference(eval_str, diff)
198
+ before = eval(eval_str)
199
+ yield
200
+ assert_equal before + diff, eval(eval_str)
201
+ end
202
+
203
+ def assert_no_difference(eval_str, &block)
204
+ assert_difference(eval_str, 0, &block)
205
+ end
206
+ end
@@ -0,0 +1,83 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ class GemSpecMock
4
+ attr_accessor :name, :description
5
+
6
+ def initialize(name, description)
7
+ @name, @description = name, description
8
+ end
9
+ end
10
+
11
+ describe "JewelryPortfolio::Template" do
12
+ before do
13
+ @repos = [
14
+ JewelryPortfolio::Repo.new(GemSpecMock.new('dr-nic-magic-awesome', "Magically fix your projects overnight!"), 'alloy'),
15
+ JewelryPortfolio::Repo.new(GemSpecMock.new('microgem', "MicroGem provides a simple naive replacement for the `gem install' command in the form of the `mgem' commandline utility."), 'alloy')
16
+ ]
17
+
18
+ @page = JewelryPortfolio::Template.new(fixture('template'), @repos)
19
+ end
20
+
21
+ it "should raise a JewelryPortfolio::FileMissingError if the specified template does not exist" do
22
+ e = nil
23
+ begin
24
+ JewelryPortfolio::Template.new('/not/existing/template', @repos)
25
+ rescue JewelryPortfolio::FileMissingError => e
26
+ end
27
+
28
+ e.should.be.instance_of JewelryPortfolio::FileMissingError
29
+ e.message.should == "Could not find template at path `/not/existing/template.html.erb'"
30
+ end
31
+
32
+ it "should return the path to the template" do
33
+ @page.template.should == fixture('template.html.erb')
34
+ end
35
+
36
+ it "should return the repos" do
37
+ @page.repos.should == @repos
38
+ end
39
+
40
+ it "should return the view_path" do
41
+ @page.view_path.should == FIXTURE_PATH
42
+ end
43
+
44
+ it "should render with the specified gem repos available as `repos'" do
45
+ File.stubs(:read).returns('<%= repos.inspect %>')
46
+ @page.render.should == @repos.inspect
47
+ end
48
+
49
+ it "should render an ERB partial with the specified local variables" do
50
+ @page.partial('repo', :repo => @repos.first, :spec => @repos.first.spec).should ==
51
+ File.read(fixture('dr-nic-magic-awesome.html'))
52
+ end
53
+
54
+ it "should render an ERB partial with the specified repo and make its spec available" do
55
+ @page.repo_partial(@repos.first).should ==
56
+ File.read(fixture('dr-nic-magic-awesome.html'))
57
+ end
58
+
59
+ it "should render an ERB partial with the specified repo and local variables" do
60
+ File.stubs(:read).returns('<%= "#{repo.name} #{extra_var}" %>')
61
+ @page.repo_partial(@repos.first, :extra_var => 'extra_var_value').should == "#{@repos.first.name} extra_var_value"
62
+ end
63
+
64
+ it "should render an ERB partial with nested partials" do
65
+ stubs_file_exists_and_returns('parent.html.erb', 'Hello <%= partial "nested1", :text => "world!" %>')
66
+ stubs_file_exists_and_returns('nested1.html.erb', '<%= text %> <%= partial "nested2", :text => "Wazzup?!" %>')
67
+ stubs_file_exists_and_returns('nested2.html.erb', '<%= text %>')
68
+
69
+ @page.partial('parent').should == 'Hello world! Wazzup?!'
70
+ end
71
+
72
+ it "should render the ERB template" do
73
+ @page.render.should == File.read(fixture('template.html'))
74
+ end
75
+
76
+ private
77
+
78
+ def stubs_file_exists_and_returns(fixture_name, data)
79
+ path = File.join(FIXTURE_PATH, fixture_name)
80
+ File.stubs(:exist?).with(path).returns(true)
81
+ File.stubs(:read).with(path).returns(data)
82
+ end
83
+ end
@@ -0,0 +1,29 @@
1
+ require 'rubygems'
2
+ require 'test/spec'
3
+ require 'mocha'
4
+
5
+ $:.unshift File.expand_path('../../lib', __FILE__)
6
+ require 'jewelry_portfolio'
7
+
8
+ TMP_PATH = File.expand_path('../tmp', __FILE__)
9
+ FileUtils.mkdir_p(TMP_PATH) unless File.exist?(TMP_PATH)
10
+
11
+ TMP_PAGES_REPO = File.join(TMP_PATH, 'alloy.github.com.git')
12
+
13
+ FIXTURE_PATH = File.expand_path('../fixtures', __FILE__)
14
+
15
+ `cd #{FIXTURE_PATH} && tar zxvf alloy.github.com.tgz` unless File.exist?(File.join(FIXTURE_PATH, 'alloy.github.com'))
16
+
17
+ class Test::Unit::TestCase
18
+ def fixture(file)
19
+ File.join(FIXTURE_PATH, file)
20
+ end
21
+
22
+ def fixture_read(file)
23
+ File.read(fixture(file))
24
+ end
25
+
26
+ def fixture_eval(name)
27
+ eval(fixture_read(name))
28
+ end
29
+ end
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: Fingertips-jewelry_portfolio
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Eloy Duran
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-03-01 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Imagine writing an erb template once and use <tt>rake release</tt> to release your gem with Jeweler as usual, but in addition re-generate and push the index.html for your GitHub pages. If that sounds good to you, you're in luck. Because that's exactly what this add-on for Jeweler[http://github.com/technicalpickles/jeweler/tree/master] does.
17
+ email: eloy.de.enige@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - README.rdoc
26
+ - VERSION.yml
27
+ - lib/jewelry_portfolio
28
+ - lib/jewelry_portfolio/repo.rb
29
+ - lib/jewelry_portfolio/repos_index.rb
30
+ - lib/jewelry_portfolio/tasks.rb
31
+ - lib/jewelry_portfolio/template.rb
32
+ - lib/jewelry_portfolio.rb
33
+ - test/fixtures
34
+ - test/fixtures/alloy.github.com
35
+ - test/fixtures/alloy.github.com/index.html
36
+ - test/fixtures/alloy.github.com/repo.html.erb
37
+ - test/fixtures/alloy.github.com/repos.yml
38
+ - test/fixtures/alloy.github.com/template.html.erb
39
+ - test/fixtures/alloy.github.com.tgz
40
+ - test/fixtures/dr-nic-magic-awesome.gemspec_
41
+ - test/fixtures/dr-nic-magic-awesome.html
42
+ - test/fixtures/dr-nic-magic-awesome_repo.yml
43
+ - test/fixtures/microgem.gemspec_
44
+ - test/fixtures/repo.html.erb
45
+ - test/fixtures/repos.yml
46
+ - test/fixtures/template.html
47
+ - test/fixtures/template.html.erb
48
+ - test/jewelry_portfolio_test.rb
49
+ - test/repo_test.rb
50
+ - test/repos_index_test.rb
51
+ - test/template_test.rb
52
+ - test/test_helper.rb
53
+ - test/tmp
54
+ - test/tmp/alloy.github.com.git
55
+ - test/tmp/alloy.github.com.git/index.html
56
+ - test/tmp/alloy.github.com.git/repo.html.erb
57
+ - test/tmp/alloy.github.com.git/repos.yml
58
+ - test/tmp/alloy.github.com.git/template.html.erb
59
+ has_rdoc: true
60
+ homepage: http://github.com/alloy/repo_page_san
61
+ post_install_message:
62
+ rdoc_options:
63
+ - --inline-source
64
+ - --charset=UTF-8
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: "0"
72
+ version:
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: "0"
78
+ version:
79
+ requirements: []
80
+
81
+ rubyforge_project:
82
+ rubygems_version: 1.2.0
83
+ signing_key:
84
+ specification_version: 2
85
+ summary: An add-on for Jeweler for lazy developers who would like to showcase their jewelry portfolio on their GitHub pages.
86
+ test_files: []
87
+