Skip to content

Commit

Permalink
Merge branch 'plugin-templates'
Browse files Browse the repository at this point in the history
  • Loading branch information
gma committed Mar 3, 2015
2 parents a99a979 + 65a76d8 commit 9b7b26d
Show file tree
Hide file tree
Showing 11 changed files with 242 additions and 95 deletions.
2 changes: 1 addition & 1 deletion lib/nesta/commands/command.rb
Expand Up @@ -27,7 +27,7 @@ def template_root

def copy_template(src, dest)
FileUtils.mkdir_p(File.dirname(dest))
template = ERB.new(File.read(File.join(template_root, src)))
template = ERB.new(File.read(File.join(template_root, src)), nil, "-")
File.open(dest, 'w') { |file| file.puts template.result(binding) }
end

Expand Down
89 changes: 45 additions & 44 deletions lib/nesta/commands/plugin/create.rb
Expand Up @@ -20,61 +20,62 @@ def lib_path(*parts)
File.join(@gem_name, 'lib', *parts)
end

def modify_required_file
File.open(lib_path("#{@gem_name}.rb"), 'w') do |file|
file.write <<-EOF
require "#{@gem_name}/version"
Nesta::Plugin.register(__FILE__)
EOF
end
def module_name
module_names.join('::')
end

def modify_init_file
module_name = @name.split('-').map { |name| name.capitalize }.join('::')
File.open(lib_path(@gem_name, 'init.rb'), 'w') do |file|
file.puts <<-EOF
module Nesta
module Plugin
module #{module_name}
module Helpers
# If your plugin needs any helper methods, add them here...
end
end
end
def nested_module_definition_with_version
indent_level = 2
indent_with = ' '

class App
helpers Nesta::Plugin::#{module_name}::Helpers
end
end
EOF
lines = module_names.map { |name| "module #{name}\n" }
indent_levels = 0.upto(module_names.size - 1).to_a

lines << "VERSION = '0.1.0'\n"
indent_levels << module_names.size

(module_names.size - 1).downto(0).each do |indent_level|
lines << "end\n"
indent_levels << indent_level
end
end

def specify_gem_dependency
gemspec = File.join(@gem_name, "#{@gem_name}.gemspec")
File.open(gemspec, 'r+') do |file|
output = ''
file.each_line do |line|
if line =~ /^end/
output << ' gem.add_dependency("nesta", ">= 0.9.11")' + "\n"
output << ' gem.add_development_dependency("rake")' + "\n"
end
output << line
''.tap do |code|
lines.each_with_index do |line, i|
code << ' ' * (indent_levels[i] + 2) + line
end
file.pos = 0
file.print(output)
file.truncate(file.pos)
end
end

def make_directories
FileUtils.mkdir_p(File.join(@gem_name, 'lib', @gem_name))
end

def gem_path(path)
File.join(@gem_name, path)
end

def execute
run_process('bundle', 'gem', @gem_name)
modify_required_file
modify_init_file
specify_gem_dependency
Dir.chdir(@gem_name) { run_process('git', 'add', '.') }
make_directories
copy_templates(
'plugins/README.md' => gem_path('README.md'),
'plugins/gitignore' => gem_path('.gitignore'),
'plugins/plugin.gemspec' => gem_path("#{@gem_name}.gemspec"),
'plugins/Gemfile' => gem_path('Gemfile'),
'plugins/lib/required.rb' => gem_path("lib/#{@gem_name}.rb"),
'plugins/lib/version.rb' => gem_path("lib/#{@gem_name}/version.rb"),
'plugins/lib/init.rb' => gem_path("lib/#{@gem_name}/init.rb"),
'plugins/Rakefile' => gem_path('Rakefile')
)
Dir.chdir(@gem_name) do
run_process('git', 'init')
run_process('git', 'add', '.')
end
end

private
def module_names
@name.split('-').map { |name| name.capitalize }
end
end
end
end
Expand Down
119 changes: 69 additions & 50 deletions spec/commands/plugin/create_spec.rb
@@ -1,8 +1,21 @@
require File.expand_path('../../spec_helper', File.dirname(__FILE__))
require File.expand_path('../../../lib/nesta/commands', File.dirname(__FILE__))

describe "nesta:plugin:create" do
include_context "temporary working directory"
describe 'nesta:plugin:create' do
include_context 'temporary working directory'

def path_in_gem(path)
File.join(@gem_name, path)
end

def should_exist(path)
File.exist?(path_in_gem(path)).should be_true
end

def should_contain(path, pattern)
contents = File.read(path_in_gem(path))
contents.should match(pattern)
end

before(:each) do
@name = 'my-feature'
Expand All @@ -11,68 +24,74 @@
@working_dir = Dir.pwd
Dir.mkdir(@plugins_path)
Dir.chdir(@plugins_path)
@command = Nesta::Commands::Plugin::Create.new(@name)
@command.stub(:run_process)
Nesta::Commands::Plugin::Create.any_instance.stub(:system)
Nesta::Commands::Plugin::Create.new(@name).execute
end

after(:each) do
Dir.chdir(@working_dir)
FileUtils.rm_r(@plugins_path)
end

it "should create a new gem prefixed with nesta-plugin" do
@command.should_receive(:run_process).with('bundle', 'gem', @gem_name)
begin
@command.execute
rescue Errno::ENOENT
# This test is only concerned with running bundle gem; ENOENT
# errors are raised because we didn't create a real gem.
end
it "creates the gem's directory" do
File.directory?(@gem_name).should be_true
end

describe "after gem created" do
def create_gem_file(*components)
path = File.join(@plugins_path, @gem_name, *components)
FileUtils.makedirs(File.dirname(path))
File.open(path, 'w') { |f| yield f if block_given? }
path
end
it 'creates a README.md file with installation instructions' do
should_exist('README.md')
should_contain('README.md', %r{echo 'gem "#{@gem_name}"' >> Gemfile})
end

before(:each) do
@required_file = create_gem_file('lib', "#{@gem_name}.rb")
@init_file = create_gem_file('lib', @gem_name, 'init.rb')
@gem_spec = create_gem_file("#{@gem_name}.gemspec") do |file|
file.puts " # specify any dependencies here; for example:"
file.puts "end"
end
end
it 'creates .gitignore' do
should_exist('.gitignore')
end

after(:each) do
FileUtils.rm(@required_file)
FileUtils.rm(@init_file)
end
it 'creates the gemspec' do
path = "#{@gem_name}.gemspec"
should_exist(path)
should_contain(path, %r{require "#{@gem_name}/version"})
should_contain(path, %r{Nesta::Plugin::My::Feature::VERSION})
end

it "should create the ruby file loaded on require" do
@command.execute
File.read(@required_file).should include('Plugin.register(__FILE__)')
end
it 'creates a Gemfile' do
should_exist('Gemfile')
end

it "should create a default init.rb file" do
@command.execute
init = File.read(@init_file)
boilerplate = <<-EOF
module My::Feature
module Helpers
EOF
init.should include(boilerplate)
init.should include('helpers Nesta::Plugin::My::Feature::Helpers')
end
it 'creates Rakefile that helps with packaging the gem' do
should_exist("Rakefile")
end

it "should specify plugin gem's dependencies" do
@command.execute
text = File.read(@gem_spec)
text.should include('gem.add_dependency("nesta", ">= 0.9.11")')
text.should include('gem.add_development_dependency("rake")')
it 'creates default folder for Ruby files' do
code_directory = File.join(@gem_name, 'lib', @gem_name)
File.directory?(code_directory).should be_true
end

it 'creates file required when gem loaded' do
path = "#{File.join('lib', @gem_name)}.rb"
should_exist(path)
should_contain(path, %r{require "#{@gem_name}/version"})
end

it 'creates version.rb' do
path = File.join('lib', @gem_name, 'version.rb')
should_exist(path)
should_contain path, <<-EOF
module Nesta
module Plugin
module My
module Feature
VERSION = '0.1.0'
end
end
end
end
EOF
end

it 'creates skeleton code for the plugin in init.rb' do
path = File.join('lib', @gem_name, 'init.rb')
should_exist(path)
should_contain(path, "module Nesta\n module Plugin\n module My::Feature")
should_contain(path, 'helpers Nesta::Plugin::My::Feature::Helpers')
end
end
4 changes: 4 additions & 0 deletions templates/plugins/Gemfile
@@ -0,0 +1,4 @@
source "http://rubygems.org"

# Specify your gem's dependencies in <%= @gem_name %>.gemspec
gemspec
13 changes: 13 additions & 0 deletions templates/plugins/README.md
@@ -0,0 +1,13 @@
README
======

TODO: Explain what your plugin is for

Installation
------------

To use this plugin just add it to your Nesta project's `Gemfile` and
then install it with Bundler:

$ echo 'gem "<%= @gem_name %>"' >> Gemfile
$ bundle
58 changes: 58 additions & 0 deletions templates/plugins/Rakefile
@@ -0,0 +1,58 @@
def version
version_file = File.join(File.dirname(__FILE__), "lib", name, "version.rb")
contents = File.read(version_file)
contents.match(/VERSION = ['"]([0-9a-z.-]+)['"].*$/)
$1
end

def name
"<%= @gem_name %>"
end

def built_gem_path
gem_packages = File.join(File.dirname(__FILE__), "pkg", "#{name}-*.gem")
Dir[gem_packages].sort_by { |file| File.mtime(file) }.last
end

def already_tagged?
`git tag`.split(/\n/).include?("v#{version}")
end

desc "Build #{name}-#{version}.gem into the pkg directory."
task 'build' do
`gem build -V #{File.join(File.dirname(__FILE__), "#{name}.gemspec")}`
FileUtils.mkdir_p(File.join(File.dirname(__FILE__), "pkg"))
gem = Dir[File.join(File.dirname(__FILE__), "#{name}-*.gem")].sort_by{|f| File.mtime(f)}.last
FileUtils.mv(gem, 'pkg')
puts "#{name} #{version} built to #{built_gem_path}."
end

desc "Build and install #{name}-#{version}.gem into system gems."
task 'install' => 'build' do
`gem install '#{built_gem_path}' --local`
end

desc "Create tag v#{version} and build and push #{name}-#{version}.gem to Rubygems\n" \
"To prevent publishing in Rubygems use `gem_push=no rake release`"
task 'release' => ['build', 'release:guard_clean',
'release:source_control_push', 'release:rubygem_push'] do
end

task 'release:guard_clean' do
if !system("git diff --exit-code") || !system("git diff-index --quiet --cached HEAD")
puts "There are files that need to be committed first."
exit(1)
end
end

task 'release:source_control_push' do
unless already_tagged?
system "git tag -a -m 'Version #{version}' v#{version}"
system 'git push'
system 'git push --tags'
end
end

task 'release:rubygem_push' do
system "gem push #{built_gem_path}"
end
3 changes: 3 additions & 0 deletions templates/plugins/gitignore
@@ -0,0 +1,3 @@
*.gem
Gemfile.lock
pkg/*
13 changes: 13 additions & 0 deletions templates/plugins/lib/init.rb
@@ -0,0 +1,13 @@
module Nesta
module Plugin
module <%= module_name %>
module Helpers
# If your plugin needs any helper methods, add them here...
end
end
end
class App
helpers Nesta::Plugin::<%= module_name %>::Helpers
end
end
3 changes: 3 additions & 0 deletions templates/plugins/lib/required.rb
@@ -0,0 +1,3 @@
require "<%= @gem_name %>/version"

Nesta::Plugin.register(__FILE__)
5 changes: 5 additions & 0 deletions templates/plugins/lib/version.rb
@@ -0,0 +1,5 @@
module Nesta
module Plugin
<%= nested_module_definition_with_version -%>
end
end
28 changes: 28 additions & 0 deletions templates/plugins/plugin.gemspec
@@ -0,0 +1,28 @@
# -*- encoding: utf-8 -*-
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require "<%= @gem_name %>/version"

Gem::Specification.new do |spec|
spec.name = "<%= @gem_name %>"
spec.version = Nesta::Plugin::<%= module_name %>::VERSION
spec.authors = ["TODO: Your name"]
spec.email = ["TODO: Your email address"]
spec.homepage = ""
spec.summary = %q{TODO: Write a gem summary}
spec.description = %q{TODO: Write a gem description}
spec.license = "MIT"
spec.rubyforge_project = "<%= @gem_name %>"
spec.files = `git ls-files -z`.split("\x0")
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
spec.require_paths = ["lib"]
# specify any dependencies here; for example:
# spec.add_development_dependency "rspec"
# spec.add_runtime_dependency "rest-client"
spec.add_dependency("nesta", ">= 0.9.11")
spec.add_development_dependency("rake")
end

0 comments on commit 9b7b26d

Please sign in to comment.