Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Processing Gemfile and Gemfile.lock

  Gemfile is found, processed using the Bundler library and then
  additional information is assumed (rubydoc.info and rubygems) or
  found through the Github API.

  Generates the Gemfile in the list of files
  • Loading branch information...
commit fdec4e3b2c579871c4bc4fae6892aade0ea4c5b0 0 parents
Franklin Webber authored
1  History.txt
@@ -0,0 +1 @@
+=== 0.0.1 / 2011-06-26
82 README.md
@@ -0,0 +1,82 @@
+YARD-Bundler: A YARD extension for Bundler
+=========================================
+
+NOTE: This extension is currently under development. At the current moment,
+the plugin is not particularly useful for any individual. Please feel free to
+clone and take a look around.
+
+Currently the project is still in requirements gathering phase.
+
+I would love ideas, thoughts, and mock ups of visualization and presentation of
+the data and how you would be see the gem serving you.
+
+
+Synopsis
+--------
+
+YARD-Bundler is a YARD extension that processes Bundler Gemfile and Gemfile.lock
+files and includes them in the documentation output.
+
+
+Installation
+------------
+
+*Build the gem yourself:*
+
+ $ git clone https://github.com/burtlo/yard-bundler
+ $ cd yard-bundler
+ $ gem build yard-bundler.gemspec
+ $ gem install --local yard-bundler-X.X.X.gem
+
+Usage
+-----
+
+YARD supports for automatically including gems with the prefix `yard-`
+as a plugin. To enable automatic loading yard-cucumber.
+
+1. Edit `~/.yard/config` and insert the following line:
+
+ load_plugins: true
+
+2. Run `yardoc`, use the rake task, or run `yard server`, as would [normally](https://github.com/lsegal/yard).
+
+Be sure to update any file patterns so that they do not exclude `feature`
+files. yard-cucumber will even process your step definitions and transforms.
+
+ $ yardoc 'lib/**/*.rb' 'spec/**/*_spec.rb'
+
+An example with the rake task:
+
+ require 'yard'
+
+ YARD::Rake::YardocTask.new do |t|
+ t.files = ['lib/**/*.rb' 'Gemfile', 'Gemfile.lock']
+ t.options = ['--debug'] # optional arguments
+ end
+
+
+LICENSE
+-------
+
+(The MIT License)
+
+Copyright (c) 2011 Franklin Webber
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13 Rakefile
@@ -0,0 +1,13 @@
+require 'rake'
+
+task :default => :gendoc
+
+task :clean do
+ `rm -rf doc`
+ `rm -rf .yardoc`
+end
+
+task :gendoc => :clean do
+ `yardoc -e ./lib/yard-bundler.rb 'example/**/*' --debug`
+ #`open doc/index.html`
+end
11 example/Gemfile
@@ -0,0 +1,11 @@
+source :rubygems
+
+gem 'rest-client'
+gem 'json'
+gem 'addressable'
+
+group :test do
+ gem 'rspec'
+ gem 'guard'
+ gem 'guard-rspec'
+end
33 example/Gemfile.lock
@@ -0,0 +1,33 @@
+GEM
+ remote: http://rubygems.org/
+ specs:
+ addressable (2.2.6)
+ diff-lcs (1.1.2)
+ guard (0.4.2)
+ thor (~> 0.14.6)
+ guard-rspec (0.4.0)
+ guard (>= 0.4.0)
+ json (1.5.3)
+ mime-types (1.16)
+ rest-client (1.6.3)
+ mime-types (>= 1.16)
+ rspec (2.6.0)
+ rspec-core (~> 2.6.0)
+ rspec-expectations (~> 2.6.0)
+ rspec-mocks (~> 2.6.0)
+ rspec-core (2.6.4)
+ rspec-expectations (2.6.0)
+ diff-lcs (~> 1.1.2)
+ rspec-mocks (2.6.0)
+ thor (0.14.6)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ addressable
+ guard
+ guard-rspec
+ json
+ rest-client
+ rspec
40 lib/templates/default/fulldoc/html/css/bundler.css
@@ -0,0 +1,40 @@
+ul.dependencies {
+ list-style: none;
+ padding-left: 20px;
+}
+
+ul.dependencies li {
+ padding-top: 10px;
+}
+
+ul.dependencies li.dependency h3 {
+ font-weight: bold; font-family: Monaco, Consolas, Courier, monospace;
+ margin-top: 0px;
+}
+
+li.dependency {
+ padding: 6px 10px; margin-top: 18px;
+ background: #e5e8ff; border: 1px solid #d8d8e5; -moz-border-radius: 3px; -webkit-border-radius: 3px;
+ color: #3F3F3F;
+ height: 20px;
+ clear: both;
+}
+
+
+li.dependency h3 div.name {
+ float: left;
+}
+
+li.dependency h3 div.version {
+ float: right;
+}
+
+div.details { }
+
+div.details ul li.documentation { padding-top: 10px; }
+div.details ul li.project {}
+li.issue { margin-left: 15px; }
+
+li.issue span.time { font-size: 10px; }
+li.issue span.tags { font-size: 10px; text-transform:uppercase; }
+li.commit { margin-left: 15px; }
55 lib/templates/default/fulldoc/html/gemfile.erb
@@ -0,0 +1,55 @@
+
+<h1>Gemfile</h1>
+
+<h2>Dependencies</h2>
+<div>
+ Provided below is a list of the files defined in the Gemfile and Gemfile.lock.
+ All of the dependencies and sub-dependencies are shown here with links to their
+ documentation and if it the project is hosted on Github additional links are
+ included to the project, issues, and recent commits.
+</div>
+
+<ul class="dependencies">
+<% dependencies.each do |dep| %>
+ <li class="dependency">
+ <h3>
+ <div class="name"><%= h dep.name %></div>
+ <div class="version">(<a href="<%= h dep.rubygems_version_url %>"><%= h dep.version %></a>)</div>
+ </h3>
+ <br/ style="clear:both;">
+ </li>
+ <li class="details">
+ <div class="details">
+ <ul style="list-style: none;">
+ <li class="documentation"><a href="<%= h dep.documentation_url %>">Documentation</a></li>
+
+ <% if dep.project_url and not dep.project_url == "" %>
+ <li class="project"><a href="<%= h dep.project_url %>">Project</a></li>
+ <% end %>
+
+
+ <% if dep.issues and not dep.issues.empty? %>
+ <h4>Open Issues</h4>
+ <% dep.open_bugs.each do |issue| %>
+ <li class="issue">
+ <a href="<%= h issue.html_url %>"><%= h issue.title %></a>
+ <span class="time"><%= h issue.updated_at %></span>
+ <span class="tags">[<%= h issue.labels.join(', ') %>]</span>
+ </li>
+ <% end %>
+
+ <% end %>
+
+ <% if dep.commits and not dep.commits.empty? %>
+ <h4>Recent Commits</h4>
+ <% dep.commits[0..4].each do |commit| %>
+ <li class="commit"><a href="http://github.com<%= commit.url %>"><%= h commit.message %></a></li>
+ <% end %>
+ <% end %>
+
+ </ul></div>
+ </li>
+
+<% end %>
+</ul>
+<br/ style="clear:both;">
28 lib/templates/default/fulldoc/html/setup.rb
@@ -0,0 +1,28 @@
+def init
+
+ # The Bundler namespace was stored within the Registry attached as a child on
+ # root, however, we do not want to have it displayed in the Class List so we
+ # have it removed.
+ YARD::Registry.root.children.delete YARD::CodeObjects::Bundler::BUNDLER_NAMESPACE
+
+ # Generate an ExtraFileObject, this is similar to a README, out of the Gemfile
+ gemfile = YARD::CodeObjects::ExtraFileObject.new("Gemfile.html",erb(:gemfile))
+
+ # Add it to the files that should be persisted and appearing in the FileList
+ options[:files] << gemfile
+
+ super
+
+ asset("css/bundler.css",file("css/bundler.css",true))
+end
+
+
+#
+# Helper method for providing the gemfile dependencies for use in the gemfile
+# template (gemfile.erb).
+#
+def dependencies
+ @dependencies ||= begin
+ YARD::Registry.all(:dependency)
+ end
+end
9 lib/templates/default/layout/html/setup.rb
@@ -0,0 +1,9 @@
+def init
+ super
+end
+
+# Append yard-bundler stylesheet to yard core stylesheets
+def stylesheets
+ log.info "Loading the yard-bundler stylesheets"
+ super + %w(css/bundler.css)
+end
19 lib/yard-bundler.rb
@@ -0,0 +1,19 @@
+module BundlerInTheYARD
+ VERSION = '0.0.1' unless defined?(BundlerInTheYARD::VERSION)
+end
+
+require File.dirname(__FILE__) + "/yard/parser/bundler/gemfile_parser"
+require File.dirname(__FILE__) + "/yard/code_objects/bundler/gemfile"
+
+if RUBY19
+ require File.dirname(__FILE__) + "/yard/handlers/gemfile"
+ require File.dirname(__FILE__) + "/yard/code_objects/bundler/gemfile"
+ require File.dirname(__FILE__) + "/yard/code_objects/bundler/dependency"
+end
+
+# This registered template works for yardoc
+YARD::Templates::Engine.register_template_path File.dirname(__FILE__) + '/templates'
+
+# The following static paths and templates are for yard server
+#YARD::Server.register_static_path File.dirname(__FILE__) + "/templates/default/fulldoc/html"
+#YARD::Server.register_static_path File.dirname(__FILE__) + "/docserver/default/fulldoc/html"
31 lib/yard/code_objects/bundler/dependency.rb
@@ -0,0 +1,31 @@
+
+module YARD::CodeObjects
+ module Bundler
+
+ #
+ # Generate a dependency object that we can represent in t
+ #
+ class Dependency < YARD::CodeObjects::Base
+
+ attr_accessor :version
+
+ attr_accessor :documentation_url
+
+ attr_accessor :project_url
+
+ def rubygems_version_url
+ "http://rubygems.org/gems/#{name}/versions/#{version}"
+ end
+
+ attr_accessor :issues, :commits
+
+ def open_bugs
+ issues.find_all {|issue| issue.state == "open" and issue.labels.include?("bug") }
+ end
+
+ # TODO: open bugs against the current version
+
+ end
+
+ end
+end
9 lib/yard/code_objects/bundler/gemfile.rb
@@ -0,0 +1,9 @@
+
+module YARD::CodeObjects
+ module Bundler
+
+ class Gemfile < YARD::CodeObjects::NamespaceObject ; end
+ BUNDLER_NAMESPACE = Gemfile.new(:root, "Gemfile") unless defined?(BUNDLER_NAMESPACE)
+
+ end
+end
0  lib/yard/handlers/gemfile.rb
No changes.
146 lib/yard/parser/bundler/gemfile_parser.rb
@@ -0,0 +1,146 @@
+require 'bundler'
+require 'hashie'
+require 'open-uri'
+require 'octokit'
+require 'json'
+# This is for Stack Overflow and will be implementated later
+#require 'pilha'
+
+module YARD::Parser::Bundler
+
+ class GemfileParser < YARD::Parser::Base
+
+ def initialize(source, file = '(stdin)')
+ @source = source
+ @file = file
+ end
+
+ #
+ # Parser the output of Rspec documentation output.
+ #
+ def parse
+
+ log.info "Gemfile - Bundler: #{File.basename(@file)} (#{File.basename(@file)[/^(.+)\.lock$/,1]})"
+
+ # Capture the current working directory so that we can restart it
+ working_directory = Dir.getwd
+
+ #
+ # Bundler required operations to be in the path local to the Gemfile. This
+ # is likely the same directory as the yard documentation is being generated.
+ # However, if it isn't we move into the directory.
+ #
+
+ Dir.chdir File.dirname(@file)
+
+ # Use Bundler's DSL evaluator to generate the domain objects
+
+ bundle = Bundler::Dsl.evaluate(File.basename(@file)[/^(.+)\.lock$/,1],File.basename(@file),{})
+
+ # DEBUG
+
+ # Dependencies - contains the entries in the Gemfile with their specified
+ # versions.
+
+ #log.info bundle.dependencies
+
+ # Specs - contains the entries in the Gemfile.lock with the specific versions.
+
+ #log.info bundle.specs
+
+ # For all the specs, we want to capture the project information and
+ # add it to the the dependency
+
+ bundle.specs.each do |spec|
+ decompose spec
+ end
+
+ # Return the working directory back to the original path
+ Dir.chdir working_directory
+
+ end
+
+ #
+ # @param [Gem::Specification] gem_specification containing the name and the
+ # version of the gem specification.
+ #
+ def decompose(gem_specification)
+
+ gem_name = gem_specification.name
+ gem_version = gem_specification.version.to_s
+
+ dependency = YARD::CodeObjects::Bundler::Dependency.new(YARD::CodeObjects::Bundler::BUNDLER_NAMESPACE,gem_name)
+ dependency.version = gem_version
+
+ # Generate a link to the YARDOC
+ # @example http://rubydoc.info/gems/a_b_plugin/0.1.0/frames
+ dependency.documentation_url = "http://rubydoc.info/gems/#{gem_name}/#{gem_version}/frames"
+
+ json = ""
+ mash = nil
+
+ # Rubygems API does not have a way to ask for detailed information about
+ # a particular version of a gem so you have to grab the latest.
+
+ begin
+ # Ask Rubygems for the gemspec
+ # curl http://rubygems.org/api/v1/gems/rails.json
+ open "http://rubygems.org/api/v1/gems/#{gem_name}.json" do |response|
+ json = JSON.parse(response.read)
+ mash = Hashie::Mash.new json
+ end
+ rescue
+ log.error "could not load the rubygems information for #{gem_name}"
+ end
+
+ # project_uri
+ # - when github has been specified, retrieve additional information
+
+ # TODO: check for github gem being installed
+
+ if mash and user_repo = mash.source_code_uri.to_s[/^http:\/\/github.com\/(.+)/,1]
+
+ log.debug "Setting Project URL: #{mash.source_code_uri}"
+ dependency.project_url = mash.source_code_uri
+
+ log.debug "Loading Github Repo: #{user_repo}"
+ github_repo = Octokit.repo(user_repo)
+
+ log.debug "Setting Github Issues: #{user_repo}"
+ # Retrieve the issues
+ dependency.issues = Octokit.issues(user_repo) if github_repo.has_issues
+
+ log.debug "Setting Github Commits: #{user_repo}"
+ # Retrieve the last commits
+ dependency.commits = Octokit.commits(user_repo)
+
+ end
+
+ # stackoverflow - last few tagged topics that match the gem
+ # TODO: change to use search text and perhaps not just tags
+ # StackExchange::StackOverflow::Question.find_by_tags gem_name
+ #
+
+ end
+
+
+
+ #
+ # Default YARD Parser methods
+ #
+ def tokenize
+
+ end
+
+ #
+ # Default YARD Parser methods
+ #
+ def enumerator
+
+ end
+
+ end
+
+
+ YARD::Parser::SourceParser.register_parser_type :gemfile, GemfileParser, 'lock'
+end
66 yard-bundler.gemspec
@@ -0,0 +1,66 @@
+require 'YARD'
+require File.dirname(__FILE__) + "/lib/yard-bundler"
+
+module BundlerInTheYARD
+ extend self
+
+ def show_version_changes(version)
+ date = ""
+ changes = []
+ grab_changes = false
+
+ File.open("#{File.dirname(__FILE__)}/History.txt",'r') do |file|
+ while (line = file.gets) do
+
+ if line =~ /^===\s*#{version.gsub('.','\.')}\s*\/\s*(.+)\s*$/
+ grab_changes = true
+ date = $1.strip
+ elsif line =~ /^===\s*.+$/
+ grab_changes = false
+ elsif grab_changes
+ changes = changes << line
+ end
+
+ end
+ end
+
+ { :date => date, :changes => changes }
+ end
+end
+
+Gem::Specification.new do |s|
+ s.name = 'yard-bundler'
+ s.version = ::BundlerInTheYARD::VERSION
+ s.authors = ["Franklin Webber"]
+ s.description = %{
+ YARD-Bundler is a YARD extension that processes Bundler Gemfiles. }
+ s.summary = "Bundler in YARD"
+ s.email = 'franklin.webber@gmail.com'
+ s.homepage = "http://github.com/burtlo/yard-bundler"
+
+ s.platform = Gem::Platform::RUBY
+
+ changes = BundlerInTheYARD.show_version_changes(::RSpecInTheYARD::VERSION)
+
+ s.post_install_message = %{
+(##) (##) (##) (##) (##) (##) (##) (##) (##) (##) (##) (##) (##) (##) (##)
+
+ Thank you for installing yard-bundler #{::BundlerInTheYARD::VERSION} / #{changes[:date]}.
+
+ Changes:
+ #{changes[:changes].collect{|change| " #{change}"}.join("")}
+(##) (##) (##) (##) (##) (##) (##) (##) (##) (##) (##) (##) (##) (##) (##)
+
+}
+
+ s.add_dependency 'yard', '~> 0.7'
+ s.add_dependency 'bundler', '~> 1.0'
+ s.add_dependency 'octokit', '~> 0.6'
+ s.add_dependency 'hashie', '~> 1.0'
+
+ s.rubygems_version = "1.3.7"
+ s.files = `git ls-files`.split("\n")
+ s.extra_rdoc_files = ["README.md", "History.txt"]
+ s.rdoc_options = ["--charset=UTF-8"]
+ s.require_path = "lib"
+end
Please sign in to comment.
Something went wrong with that request. Please try again.