├── .gitignore ├── .rvmrc ├── .rspec ├── Gemfile ├── spec ├── spec_helper.rb ├── gram_spec.rb └── gram │ ├── gem_spec.rb │ ├── blog │ └── parser_spec.rb │ ├── ssh_spec.rb │ ├── blog_spec.rb │ └── gem │ └── generator_spec.rb ├── lib ├── gram │ ├── version.rb │ ├── gem │ │ ├── templates │ │ │ ├── rvmrc.tt │ │ │ ├── gitignore.tt │ │ │ ├── spec │ │ │ │ ├── rspec_helper.tt │ │ │ │ └── minispec_helper.tt │ │ │ ├── Readme.tt │ │ │ ├── Rakefile_rspec.tt │ │ │ └── Rakefile.tt │ │ └── generator.rb │ ├── blog │ │ └── parser.rb │ ├── gem.rb │ ├── ssh.rb │ └── blog.rb └── gram.rb ├── Rakefile ├── bin └── gram ├── gram.gemspec ├── Readme.md └── Gemfile.lock /.gitignore: -------------------------------------------------------------------------------- 1 | pkg/ 2 | tmp/ 3 | -------------------------------------------------------------------------------- /.rvmrc: -------------------------------------------------------------------------------- 1 | rvm --create use ruby-1.9.2@gram 2 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | --format documentation 3 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source :gemcutter 2 | 3 | gemspec 4 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require 'rspec' 2 | require 'gram' 3 | -------------------------------------------------------------------------------- /lib/gram/version.rb: -------------------------------------------------------------------------------- 1 | module Gram 2 | VERSION = '0.3.0' 3 | end 4 | -------------------------------------------------------------------------------- /spec/gram_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe Gram do 4 | end 5 | -------------------------------------------------------------------------------- /lib/gram/gem/templates/rvmrc.tt: -------------------------------------------------------------------------------- 1 | rvm --create use ruby-1.9.2@<%= underscored %> 2 | -------------------------------------------------------------------------------- /lib/gram/gem/templates/gitignore.tt: -------------------------------------------------------------------------------- 1 | *.gem 2 | .bundle 3 | pkg/* 4 | graph.png 5 | .yardoc/* 6 | doc/* 7 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'bundler' 2 | Bundler::GemHelper.install_tasks 3 | 4 | require 'rspec/core/rake_task' 5 | desc "Run the specs under spec" 6 | RSpec::Core::RakeTask.new 7 | 8 | task :default => :spec 9 | -------------------------------------------------------------------------------- /lib/gram.rb: -------------------------------------------------------------------------------- 1 | require 'gram/blog' 2 | require 'gram/blog/parser' 3 | 4 | require 'gram/gem' 5 | require 'gram/gem/generator' 6 | 7 | require 'gram/ssh' 8 | 9 | module Gram 10 | COMPONENTS = %w(blog gem ssh) 11 | end 12 | -------------------------------------------------------------------------------- /lib/gram/gem/templates/spec/rspec_helper.tt: -------------------------------------------------------------------------------- 1 | require 'rspec' 2 | require '<%= underscored %>' 3 | <% if rails %> 4 | 5 | ActiveRecord::Base.establish_connection( 6 | :adapter => 'sqlite3', 7 | :database => ':memory:' 8 | ) 9 | 10 | ActiveRecord::Schema.define do 11 | create_table :articles do |t| 12 | t.string :name 13 | t.integer :price 14 | 15 | t.timestamps 16 | end 17 | end 18 | <% end %> 19 | -------------------------------------------------------------------------------- /spec/gram/gem_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | module Gram 4 | describe Gem do 5 | 6 | describe ".create" do 7 | it 'calls a gem generator' do 8 | generator = mock(Gem::Generator) 9 | Gem::Generator.should_receive(:new).and_return generator 10 | generator.should_receive(:generate).with('my_gem', ['--rails']) 11 | 12 | subject.create 'my_gem', '--rails' 13 | end 14 | end 15 | 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/gram/blog/parser.rb: -------------------------------------------------------------------------------- 1 | require 'yaml' 2 | 3 | module Gram 4 | module Blog 5 | module Parser 6 | class << self 7 | 8 | def parse(file) 9 | raw_content = File.read(file) 10 | headers = raw_content.match(/---(.*)---/m) 11 | yaml = YAML.load($1.strip) 12 | 13 | content = raw_content.gsub(/---.*---/m, '').strip 14 | 15 | yaml.update({ 'body' => content }) 16 | end 17 | 18 | end 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/gram/gem/templates/spec/minispec_helper.tt: -------------------------------------------------------------------------------- 1 | gem 'minitest' 2 | require 'minitest/spec' 3 | require 'minitest/autorun' 4 | require 'mocha' 5 | 6 | require '<%= underscored %>' 7 | <% if rails %> 8 | 9 | ActiveRecord::Base.establish_connection( 10 | :adapter => 'sqlite3', 11 | :database => ':memory:' 12 | ) 13 | 14 | ActiveRecord::Schema.define do 15 | create_table :articles do |t| 16 | t.string :name 17 | t.integer :price 18 | 19 | t.timestamps 20 | end 21 | end 22 | <% end %> 23 | -------------------------------------------------------------------------------- /bin/gram: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | $: << 'lib' 3 | require 'gram' 4 | 5 | component = ARGV.shift 6 | action = ARGV.shift 7 | args = ARGV 8 | 9 | raise "Unknown Gram component. Available components are: #{Gram::COMPONENTS.join(', ')}" unless Gram::COMPONENTS.include?(component) 10 | 11 | component_klass = eval("Gram::#{component.capitalize}") 12 | 13 | raise "Unknown action for #{component} component.\n#{component_klass.banner}\n" unless component_klass::ACTIONS.keys.map(&:to_s).include?(action) 14 | 15 | component_klass.send(action, *args) 16 | -------------------------------------------------------------------------------- /spec/gram/blog/parser_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | module Gram 4 | module Blog 5 | describe Parser do 6 | 7 | describe ".parse" do 8 | it 'converts a file into a hash' do 9 | file = double :file 10 | raw = """ 11 | --- 12 | title: My title 13 | tagline: My tagline 14 | published: false 15 | --- 16 | 17 | #My post 18 | # 19 | Blah 20 | """ 21 | File.stub(:read).with(file).and_return raw 22 | 23 | subject.parse(file).should == { 'title' => 'My title', 24 | 'tagline' => 'My tagline', 25 | 'published' => false, 26 | 'body' => "#My post\n#\nBlah"} 27 | end 28 | end 29 | 30 | end 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /lib/gram/gem.rb: -------------------------------------------------------------------------------- 1 | module Gram 2 | module Gem 3 | 4 | ACTIONS = { create: { 5 | description: "Creates a new gem with the given NAME", 6 | arguments: %w(NAME [--rails]), 7 | }, 8 | } 9 | 10 | class << self 11 | 12 | def banner 13 | out = "Available actions:\n" 14 | ACTIONS.each_pair do |action, metadata| 15 | out << "\n\t#{action} #{metadata[:arguments].join(' ')}\t\t#{metadata[:description]}" 16 | end 17 | out 18 | end 19 | 20 | # ACTIONS 21 | 22 | def create(name, *options) 23 | puts "Gram::Gem generating gem scaffold for #{name}..." 24 | Generator.new.generate(name, options) 25 | puts "Generated on ./#{name} :)" 26 | end 27 | 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /spec/gram/ssh_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | module Gram 4 | describe Ssh do 5 | 6 | describe ".paste" do 7 | it 'pastes a post to a peer' do 8 | subject.stub(:get_peers).and_return({"josepjaume" => "192.168.1.55.55"}) 9 | subject.stub(:system) 10 | subject.should_receive(:system).with("pbpaste | ssh josepjaume@192.168.1.55.55 pbcopy") 11 | 12 | subject.paste 'josepjaume' 13 | end 14 | end 15 | 16 | describe ".broadcast" do 17 | it 'pastes a post to every peer' do 18 | subject.stub(:get_peers).and_return({"josepjaume" => "192.168.1.55.55", "oriol" => "192.168.1.55.54"}) 19 | 20 | subject.should_receive(:paste).with("josepjaume") 21 | subject.should_receive(:paste).with("oriol") 22 | 23 | subject.broadcast 24 | end 25 | end 26 | 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /lib/gram/gem/templates/Readme.tt: -------------------------------------------------------------------------------- 1 | #<%= underscored %> 2 | 3 | <%= camelized %> is a lightweight gem aimed at saving the world. 4 | 5 | ##Install 6 | 7 | $ gem install <%= underscored %> 8 | 9 | Or in your Gemfile: 10 | 11 | gem '<%= underscored %>' 12 | 13 | ##Usage 14 | 15 | (usage instructions) 16 | 17 | ##Under the hood 18 | 19 | Run the test suite by typing: 20 | 21 | rake spec 22 | 23 | You can also build the documentation with the following command: 24 | 25 | rake docs 26 | 27 | ## Note on Patches/Pull Requests 28 | 29 | * Fork the project. 30 | * Make your feature addition or bug fix. 31 | * Add tests for it. This is important so I don't break it in a 32 | future version unintentionally. 33 | * Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull) 34 | * Send us a pull request. Bonus points for topic branches. 35 | 36 | ## Copyright 37 | 38 | Copyright (c) 2011 Codegram. See LICENSE for details. 39 | -------------------------------------------------------------------------------- /gram.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | $:.push File.expand_path("../lib", __FILE__) 3 | require "gram/version" 4 | 5 | Gem::Specification.new do |s| 6 | s.name = "gram" 7 | s.version = Gram::VERSION 8 | s.platform = Gem::Platform::RUBY 9 | s.authors = ["Josep M. Bach", "Josep Jaume Rey", "Oriol Gual"] 10 | s.email = ["info@codegram.com"] 11 | s.homepage = "http://github.com/codegram/gram" 12 | s.summary = %q{Internal client for Codegram administration} 13 | s.description = %q{Internal client for Codegram administration} 14 | 15 | s.rubyforge_project = "gram" 16 | 17 | s.add_runtime_dependency 'rest-client' 18 | s.add_runtime_dependency 'thor' 19 | s.add_runtime_dependency 'i18n' 20 | s.add_runtime_dependency 'activesupport' 21 | 22 | s.add_development_dependency 'bundler', '~> 1.0.7' 23 | s.add_development_dependency 'rspec', '~> 2.5.0' 24 | s.add_development_dependency 'generator_spec', '~> 0.8.1' 25 | s.add_development_dependency 'activemodel' 26 | 27 | s.files = `git ls-files`.split("\n") 28 | s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") 29 | s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } 30 | s.require_paths = ["lib"] 31 | end 32 | -------------------------------------------------------------------------------- /lib/gram/gem/templates/Rakefile_rspec.tt: -------------------------------------------------------------------------------- 1 | require 'bundler' 2 | Bundler::GemHelper.install_tasks 3 | 4 | require 'rspec/core/rake_task' 5 | desc "Run <%= underscored %> specs" 6 | RSpec::Core::RakeTask.new 7 | 8 | require 'yard' 9 | YARD::Rake::YardocTask.new(:docs) do |t| 10 | t.files = ['lib/**/*.rb'] 11 | t.options = ['-m', 'markdown', '--no-private', '-r', 'Readme.md', '--title', '<%= camelized %> documentation'] 12 | end 13 | 14 | site = 'doc' 15 | source_branch = 'master' 16 | deploy_branch = 'gh-pages' 17 | 18 | desc "generate and deploy documentation website to github pages" 19 | multitask :pages do 20 | puts ">>> Deploying #{deploy_branch} branch to Github Pages <<<" 21 | require 'git' 22 | repo = Git.open('.') 23 | puts "\n>>> Checking out #{deploy_branch} branch <<<\n" 24 | repo.branch("#{deploy_branch}").checkout 25 | (Dir["*"] - [site]).each { |f| rm_rf(f) } 26 | Dir["#{site}/*"].each {|f| mv(f, "./")} 27 | rm_rf(site) 28 | puts "\n>>> Moving generated site files <<<\n" 29 | Dir["**/*"].each {|f| repo.add(f) } 30 | repo.status.deleted.each {|f, s| repo.remove(f)} 31 | puts "\n>>> Commiting: Site updated at #{Time.now.utc} <<<\n" 32 | message = ENV["MESSAGE"] || "Site updated at #{Time.now.utc}" 33 | repo.commit(message) 34 | puts "\n>>> Pushing generated site to #{deploy_branch} branch <<<\n" 35 | repo.push 36 | puts "\n>>> Github Pages deploy complete <<<\n" 37 | repo.branch("#{source_branch}").checkout 38 | end 39 | 40 | task :doc => [:docs] 41 | 42 | desc "Generate and open class diagram (needs Graphviz installed)" 43 | task :graph do |t| 44 | `bundle exec yard graph -d --full --no-private | dot -Tpng -o graph.png && open graph.png` 45 | end 46 | 47 | task :default => [:spec] 48 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | #gram 2 | 3 | Gram is an internal administration tool for Codegram. 4 | 5 | It is composed of independent components. For now the only available component is Blog. To install and setup Gram, just do the following: 6 | 7 | $ echo "token: MY_CODEGRAM_TOKEN" > ~/.gramrc 8 | $ gem install gram 9 | 10 | ##Blog component 11 | 12 | To publish a blogpost, type this: 13 | 14 | $ gram blog my_blogpost.markdown 15 | 16 | The `my_blogpost.markdown` file should be a regular markdown file with some headers in it, like this: 17 | 18 | --- 19 | title: My blog post title 20 | tagline: Stranger than fiction 21 | --- 22 | 23 | # My awesome header 24 | ## More markdown goodness, etc. 25 | 26 | ##Gem component 27 | 28 | To bootstrap a new gem, type this: 29 | 30 | $ gram gem create my_gem 31 | 32 | By default, the new gem will be using Minitest/Spec & Mocha. If you prefer RSpec: 33 | 34 | $ gram gem create my_gem --rspec 35 | 36 | And if you want to create a Rails extension or anything requiring ActiveRecord, 37 | just use the `--rails` option: 38 | 39 | $ gram gem create my_gem --rails 40 | 41 | This will add the required dependencies and enable the test suite to use 42 | ActiveRecord with in-memory sqlite :) 43 | 44 | ##SSH component 45 | 46 | Put your peers in your `.gramrc`: 47 | 48 | token: 289347287365872whatever 49 | peers: 50 | john: 192.168.1.43 51 | jimmy: 192.168.1.99 52 | 53 | To paste your clipboard's content to your peer's: 54 | 55 | $ gram ssh paste john 56 | 57 | You can also broadcast your clipboard's content to all your peers: 58 | 59 | $ gram ssh broadcast 60 | 61 | ## Copyright 62 | 63 | Copyright (c) 2011 Codegram. See LICENSE for details. 64 | -------------------------------------------------------------------------------- /lib/gram/gem/templates/Rakefile.tt: -------------------------------------------------------------------------------- 1 | require 'bundler' 2 | Bundler::GemHelper.install_tasks 3 | 4 | require 'rake/testtask' 5 | desc "Run <%= underscored %> specs" 6 | Rake::TestTask.new do |t| 7 | t.libs << "spec" 8 | t.test_files = FileList['spec/**/*_spec.rb'] 9 | t.verbose = true 10 | end 11 | 12 | require 'yard' 13 | YARD::Rake::YardocTask.new(:docs) do |t| 14 | t.files = ['lib/**/*.rb'] 15 | t.options = ['-m', 'markdown', '--no-private', '-r', 'Readme.md', '--title', '<%= camelized %> documentation'] 16 | end 17 | 18 | site = 'doc' 19 | source_branch = 'master' 20 | deploy_branch = 'gh-pages' 21 | 22 | desc "generate and deploy documentation website to github pages" 23 | multitask :pages do 24 | puts ">>> Deploying #{deploy_branch} branch to Github Pages <<<" 25 | require 'git' 26 | repo = Git.open('.') 27 | puts "\n>>> Checking out #{deploy_branch} branch <<<\n" 28 | repo.branch("#{deploy_branch}").checkout 29 | (Dir["*"] - [site]).each { |f| rm_rf(f) } 30 | Dir["#{site}/*"].each {|f| mv(f, "./")} 31 | rm_rf(site) 32 | puts "\n>>> Moving generated site files <<<\n" 33 | Dir["**/*"].each {|f| repo.add(f) } 34 | repo.status.deleted.each {|f, s| repo.remove(f)} 35 | puts "\n>>> Commiting: Site updated at #{Time.now.utc} <<<\n" 36 | message = ENV["MESSAGE"] || "Site updated at #{Time.now.utc}" 37 | repo.commit(message) 38 | puts "\n>>> Pushing generated site to #{deploy_branch} branch <<<\n" 39 | repo.push 40 | puts "\n>>> Github Pages deploy complete <<<\n" 41 | repo.branch("#{source_branch}").checkout 42 | end 43 | 44 | task :doc => [:docs] 45 | 46 | desc "Generate and open class diagram (needs Graphviz installed)" 47 | task :graph do |t| 48 | `bundle exec yard graph -d --full --no-private | dot -Tpng -o graph.png && open graph.png` 49 | end 50 | 51 | task :default => [:test] 52 | -------------------------------------------------------------------------------- /lib/gram/ssh.rb: -------------------------------------------------------------------------------- 1 | module Gram 2 | module Ssh 3 | 4 | ACTIONS = { paste: { 5 | description: "Pastes the current clipboard content to your PEER's clipboard.", 6 | arguments: %w(PEER), 7 | }, 8 | broadcast: { 9 | description: "Pastes the current clipboard content to all your peers.", 10 | arguments: %w(), 11 | } 12 | } 13 | 14 | class << self 15 | 16 | def banner 17 | out = "Available actions:\n" 18 | ACTIONS.each_pair do |action, metadata| 19 | out << "\n\t#{action} #{metadata[:arguments].join(' ')}\t\t#{metadata[:description]}" 20 | end 21 | 22 | peers = nil 23 | if File.exists?(File.join(File.expand_path('~'), '.gramrc')) && 24 | peers = YAML.load(File.read(File.join(File.expand_path('~'), '.gramrc')))["peers"] 25 | out << "\nYour peers are currently: #{peers.keys.join(', ')}" 26 | else 27 | out << "\nYou don't have any peers on your ~/.gramrc. Please add some!" 28 | end 29 | 30 | out 31 | end 32 | 33 | # ACTIONS 34 | 35 | def paste(peer) 36 | ip = get_peers[peer] 37 | puts "Gram::SSH posting \"#{`pbpaste`}\" to #{peer} at #{ip}..." 38 | system("pbpaste | ssh #{peer}@#{ip} pbcopy") 39 | puts "Ok!" 40 | end 41 | 42 | def broadcast 43 | get_peers.keys.each do |peer| 44 | paste peer 45 | end 46 | end 47 | 48 | private 49 | 50 | def get_peers 51 | if File.exists?(File.join(File.expand_path('~'), '.gramrc')) && 52 | peers = YAML.load(File.read(File.join(File.expand_path('~'), '.gramrc')))["peers"] 53 | peers 54 | else 55 | puts "Can't get Gram SSH peers. Please create a ~/.gramrc YAML file with some peers." 56 | exit(1) 57 | end 58 | end 59 | 60 | end 61 | end 62 | end 63 | -------------------------------------------------------------------------------- /spec/gram/blog_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | module Gram 4 | describe Blog do 5 | 6 | before do 7 | File.stub(:exists?).and_return true 8 | File.stub(:read).and_return "token: 29384728937598" 9 | end 10 | 11 | describe ".upload" do 12 | it 'parses the file' do 13 | subject::Parser.should_receive(:parse).with("my_post.md") 14 | expect { 15 | subject.upload("my_post.md") 16 | }.to raise_error(RestClient::InternalServerError) 17 | end 18 | it 'sends a post request' do 19 | post = double :post 20 | token = double :token 21 | response = double :response, code: 201, body: 'ok' 22 | subject.stub(:get_token).and_return token 23 | subject::Parser.stub(:parse).with("my_post.md").and_return post 24 | 25 | RestClient.should_receive(:post).with("http://codegram.com/api/posts", token: token, post: post).and_return response 26 | 27 | subject.upload("my_post.md") 28 | end 29 | end 30 | 31 | describe ".download" do 32 | it 'gets the posts' do 33 | RestClient.stub(:get) 34 | JSON.should_receive(:parse).and_return [ { "post" => { 35 | "title" => "My title", 36 | "tagline" => "My tagline", 37 | "cached_slug" => "my-post", 38 | "body" => "#Hello world" 39 | } } ] 40 | 41 | file = double(:file) 42 | File.should_receive(:open).with('my-post.markdown', 'w').and_yield file 43 | file.should_receive(:write).with """ 44 | --- 45 | title: My title 46 | tagline: My tagline 47 | --- 48 | """.strip 49 | file.should_receive(:write).with "\n\n" 50 | file.should_receive(:write).with "#Hello world" 51 | file.should_receive(:write).with "\n" 52 | 53 | subject.download 54 | end 55 | end 56 | 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /lib/gram/blog.rb: -------------------------------------------------------------------------------- 1 | require 'rest-client' 2 | require 'json' 3 | 4 | module Gram 5 | module Blog 6 | 7 | ACTIONS = { upload: { 8 | description: "Uploads the markdown file with filename FILE", 9 | arguments: %w(FILE), 10 | }, 11 | download: { 12 | description: "Downloads all blog posts to the current folder.", 13 | arguments: %w(), 14 | } 15 | } 16 | 17 | class << self 18 | 19 | def banner 20 | out = "Available actions:\n" 21 | ACTIONS.each_pair do |action, metadata| 22 | out << "\n\t#{action} #{metadata[:arguments].join(' ')}\t\t#{metadata[:description]}" 23 | end 24 | out 25 | end 26 | 27 | # ACTIONS 28 | 29 | def upload(file) 30 | raise "File #{file} does not exist." unless File.exists?(file) 31 | puts "Gram::Blog uploading..." 32 | post = Parser.parse(file) 33 | response = RestClient.post("http://codegram.com/api/posts", token: get_token, post: post ) 34 | puts "Response Code: #{response.code}" 35 | puts "Response Body: #{response.body}" 36 | end 37 | 38 | def download 39 | posts = JSON.parse(RestClient.get("http://codegram.com/api/posts?token=#{get_token}")) 40 | posts.each do |post| 41 | post = post["post"] 42 | header = """ 43 | --- 44 | title: #{post["title"]} 45 | tagline: #{post["tagline"]} 46 | --- 47 | 48 | """.strip 49 | puts "Downloading #{post["cached_slug"]}.markdown..." 50 | File.open("#{post["cached_slug"]}.markdown", 'w') do |f| 51 | f.write header 52 | f.write "\n\n" 53 | f.write post["body"] 54 | f.write "\n" 55 | end 56 | end 57 | end 58 | 59 | private 60 | 61 | def get_token 62 | if File.exists?(File.join(File.expand_path('~'), '.gramrc')) 63 | YAML.load(File.read(File.join(File.expand_path('~'), '.gramrc')))["token"] 64 | else 65 | puts "Can't get Gram token. Please create a ~/.gramrc YAML file with a token key." 66 | exit(1) 67 | end 68 | end 69 | 70 | end 71 | end 72 | end 73 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: . 3 | specs: 4 | gram (0.3.0) 5 | activesupport 6 | i18n 7 | rest-client 8 | thor 9 | 10 | GEM 11 | remote: http://rubygems.org/ 12 | specs: 13 | abstract (1.0.0) 14 | actionmailer (3.0.5) 15 | actionpack (= 3.0.5) 16 | mail (~> 2.2.15) 17 | actionpack (3.0.5) 18 | activemodel (= 3.0.5) 19 | activesupport (= 3.0.5) 20 | builder (~> 2.1.2) 21 | erubis (~> 2.6.6) 22 | i18n (~> 0.4) 23 | rack (~> 1.2.1) 24 | rack-mount (~> 0.6.13) 25 | rack-test (~> 0.5.7) 26 | tzinfo (~> 0.3.23) 27 | activemodel (3.0.5) 28 | activesupport (= 3.0.5) 29 | builder (~> 2.1.2) 30 | i18n (~> 0.4) 31 | activerecord (3.0.5) 32 | activemodel (= 3.0.5) 33 | activesupport (= 3.0.5) 34 | arel (~> 2.0.2) 35 | tzinfo (~> 0.3.23) 36 | activeresource (3.0.5) 37 | activemodel (= 3.0.5) 38 | activesupport (= 3.0.5) 39 | activesupport (3.0.5) 40 | arel (2.0.9) 41 | builder (2.1.2) 42 | diff-lcs (1.1.2) 43 | erubis (2.6.6) 44 | abstract (>= 1.0.0) 45 | generator_spec (0.8.2) 46 | rails (~> 3.0) 47 | rspec-rails 48 | i18n (0.5.0) 49 | mail (2.2.15) 50 | activesupport (>= 2.3.6) 51 | i18n (>= 0.4.0) 52 | mime-types (~> 1.16) 53 | treetop (~> 1.4.8) 54 | mime-types (1.16) 55 | polyglot (0.3.1) 56 | rack (1.2.2) 57 | rack-mount (0.6.13) 58 | rack (>= 1.0.0) 59 | rack-test (0.5.7) 60 | rack (>= 1.0) 61 | rails (3.0.5) 62 | actionmailer (= 3.0.5) 63 | actionpack (= 3.0.5) 64 | activerecord (= 3.0.5) 65 | activeresource (= 3.0.5) 66 | activesupport (= 3.0.5) 67 | bundler (~> 1.0) 68 | railties (= 3.0.5) 69 | railties (3.0.5) 70 | actionpack (= 3.0.5) 71 | activesupport (= 3.0.5) 72 | rake (>= 0.8.7) 73 | thor (~> 0.14.4) 74 | rake (0.8.7) 75 | rest-client (1.6.1) 76 | mime-types (>= 1.16) 77 | rspec (2.5.0) 78 | rspec-core (~> 2.5.0) 79 | rspec-expectations (~> 2.5.0) 80 | rspec-mocks (~> 2.5.0) 81 | rspec-core (2.5.1) 82 | rspec-expectations (2.5.0) 83 | diff-lcs (~> 1.1.2) 84 | rspec-mocks (2.5.0) 85 | rspec-rails (2.5.0) 86 | actionpack (~> 3.0) 87 | activesupport (~> 3.0) 88 | railties (~> 3.0) 89 | rspec (~> 2.5.0) 90 | thor (0.14.6) 91 | treetop (1.4.9) 92 | polyglot (>= 0.3.1) 93 | tzinfo (0.3.25) 94 | 95 | PLATFORMS 96 | ruby 97 | 98 | DEPENDENCIES 99 | activemodel 100 | bundler (~> 1.0.7) 101 | generator_spec (~> 0.8.1) 102 | gram! 103 | rspec (~> 2.5.0) 104 | -------------------------------------------------------------------------------- /lib/gram/gem/generator.rb: -------------------------------------------------------------------------------- 1 | require 'thor' 2 | require 'active_support/inflector' 3 | 4 | module Gram 5 | module Gem 6 | class Generator < Thor 7 | include Thor::Actions 8 | 9 | source_root File.dirname(__FILE__) 10 | 11 | no_tasks do 12 | def generate(name, options) 13 | @rails = true if options.include?("--rails") 14 | @rspec = true if options.include?("--rspec") 15 | 16 | @underscored = name.underscore 17 | @camelized = name.camelize 18 | 19 | run "bundle gem #{@underscored}" 20 | 21 | remove_file("#{@underscored}/Rakefile") 22 | if rspec 23 | template('templates/Rakefile_rspec.tt', "#{@underscored}/Rakefile") 24 | else 25 | template('templates/Rakefile.tt', "#{@underscored}/Rakefile") 26 | end 27 | 28 | remove_file("#{@underscored}/.gitignore") 29 | template('templates/gitignore.tt', "#{@underscored}/.gitignore") 30 | 31 | template('templates/Readme.tt', "#{@underscored}/Readme.md") 32 | template('templates/rvmrc.tt', "#{@underscored}/.rvmrc") 33 | 34 | empty_directory "#{@underscored}/spec" 35 | 36 | if rspec 37 | template('templates/spec/rspec_helper.tt', "#{@underscored}/spec/spec_helper.rb") 38 | else 39 | template('templates/spec/minispec_helper.tt', "#{@underscored}/spec/spec_helper.rb") 40 | end 41 | 42 | inject_into_file "#{@underscored}/#{@underscored}.gemspec", :after => "s.rubyforge_project = \"#{@underscored}\"" do 43 | runtime_dependencies = [] 44 | runtime_dependencies << " s.add_runtime_dependency 'activerecord', '~> 3.0.5'" if rails 45 | 46 | development_dependencies = [] 47 | development_dependencies << " s.add_runtime_dependency 'sqlite3'" if rails 48 | if rspec 49 | development_dependencies << " s.add_development_dependency 'rspec', '~> 2.5.0'" 50 | else 51 | development_dependencies << " s.add_development_dependency 'minitest'" 52 | end 53 | development_dependencies << " s.add_development_dependency 'mocha'" unless rspec 54 | development_dependencies += [ 55 | " s.add_development_dependency 'yard'", 56 | " s.add_development_dependency 'bluecloth'" ] 57 | 58 | "\n\n" + runtime_dependencies.join("\n") << "\n\n"<< development_dependencies.join("\n") 59 | end 60 | end 61 | end 62 | 63 | private 64 | 65 | def underscored 66 | @underscored 67 | end 68 | 69 | def camelized 70 | @camelized 71 | end 72 | 73 | def rails 74 | @rails 75 | end 76 | 77 | def rspec 78 | @rspec 79 | end 80 | end 81 | end 82 | end 83 | -------------------------------------------------------------------------------- /spec/gram/gem/generator_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | require 'fileutils' 3 | 4 | require 'action_view' 5 | require 'action_controller' 6 | ActionView::Template::Handlers::ERB::ENCODING_FLAG = ActionView::ENCODING_FLAG 7 | 8 | require 'generator_spec/test_case' 9 | 10 | module Gram 11 | module Gem 12 | describe Generator do 13 | include GeneratorSpec::TestCase 14 | destination File.expand_path('../../../../tmp', __FILE__) 15 | tests Generator 16 | 17 | before(:each) do 18 | prepare_destination 19 | end 20 | 21 | after(:each) do 22 | FileUtils.rm_rf File.expand_path('../../../../tmp', __FILE__) 23 | end 24 | 25 | it 'is a Thor generator' do 26 | Generator.ancestors.should include(Thor) 27 | end 28 | 29 | describe ".generate" do 30 | it 'creates a new gem' do 31 | FileUtils.chdir File.expand_path('../../../../tmp', __FILE__) 32 | Generator.new.generate('my_gem', []) 33 | destination_root.should have_structure { 34 | directory "my_gem" do 35 | file "Gemfile" 36 | file "Rakefile" 37 | file ".gitignore" 38 | file ".rvmrc" 39 | file "Readme.md" 40 | file "my_gem.gemspec" do 41 | contains "minitest" 42 | contains "mocha" 43 | contains "yard" 44 | contains "bluecloth" 45 | end 46 | directory "lib" do 47 | file "my_gem.rb" 48 | directory "my_gem" do 49 | file "version.rb" 50 | end 51 | end 52 | directory "spec" do 53 | file "spec_helper.rb" do 54 | contains "minitest/spec" 55 | end 56 | end 57 | end 58 | } 59 | end 60 | end 61 | 62 | context 'with --rails' do 63 | it 'creates a new rails-ready gem' do 64 | FileUtils.chdir File.expand_path('../../../../tmp', __FILE__) 65 | Generator.new.generate('my_gem', ['--rails']) 66 | destination_root.should have_structure { 67 | directory "my_gem" do 68 | file "Gemfile" 69 | file "Rakefile" 70 | file ".gitignore" 71 | file ".rvmrc" 72 | file "Readme.md" 73 | file "my_gem.gemspec" do 74 | contains "activerecord" 75 | contains "sqlite3" 76 | 77 | contains "minitest" 78 | contains "mocha" 79 | contains "bluecloth" 80 | end 81 | directory "lib" do 82 | file "my_gem.rb" 83 | directory "my_gem" do 84 | file "version.rb" 85 | end 86 | end 87 | directory "spec" do 88 | file "spec_helper.rb" do 89 | contains "minitest/spec" 90 | contains "ActiveRecord" 91 | end 92 | end 93 | end 94 | } 95 | end 96 | end 97 | 98 | context 'with --rspec' do 99 | it 'creates a new rspec-ready gem' do 100 | FileUtils.chdir File.expand_path('../../../../tmp', __FILE__) 101 | Generator.new.generate('my_gem', ['--rspec']) 102 | destination_root.should have_structure { 103 | directory "my_gem" do 104 | file "Gemfile" 105 | file "Rakefile" 106 | file ".gitignore" 107 | file ".rvmrc" 108 | file "Readme.md" 109 | file "my_gem.gemspec" do 110 | contains "rspec" 111 | contains "yard" 112 | contains "bluecloth" 113 | end 114 | directory "lib" do 115 | file "my_gem.rb" 116 | directory "my_gem" do 117 | file "version.rb" 118 | end 119 | end 120 | directory "spec" do 121 | file "spec_helper.rb" do 122 | contains "rspec" 123 | end 124 | end 125 | end 126 | } 127 | end 128 | end 129 | 130 | end 131 | end 132 | end 133 | --------------------------------------------------------------------------------