em_apn_manager 0.0.2 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +26 -10
- data/VERSION +1 -1
- data/bin/em_apn_manager +2 -0
- data/em_apn_manager.gemspec +32 -2
- data/lib/em_apn_manager.rb +2 -1
- data/lib/em_apn_manager/cli.rb +53 -18
- data/lib/em_apn_manager/client.rb +2 -2
- data/lib/em_apn_manager/generators/templates/em_apn_manager.yml +3 -13
- data/lib/em_apn_manager/manager.rb +5 -3
- metadata +142 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 7488d9d6b4d3ffca37840e1efd52dd3bc555c4cb
         | 
| 4 | 
            +
              data.tar.gz: 39053f313b6bdd6bb04469d2804c650ec0ca549f
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 4a9906727741db1583fe89b897c7876944a31ce5b0fa231c955195371e6f624ff633b3c606868aa47204a379933bf5ef6c3038952516ad2256e38a44d795786c
         | 
| 7 | 
            +
              data.tar.gz: a0e2b04ee2a8d50f83d10931ddd6b94f9ac08051905ea1edb93a6c25a27c48ae412cf4177bf260d65908d16777f540ee24c28eaef06a630d0cf156fe040a3ca3
         | 
    
        data/Gemfile.lock
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -3,24 +3,40 @@ EventMachine APN Manager | |
| 3 3 |  | 
| 4 4 | 
             
            EventMachine APN Connection Manager, The purpose is to support multiple cert and multiple application with one process.
         | 
| 5 5 |  | 
| 6 | 
            -
            Steps  | 
| 7 | 
            -
             | 
| 8 | 
            -
             | 
| 9 | 
            -
             | 
| 10 | 
            -
             | 
| 6 | 
            +
            Steps for running with *Rails*:
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            1. Add `gem 'em_apn_manager', git: 'git@github.com:hlxwell/em_apn_manager.git'` to *Gemfile*.
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            2. Run `bundle exec rails g event_machine:apn_manager:install` to generate `config/em_apn_manager.yml` file.
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            3. Run `bundle exec em_apn_manager server -e development`.
         | 
| 13 | 
            +
             | 
| 14 | 
            +
             | 
| 15 | 
            +
            Steps for running `Standalone`:
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            1. Run `gem install em_apn_manager`
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            2. Run `em_apn_manager server --redis-host 127.0.0.1 --redis-port 6379` or `em_apn_manager server --config CONFIG_FILE_PATH`
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            Put below line to your code for sending push notification:
         | 
| 22 | 
            +
             | 
| 11 23 | 
             
            `EM::ApnManager.push_notification({
         | 
| 12 | 
            -
               | 
| 24 | 
            +
              env: CERT_ENVIRONMENT,
         | 
| 25 | 
            +
              cert: PEM_CERT_TEXT_CONTENT,
         | 
| 13 26 | 
             
              token: DEVICE_TOKEN,
         | 
| 14 27 | 
             
              message: YOUR_MESSAGE
         | 
| 15 28 | 
             
            })`
         | 
| 16 29 |  | 
| 30 | 
            +
            Running server in background:
         | 
| 31 | 
            +
             | 
| 32 | 
            +
            `em_apn_manager server --daemon`
         | 
| 17 33 |  | 
| 18 34 | 
             
            Generate pem from p12
         | 
| 19 35 | 
             
            ==================
         | 
| 36 | 
            +
             | 
| 37 | 
            +
            This is how you get `p12` file:
         | 
| 38 | 
            +
            http://docs.urbanairship.com/build/ios.html#set-up-your-application-with-apple
         | 
| 39 | 
            +
             | 
| 20 40 | 
             
            You have to convert p12 format to pem format by below command line.
         | 
| 21 41 | 
             
            `openssl pkcs12 -in cert.p12 -out cert.pem -nodes -clcerts`
         | 
| 22 42 |  | 
| 23 | 
            -
             | 
| 24 | 
            -
            TO DOs
         | 
| 25 | 
            -
            ==================
         | 
| 26 | 
            -
            1. Implement running `bundle exec em_apn_manager -e development` in background, support `-daemon` and `-pid_file`
         | 
    
        data/VERSION
    CHANGED
    
    | @@ -1 +1 @@ | |
| 1 | 
            -
            0.0 | 
| 1 | 
            +
            0.1.0
         | 
    
        data/bin/em_apn_manager
    CHANGED
    
    
    
        data/em_apn_manager.gemspec
    CHANGED
    
    | @@ -5,11 +5,11 @@ | |
| 5 5 |  | 
| 6 6 | 
             
            Gem::Specification.new do |s|
         | 
| 7 7 | 
             
              s.name = "em_apn_manager"
         | 
| 8 | 
            -
              s.version = "0.0 | 
| 8 | 
            +
              s.version = "0.1.0"
         | 
| 9 9 |  | 
| 10 10 | 
             
              s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
         | 
| 11 11 | 
             
              s.authors = ["Michael He"]
         | 
| 12 | 
            -
              s.date = "2013-07- | 
| 12 | 
            +
              s.date = "2013-07-17"
         | 
| 13 13 | 
             
              s.description = "EventMachine multiple APNs connections Management Solution. You can use multiple cert and connection to apple's APNs server."
         | 
| 14 14 | 
             
              s.email = "m.he@skillupjapan.co.jp"
         | 
| 15 15 | 
             
              s.executables = ["em_apn_manager"]
         | 
| @@ -99,6 +99,16 @@ Gem::Specification.new do |s| | |
| 99 99 | 
             
                  s.add_development_dependency(%q<rdoc>, [">= 0"])
         | 
| 100 100 | 
             
                  s.add_development_dependency(%q<bundler>, [">= 0"])
         | 
| 101 101 | 
             
                  s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
         | 
| 102 | 
            +
                  s.add_development_dependency(%q<rspec>, ["~> 2.6.0"])
         | 
| 103 | 
            +
                  s.add_development_dependency(%q<shoulda>, [">= 0"])
         | 
| 104 | 
            +
                  s.add_development_dependency(%q<rdoc>, [">= 0"])
         | 
| 105 | 
            +
                  s.add_development_dependency(%q<bundler>, [">= 0"])
         | 
| 106 | 
            +
                  s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
         | 
| 107 | 
            +
                  s.add_development_dependency(%q<rspec>, ["~> 2.6.0"])
         | 
| 108 | 
            +
                  s.add_development_dependency(%q<shoulda>, [">= 0"])
         | 
| 109 | 
            +
                  s.add_development_dependency(%q<rdoc>, [">= 0"])
         | 
| 110 | 
            +
                  s.add_development_dependency(%q<bundler>, [">= 0"])
         | 
| 111 | 
            +
                  s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
         | 
| 102 112 | 
             
                  s.add_runtime_dependency(%q<thor>, ["~> 0.16"])
         | 
| 103 113 | 
             
                  s.add_runtime_dependency(%q<eventmachine>, [">= 1.0.0"])
         | 
| 104 114 | 
             
                  s.add_runtime_dependency(%q<yajl-ruby>, [">= 0.8.2"])
         | 
| @@ -157,6 +167,16 @@ Gem::Specification.new do |s| | |
| 157 167 | 
             
                  s.add_dependency(%q<rdoc>, [">= 0"])
         | 
| 158 168 | 
             
                  s.add_dependency(%q<bundler>, [">= 0"])
         | 
| 159 169 | 
             
                  s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
         | 
| 170 | 
            +
                  s.add_dependency(%q<rspec>, ["~> 2.6.0"])
         | 
| 171 | 
            +
                  s.add_dependency(%q<shoulda>, [">= 0"])
         | 
| 172 | 
            +
                  s.add_dependency(%q<rdoc>, [">= 0"])
         | 
| 173 | 
            +
                  s.add_dependency(%q<bundler>, [">= 0"])
         | 
| 174 | 
            +
                  s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
         | 
| 175 | 
            +
                  s.add_dependency(%q<rspec>, ["~> 2.6.0"])
         | 
| 176 | 
            +
                  s.add_dependency(%q<shoulda>, [">= 0"])
         | 
| 177 | 
            +
                  s.add_dependency(%q<rdoc>, [">= 0"])
         | 
| 178 | 
            +
                  s.add_dependency(%q<bundler>, [">= 0"])
         | 
| 179 | 
            +
                  s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
         | 
| 160 180 | 
             
                  s.add_dependency(%q<thor>, ["~> 0.16"])
         | 
| 161 181 | 
             
                  s.add_dependency(%q<eventmachine>, [">= 1.0.0"])
         | 
| 162 182 | 
             
                  s.add_dependency(%q<yajl-ruby>, [">= 0.8.2"])
         | 
| @@ -216,6 +236,16 @@ Gem::Specification.new do |s| | |
| 216 236 | 
             
                s.add_dependency(%q<rdoc>, [">= 0"])
         | 
| 217 237 | 
             
                s.add_dependency(%q<bundler>, [">= 0"])
         | 
| 218 238 | 
             
                s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
         | 
| 239 | 
            +
                s.add_dependency(%q<rspec>, ["~> 2.6.0"])
         | 
| 240 | 
            +
                s.add_dependency(%q<shoulda>, [">= 0"])
         | 
| 241 | 
            +
                s.add_dependency(%q<rdoc>, [">= 0"])
         | 
| 242 | 
            +
                s.add_dependency(%q<bundler>, [">= 0"])
         | 
| 243 | 
            +
                s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
         | 
| 244 | 
            +
                s.add_dependency(%q<rspec>, ["~> 2.6.0"])
         | 
| 245 | 
            +
                s.add_dependency(%q<shoulda>, [">= 0"])
         | 
| 246 | 
            +
                s.add_dependency(%q<rdoc>, [">= 0"])
         | 
| 247 | 
            +
                s.add_dependency(%q<bundler>, [">= 0"])
         | 
| 248 | 
            +
                s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
         | 
| 219 249 | 
             
                s.add_dependency(%q<thor>, ["~> 0.16"])
         | 
| 220 250 | 
             
                s.add_dependency(%q<eventmachine>, [">= 1.0.0"])
         | 
| 221 251 | 
             
                s.add_dependency(%q<yajl-ruby>, [">= 0.8.2"])
         | 
    
        data/lib/em_apn_manager.rb
    CHANGED
    
    | @@ -13,10 +13,11 @@ module EventMachine | |
| 13 13 | 
             
                def push_notification options = {}
         | 
| 14 14 | 
             
                  # FIXME Check options
         | 
| 15 15 | 
             
                  $apn_manager_redis.publish "push-notification", {
         | 
| 16 | 
            +
                    env: options[:env],
         | 
| 16 17 | 
             
                    cert: options[:cert],
         | 
| 17 18 | 
             
                    token: options[:token],
         | 
| 18 19 | 
             
                    message: options[:message]
         | 
| 19 20 | 
             
                  }.to_json
         | 
| 20 21 | 
             
                end
         | 
| 21 22 | 
             
              end
         | 
| 22 | 
            -
            end
         | 
| 23 | 
            +
            end
         | 
    
        data/lib/em_apn_manager/cli.rb
    CHANGED
    
    | @@ -16,34 +16,48 @@ $apn_manager_redis = nil | |
| 16 16 | 
             
            module EventMachine
         | 
| 17 17 | 
             
              module ApnManager
         | 
| 18 18 | 
             
                class CLI < Thor
         | 
| 19 | 
            -
                  class_option :config, | 
| 20 | 
            -
                  class_option :environment, | 
| 19 | 
            +
                  class_option :config,       :aliases => ["-c"], :type => :string
         | 
| 20 | 
            +
                  class_option :environment,  :aliases => ["-e"], :type => :string
         | 
| 21 | 
            +
                  class_option :redis,        :aliases => ["-r"], :type => :string
         | 
| 21 22 |  | 
| 23 | 
            +
                  ### 3 ways to specify the redis
         | 
| 24 | 
            +
                  # 1. config yml file
         | 
| 25 | 
            +
                  # 2. pass redis-url is 'redis://username:password@host:port/database'
         | 
| 26 | 
            +
                  # like `redis://test:test@localhost:6379/em_apn_manager`
         | 
| 27 | 
            +
                  #
         | 
| 22 28 | 
             
                  def initialize(args = [], opts = [], config = {})
         | 
| 23 29 | 
             
                    super(args, opts, config)
         | 
| 24 30 |  | 
| 25 | 
            -
                     | 
| 26 | 
            -
                     | 
| 27 | 
            -
             | 
| 28 | 
            -
                       | 
| 29 | 
            -
             | 
| 30 | 
            -
             | 
| 31 | 
            -
             | 
| 31 | 
            +
                    redis_config = options[:redis]
         | 
| 32 | 
            +
                    if redis_config.nil?
         | 
| 33 | 
            +
                      # read the environment var.
         | 
| 34 | 
            +
                      @environment = ENV["RAILS_ENV"] || "development"
         | 
| 35 | 
            +
                      @environment = options[:environment] if %w{test development production}.include? options[:environment]
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                      # Read config option, or use default config yml
         | 
| 38 | 
            +
                      config_path = options[:config] || File.join(".", "config", "em_apn_manager.yml")
         | 
| 39 | 
            +
                      if config_path && File.exists?(config_path)
         | 
| 40 | 
            +
                        EM::ApnManager.config = Thor::CoreExt::HashWithIndifferentAccess.new(YAML.load_file(config_path))
         | 
| 41 | 
            +
                        redis_config = EM::ApnManager.config[@environment]
         | 
| 42 | 
            +
                      end
         | 
| 32 43 |  | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 35 | 
            -
                     | 
| 44 | 
            +
                      # default redis
         | 
| 45 | 
            +
                      redis_config ||= "redis://localhost:6379/em_apn_manager"
         | 
| 46 | 
            +
                    end
         | 
| 36 47 |  | 
| 37 48 | 
             
                    # create redis connection
         | 
| 38 | 
            -
                    $apn_manager_redis = Redis.new  | 
| 49 | 
            +
                    $apn_manager_redis = Redis.new url: redis_config
         | 
| 39 50 | 
             
                  end
         | 
| 40 51 |  | 
| 41 52 | 
             
                  desc "server", "Start manager server."
         | 
| 42 | 
            -
                   | 
| 43 | 
            -
                   | 
| 53 | 
            +
                  option :daemon,       :aliases => ["-d"], :type => :boolean
         | 
| 54 | 
            +
                  option :pid_file,     :aliases => ["-p"], :type => :string
         | 
| 44 55 | 
             
                  def server
         | 
| 56 | 
            +
                    daemonize if options[:daemon]
         | 
| 57 | 
            +
                    write_pid_file(options[:pid_file]) if options[:pid_file]
         | 
| 58 | 
            +
             | 
| 45 59 | 
             
                    EM::ApnManager.logger.info("Starting APN Manager")
         | 
| 46 | 
            -
                    EM.run { EM::ApnManager::Manager.run  | 
| 60 | 
            +
                    EM.run { EM::ApnManager::Manager.run }
         | 
| 47 61 | 
             
                  end
         | 
| 48 62 |  | 
| 49 63 | 
             
                  ### For Testing ##################################################
         | 
| @@ -52,8 +66,9 @@ module EventMachine | |
| 52 66 | 
             
                  def push_test_message
         | 
| 53 67 | 
             
                    10.times do |i|
         | 
| 54 68 | 
             
                      EM::ApnManager.push_notification({
         | 
| 55 | 
            -
                         | 
| 56 | 
            -
                         | 
| 69 | 
            +
                        env: 'test',
         | 
| 70 | 
            +
                        cert: File.read(ENV["APN_CERT"]), # test cert
         | 
| 71 | 
            +
                        token: ["0F93C49EAAF3544B5218D2BAE893608C515F69B445279AB2B17511C37046C52B", "D42A6795D0C6C0E5F3CC762F905C3654D2A07E72D64CDEC1E2F74AC43C4CC440"].sample,
         | 
| 57 72 | 
             
                        message: "Hahahaha I am going to spam you. #{i}-#{rand * 100}"
         | 
| 58 73 | 
             
                      })
         | 
| 59 74 | 
             
                    end
         | 
| @@ -64,6 +79,26 @@ module EventMachine | |
| 64 79 | 
             
                    EM::ApnManager.logger.info("Starting Mock APN Server")
         | 
| 65 80 | 
             
                    EM.run { EM.start_server("127.0.0.1", 2195, EM::ApnManager::ApnServer) }
         | 
| 66 81 | 
             
                  end
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                  private
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                  # Daemonize process (ruby >= 1.9 only)
         | 
| 86 | 
            +
                  # @return [void] Ruby ~>1.8
         | 
| 87 | 
            +
                  # @return [0] Ruby 1.9+ (see Process::daemon)
         | 
| 88 | 
            +
                  # @raise [Errno] on failure
         | 
| 89 | 
            +
                  def daemonize
         | 
| 90 | 
            +
                    if Process.respond_to?(:daemon)
         | 
| 91 | 
            +
                      Process.daemon(true, true)
         | 
| 92 | 
            +
                    else
         | 
| 93 | 
            +
                      Kernel.warn "Running process as daemon requires ruby >= 1.9"
         | 
| 94 | 
            +
                    end
         | 
| 95 | 
            +
                  end
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                  # Save worker's pid to file
         | 
| 98 | 
            +
                  # @return [void]
         | 
| 99 | 
            +
                  def write_pid_file(path = nil)
         | 
| 100 | 
            +
                    File.open(path, 'w'){ |f| f << Process.pid } if path
         | 
| 101 | 
            +
                  end
         | 
| 67 102 | 
             
                end
         | 
| 68 103 | 
             
              end
         | 
| 69 104 | 
             
            end
         | 
| @@ -20,10 +20,10 @@ module EventMachine | |
| 20 20 | 
             
                  end
         | 
| 21 21 |  | 
| 22 22 | 
             
                  def initialize(options = {})
         | 
| 23 | 
            -
                    @cert = options[:cert] | 
| 23 | 
            +
                    @cert = options[:cert]
         | 
| 24 24 | 
             
                    @port = options[:port] || PORT
         | 
| 25 25 | 
             
                    @environment = options[:env]
         | 
| 26 | 
            -
                    @gateway = options[:gateway] | 
| 26 | 
            +
                    @gateway = options[:gateway]
         | 
| 27 27 | 
             
                    @gateway ||=  case @environment
         | 
| 28 28 | 
             
                                  when "test"
         | 
| 29 29 | 
             
                                    TEST_GATEWAY
         | 
| @@ -1,13 +1,3 @@ | |
| 1 | 
            -
            production:
         | 
| 2 | 
            -
             | 
| 3 | 
            -
             | 
| 4 | 
            -
              db: YOUR_PRODUCTION_REDIS
         | 
| 5 | 
            -
              password: PASSWORD
         | 
| 6 | 
            -
             | 
| 7 | 
            -
            development:
         | 
| 8 | 
            -
              host: localhost
         | 
| 9 | 
            -
              port: 6379
         | 
| 10 | 
            -
             | 
| 11 | 
            -
            test:
         | 
| 12 | 
            -
              host: localhost
         | 
| 13 | 
            -
              port: 6379
         | 
| 1 | 
            +
            production: redis://username:password@host:port/database
         | 
| 2 | 
            +
            development: redis://localhost:6379/resque
         | 
| 3 | 
            +
            test: redis://localhost:6379/resque
         | 
| @@ -24,15 +24,17 @@ module EventMachine | |
| 24 24 |  | 
| 25 25 | 
             
                    ### launch a new connect to apple when detected any pushs.
         | 
| 26 26 | 
             
                    @redis.pubsub.subscribe('push-notification') do |msg|
         | 
| 27 | 
            -
                      msg_hash = Yajl::Parser.parse(msg) # might be some wrong json
         | 
| 27 | 
            +
                      msg_hash = Yajl::Parser.parse(msg) # FIXME might be some wrong json
         | 
| 28 | 
            +
             | 
| 28 29 | 
             
                      # save the cert to local first, since the start_tls read from file.
         | 
| 29 30 | 
             
                      cert_filename = save_cert_to_file msg_hash["cert"]
         | 
| 31 | 
            +
             | 
| 30 32 | 
             
                      # cert filename is a key for connection pool
         | 
| 31 33 | 
             
                      client = $connection_pool[cert_filename]
         | 
| 32 34 |  | 
| 33 35 | 
             
                      ### Create client connection if doesn't exist in pool.
         | 
| 34 36 | 
             
                      if client.nil?
         | 
| 35 | 
            -
                        client = EM::ApnManager::Client.new(options.merge!({cert: cert_filename}))
         | 
| 37 | 
            +
                        client = EM::ApnManager::Client.new(options.merge!({env: msg_hash["env"], cert: cert_filename}))
         | 
| 36 38 | 
             
                        # Store the connection to pool
         | 
| 37 39 | 
             
                        $connection_pool[cert_filename] = client
         | 
| 38 40 | 
             
                      end
         | 
| @@ -54,8 +56,8 @@ module EventMachine | |
| 54 56 |  | 
| 55 57 | 
             
                  private
         | 
| 56 58 |  | 
| 59 | 
            +
                  # NOTICE should not put the 'certs' folder to a downloadable place.
         | 
| 57 60 | 
             
                  def save_cert_to_file cert_content
         | 
| 58 | 
            -
                    # TODO, should store Rails.root/tmp/certs and this folder should be protected.
         | 
| 59 61 | 
             
                    FileUtils.mkdir_p "certs"
         | 
| 60 62 | 
             
                    filename = Base64.encode64(cert_content)[0..50]
         | 
| 61 63 | 
             
                    filename = File.join "certs", filename
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: em_apn_manager
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.0 | 
| 4 | 
            +
              version: 0.1.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Michael He
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2013-07- | 
| 11 | 
            +
            date: 2013-07-17 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: em_apn_manager
         | 
| @@ -724,6 +724,146 @@ dependencies: | |
| 724 724 | 
             
                - - ~>
         | 
| 725 725 | 
             
                  - !ruby/object:Gem::Version
         | 
| 726 726 | 
             
                    version: 1.8.4
         | 
| 727 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 728 | 
            +
              name: rspec
         | 
| 729 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 730 | 
            +
                requirements:
         | 
| 731 | 
            +
                - - ~>
         | 
| 732 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 733 | 
            +
                    version: 2.6.0
         | 
| 734 | 
            +
              type: :development
         | 
| 735 | 
            +
              prerelease: false
         | 
| 736 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 737 | 
            +
                requirements:
         | 
| 738 | 
            +
                - - ~>
         | 
| 739 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 740 | 
            +
                    version: 2.6.0
         | 
| 741 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 742 | 
            +
              name: shoulda
         | 
| 743 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 744 | 
            +
                requirements:
         | 
| 745 | 
            +
                - - '>='
         | 
| 746 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 747 | 
            +
                    version: '0'
         | 
| 748 | 
            +
              type: :development
         | 
| 749 | 
            +
              prerelease: false
         | 
| 750 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 751 | 
            +
                requirements:
         | 
| 752 | 
            +
                - - '>='
         | 
| 753 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 754 | 
            +
                    version: '0'
         | 
| 755 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 756 | 
            +
              name: rdoc
         | 
| 757 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 758 | 
            +
                requirements:
         | 
| 759 | 
            +
                - - '>='
         | 
| 760 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 761 | 
            +
                    version: '0'
         | 
| 762 | 
            +
              type: :development
         | 
| 763 | 
            +
              prerelease: false
         | 
| 764 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 765 | 
            +
                requirements:
         | 
| 766 | 
            +
                - - '>='
         | 
| 767 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 768 | 
            +
                    version: '0'
         | 
| 769 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 770 | 
            +
              name: bundler
         | 
| 771 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 772 | 
            +
                requirements:
         | 
| 773 | 
            +
                - - '>='
         | 
| 774 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 775 | 
            +
                    version: '0'
         | 
| 776 | 
            +
              type: :development
         | 
| 777 | 
            +
              prerelease: false
         | 
| 778 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 779 | 
            +
                requirements:
         | 
| 780 | 
            +
                - - '>='
         | 
| 781 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 782 | 
            +
                    version: '0'
         | 
| 783 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 784 | 
            +
              name: jeweler
         | 
| 785 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 786 | 
            +
                requirements:
         | 
| 787 | 
            +
                - - ~>
         | 
| 788 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 789 | 
            +
                    version: 1.8.4
         | 
| 790 | 
            +
              type: :development
         | 
| 791 | 
            +
              prerelease: false
         | 
| 792 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 793 | 
            +
                requirements:
         | 
| 794 | 
            +
                - - ~>
         | 
| 795 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 796 | 
            +
                    version: 1.8.4
         | 
| 797 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 798 | 
            +
              name: rspec
         | 
| 799 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 800 | 
            +
                requirements:
         | 
| 801 | 
            +
                - - ~>
         | 
| 802 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 803 | 
            +
                    version: 2.6.0
         | 
| 804 | 
            +
              type: :development
         | 
| 805 | 
            +
              prerelease: false
         | 
| 806 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 807 | 
            +
                requirements:
         | 
| 808 | 
            +
                - - ~>
         | 
| 809 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 810 | 
            +
                    version: 2.6.0
         | 
| 811 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 812 | 
            +
              name: shoulda
         | 
| 813 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 814 | 
            +
                requirements:
         | 
| 815 | 
            +
                - - '>='
         | 
| 816 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 817 | 
            +
                    version: '0'
         | 
| 818 | 
            +
              type: :development
         | 
| 819 | 
            +
              prerelease: false
         | 
| 820 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 821 | 
            +
                requirements:
         | 
| 822 | 
            +
                - - '>='
         | 
| 823 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 824 | 
            +
                    version: '0'
         | 
| 825 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 826 | 
            +
              name: rdoc
         | 
| 827 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 828 | 
            +
                requirements:
         | 
| 829 | 
            +
                - - '>='
         | 
| 830 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 831 | 
            +
                    version: '0'
         | 
| 832 | 
            +
              type: :development
         | 
| 833 | 
            +
              prerelease: false
         | 
| 834 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 835 | 
            +
                requirements:
         | 
| 836 | 
            +
                - - '>='
         | 
| 837 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 838 | 
            +
                    version: '0'
         | 
| 839 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 840 | 
            +
              name: bundler
         | 
| 841 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 842 | 
            +
                requirements:
         | 
| 843 | 
            +
                - - '>='
         | 
| 844 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 845 | 
            +
                    version: '0'
         | 
| 846 | 
            +
              type: :development
         | 
| 847 | 
            +
              prerelease: false
         | 
| 848 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 849 | 
            +
                requirements:
         | 
| 850 | 
            +
                - - '>='
         | 
| 851 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 852 | 
            +
                    version: '0'
         | 
| 853 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 854 | 
            +
              name: jeweler
         | 
| 855 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 856 | 
            +
                requirements:
         | 
| 857 | 
            +
                - - ~>
         | 
| 858 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 859 | 
            +
                    version: 1.8.4
         | 
| 860 | 
            +
              type: :development
         | 
| 861 | 
            +
              prerelease: false
         | 
| 862 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 863 | 
            +
                requirements:
         | 
| 864 | 
            +
                - - ~>
         | 
| 865 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 866 | 
            +
                    version: 1.8.4
         | 
| 727 867 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 728 868 | 
             
              name: thor
         | 
| 729 869 | 
             
              requirement: !ruby/object:Gem::Requirement
         |