{"action":"created","comment":{"url":"https://api.github.com/repos/elasticsearch/logstash/pulls/comments/24697414","id":24697414,"diff_hunk":"@@ -0,0 +1,173 @@\n+module LogStash\n+\n+  class GemfileError < StandardError; end\n+\n+  class Gemfile\n+    attr_accessor :gemset\n+\n+    HEADER = \\\n+      \"# This is a Logstash generated Gemfile.\\n\" + \\\n+      \"# If you modify this file manually all comments and formatting will be lost.\\n\\n\"\n+\n+    # @params io [IO] any IO object that supports read, write, truncate, rewind\n+    def initialize(io)\n+      @io = io\n+      @gemset = nil\n+    end\n+\n+    def load\n+      @gemset ||= Dsl.parse(@io.read)\n+      self\n+    end\n+\n+    def save\n+      raise(GemfileError, \"a Gemfile must first be loaded\") unless @gemset\n+      @io.truncate(0)\n+      @io.rewind\n+      @io.write(HEADER)\n+      @io.write(@gemset.to_s)\n+      @io.flush\n+    end\n+\n+    def find(name)\n+      @gemset.find_gem(name)\n+    end\n+\n+    # @param name [String] gem name\n+    # @param *requirements params following name use the same notation as the Gemfile gem DSL statement\n+    # @raise GemfileError if gem already exists in Gemfile\n+    def add(name, *requirements)\n+      @gemset.add_gem(Gem.parse(name, *requirements))\n+    end\n+\n+    # update existing or add new\n+    # @param name [String] gem name\n+    # @param *requirements params following name use the same notation as the Gemfile gem DSL statement\n+    def update(name, *requirements)\n+      @gemset.update_gem(Gem.parse(name, *requirements))\n+    end\n+\n+    # @return [Gem] removed gem or nil if not found\n+    def remove(name)\n+      @gemset.remove_gem(name)\n+    end\n+  end\n+\n+  class Gemset\n+    attr_accessor :sources, :gems, :gemspec\n+\n+    def initialize\n+      @sources = []      # list of urls\n+      @gems = []         # list of Gem class\n+      @gems_by_name = {} # hash of name => Gem\n+      @gemspec = {}      # gemspec is a options hash\n+    end\n+\n+    def to_s\n+      [sources_to_s, gemspec_to_s, gems_to_s].compact.join(\"\\n\") + \"\\n\"\n+    end\n+\n+    # @return [Gem] found gem or nil if not found\n+    def find_gem(name)\n+      @gems_by_name[name.downcase]\n+    end\n+\n+    # @raise GemfileError if gem already exists\n+    def add_gem(_gem)\n+      raise(GemfileError, \"duplicate gem #{_gem.name}\") if find_gem(_gem.name)\n+      @gems << _gem\n+      @gems_by_name[_gem.name.downcase] = _gem\n+    end\n+\n+    # update existing or add new\n+    def update_gem(_gem)\n+      if old = find_gem(_gem.name)\n+        @gems[@gems.index(old)] = _gem\n+      else\n+        @gems << _gem\n+      end\n+      @gems_by_name[_gem.name.downcase] = _gem\n+    end\n+\n+    # @return [Gem] removed gem or nil if not found\n+    def remove_gem(name)\n+      if _gem = @gems_by_name.delete(name.downcase)\n+        @gems.delete_at(@gems.index(_gem))\n+      end\n+      _gem\n+    end\n+\n+    # deep clone self\n+    def copy\n+      Marshal.load(Marshal.dump(self))\n+    end\n+\n+    private\n+\n+    def sources_to_s\n+      return nil if @sources.empty?\n+      @sources.map{|source| \"source #{source.inspect}\"}.join(\"\\n\")\n+    end\n+\n+    def gems_to_s\n+      return nil if @gems.empty?\n+      @gems.map do |gem|\n+        requirements = gem.requirements.empty? ? nil : gem.requirements.map{|r| r.inspect}.join(\", \")\n+        options = gem.options.empty? ? nil : gem.options.map{|k, v| \"#{k.inspect} => #{v.inspect}\"}.join(\", \")\n+        \"gem \" + [gem.name.inspect, requirements, options].compact.join(\", \")\n+      end.join(\"\\n\")\n+    end\n+\n+    def gemspec_to_s\n+      return nil if @gemspec.empty?\n+      options = @gemspec.map{|k, v| \"#{k.inspect} => #{v.inspect}\"}.join(\", \")\n+      \"gemspec #{options}\"\n+    end\n+  end\n+\n+  # Dsl is a minimal, incomplete Gemfile DSL subset parser, only what is currently required is implemented.\n+  class Dsl\n+    attr_reader :gemset\n+\n+    def initialize\n+      @gemset = Gemset.new\n+    end\n+\n+    def self.parse(gemfile)","path":"lib/logstash/gemfile.rb","position":136,"original_position":136,"commit_id":"be8b530ff758213c7664547666ff8ba384c4f46a","original_commit_id":"be8b530ff758213c7664547666ff8ba384c4f46a","user":{"login":"colinsurprenant","id":2010,"avatar_url":"https://avatars.githubusercontent.com/u/2010?v=3","gravatar_id":"","url":"https://api.github.com/users/colinsurprenant","html_url":"https://github.com/colinsurprenant","followers_url":"https://api.github.com/users/colinsurprenant/followers","following_url":"https://api.github.com/users/colinsurprenant/following{/other_user}","gists_url":"https://api.github.com/users/colinsurprenant/gists{/gist_id}","starred_url":"https://api.github.com/users/colinsurprenant/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/colinsurprenant/subscriptions","organizations_url":"https://api.github.com/users/colinsurprenant/orgs","repos_url":"https://api.github.com/users/colinsurprenant/repos","events_url":"https://api.github.com/users/colinsurprenant/events{/privacy}","received_events_url":"https://api.github.com/users/colinsurprenant/received_events","type":"User","site_admin":false},"body":"+1","created_at":"2015-02-13T21:16:42Z","updated_at":"2015-02-13T21:16:42Z","html_url":"https://github.com/elasticsearch/logstash/pull/2475#discussion_r24697414","pull_request_url":"https://api.github.com/repos/elasticsearch/logstash/pulls/2475","_links":{"self":{"href":"https://api.github.com/repos/elasticsearch/logstash/pulls/comments/24697414"},"html":{"href":"https://github.com/elasticsearch/logstash/pull/2475#discussion_r24697414"},"pull_request":{"href":"https://api.github.com/repos/elasticsearch/logstash/pulls/2475"}}},"pull_request":{"url":"https://api.github.com/repos/elasticsearch/logstash/pulls/2475","id":28232747,"html_url":"https://github.com/elasticsearch/logstash/pull/2475","diff_url":"https://github.com/elasticsearch/logstash/pull/2475.diff","patch_url":"https://github.com/elasticsearch/logstash/pull/2475.patch","issue_url":"https://api.github.com/repos/elasticsearch/logstash/issues/2475","number":2475,"state":"open","locked":false,"title":"plugins/bundler refactor","user":{"login":"ph","id":640,"avatar_url":"https://avatars.githubusercontent.com/u/640?v=3","gravatar_id":"","url":"https://api.github.com/users/ph","html_url":"https://github.com/ph","followers_url":"https://api.github.com/users/ph/followers","following_url":"https://api.github.com/users/ph/following{/other_user}","gists_url":"https://api.github.com/users/ph/gists{/gist_id}","starred_url":"https://api.github.com/users/ph/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ph/subscriptions","organizations_url":"https://api.github.com/users/ph/orgs","repos_url":"https://api.github.com/users/ph/repos","events_url":"https://api.github.com/users/ph/events{/privacy}","received_events_url":"https://api.github.com/users/ph/received_events","type":"User","site_admin":false},"body":"","created_at":"2015-01-28T21:49:28Z","updated_at":"2015-02-13T21:16:42Z","closed_at":null,"merged_at":null,"merge_commit_sha":"388f3ce5239c38c8e559fb399a56165cd3c86287","assignee":{"login":"colinsurprenant","id":2010,"avatar_url":"https://avatars.githubusercontent.com/u/2010?v=3","gravatar_id":"","url":"https://api.github.com/users/colinsurprenant","html_url":"https://github.com/colinsurprenant","followers_url":"https://api.github.com/users/colinsurprenant/followers","following_url":"https://api.github.com/users/colinsurprenant/following{/other_user}","gists_url":"https://api.github.com/users/colinsurprenant/gists{/gist_id}","starred_url":"https://api.github.com/users/colinsurprenant/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/colinsurprenant/subscriptions","organizations_url":"https://api.github.com/users/colinsurprenant/orgs","repos_url":"https://api.github.com/users/colinsurprenant/repos","events_url":"https://api.github.com/users/colinsurprenant/events{/privacy}","received_events_url":"https://api.github.com/users/colinsurprenant/received_events","type":"User","site_admin":false},"milestone":{"url":"https://api.github.com/repos/elasticsearch/logstash/milestones/8","labels_url":"https://api.github.com/repos/elasticsearch/logstash/milestones/8/labels","id":953679,"number":8,"title":"v1.5.0 rc1","description":"","creator":{"login":"jordansissel","id":131818,"avatar_url":"https://avatars.githubusercontent.com/u/131818?v=3","gravatar_id":"","url":"https://api.github.com/users/jordansissel","html_url":"https://github.com/jordansissel","followers_url":"https://api.github.com/users/jordansissel/followers","following_url":"https://api.github.com/users/jordansissel/following{/other_user}","gists_url":"https://api.github.com/users/jordansissel/gists{/gist_id}","starred_url":"https://api.github.com/users/jordansissel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jordansissel/subscriptions","organizations_url":"https://api.github.com/users/jordansissel/orgs","repos_url":"https://api.github.com/users/jordansissel/repos","events_url":"https://api.github.com/users/jordansissel/events{/privacy}","received_events_url":"https://api.github.com/users/jordansissel/received_events","type":"User","site_admin":false},"open_issues":13,"closed_issues":16,"state":"open","created_at":"2015-01-27T18:51:07Z","updated_at":"2015-02-13T01:43:54Z","due_on":null,"closed_at":null},"commits_url":"https://api.github.com/repos/elasticsearch/logstash/pulls/2475/commits","review_comments_url":"https://api.github.com/repos/elasticsearch/logstash/pulls/2475/comments","review_comment_url":"https://api.github.com/repos/elasticsearch/logstash/pulls/comments/{number}","comments_url":"https://api.github.com/repos/elasticsearch/logstash/issues/2475/comments","statuses_url":"https://api.github.com/repos/elasticsearch/logstash/statuses/be8b530ff758213c7664547666ff8ba384c4f46a","head":{"label":"elasticsearch:wip/bundler-move","ref":"wip/bundler-move","sha":"be8b530ff758213c7664547666ff8ba384c4f46a","user":{"login":"elasticsearch","id":141304,"avatar_url":"https://avatars.githubusercontent.com/u/141304?v=3","gravatar_id":"","url":"https://api.github.com/users/elasticsearch","html_url":"https://github.com/elasticsearch","followers_url":"https://api.github.com/users/elasticsearch/followers","following_url":"https://api.github.com/users/elasticsearch/following{/other_user}","gists_url":"https://api.github.com/users/elasticsearch/gists{/gist_id}","starred_url":"https://api.github.com/users/elasticsearch/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/elasticsearch/subscriptions","organizations_url":"https://api.github.com/users/elasticsearch/orgs","repos_url":"https://api.github.com/users/elasticsearch/repos","events_url":"https://api.github.com/users/elasticsearch/events{/privacy}","received_events_url":"https://api.github.com/users/elasticsearch/received_events","type":"Organization","site_admin":false},"repo":{"id":1090311,"name":"logstash","full_name":"elasticsearch/logstash","owner":{"login":"elasticsearch","id":141304,"avatar_url":"https://avatars.githubusercontent.com/u/141304?v=3","gravatar_id":"","url":"https://api.github.com/users/elasticsearch","html_url":"https://github.com/elasticsearch","followers_url":"https://api.github.com/users/elasticsearch/followers","following_url":"https://api.github.com/users/elasticsearch/following{/other_user}","gists_url":"https://api.github.com/users/elasticsearch/gists{/gist_id}","starred_url":"https://api.github.com/users/elasticsearch/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/elasticsearch/subscriptions","organizations_url":"https://api.github.com/users/elasticsearch/orgs","repos_url":"https://api.github.com/users/elasticsearch/repos","events_url":"https://api.github.com/users/elasticsearch/events{/privacy}","received_events_url":"https://api.github.com/users/elasticsearch/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/elasticsearch/logstash","description":"logstash - logs/event transport, processing, management, search.","fork":false,"url":"https://api.github.com/repos/elasticsearch/logstash","forks_url":"https://api.github.com/repos/elasticsearch/logstash/forks","keys_url":"https://api.github.com/repos/elasticsearch/logstash/keys{/key_id}","collaborators_url":"https://api.github.com/repos/elasticsearch/logstash/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/elasticsearch/logstash/teams","hooks_url":"https://api.github.com/repos/elasticsearch/logstash/hooks","issue_events_url":"https://api.github.com/repos/elasticsearch/logstash/issues/events{/number}","events_url":"https://api.github.com/repos/elasticsearch/logstash/events","assignees_url":"https://api.github.com/repos/elasticsearch/logstash/assignees{/user}","branches_url":"https://api.github.com/repos/elasticsearch/logstash/branches{/branch}","tags_url":"https://api.github.com/repos/elasticsearch/logstash/tags","blobs_url":"https://api.github.com/repos/elasticsearch/logstash/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/elasticsearch/logstash/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/elasticsearch/logstash/git/refs{/sha}","trees_url":"https://api.github.com/repos/elasticsearch/logstash/git/trees{/sha}","statuses_url":"https://api.github.com/repos/elasticsearch/logstash/statuses/{sha}","languages_url":"https://api.github.com/repos/elasticsearch/logstash/languages","stargazers_url":"https://api.github.com/repos/elasticsearch/logstash/stargazers","contributors_url":"https://api.github.com/repos/elasticsearch/logstash/contributors","subscribers_url":"https://api.github.com/repos/elasticsearch/logstash/subscribers","subscription_url":"https://api.github.com/repos/elasticsearch/logstash/subscription","commits_url":"https://api.github.com/repos/elasticsearch/logstash/commits{/sha}","git_commits_url":"https://api.github.com/repos/elasticsearch/logstash/git/commits{/sha}","comments_url":"https://api.github.com/repos/elasticsearch/logstash/comments{/number}","issue_comment_url":"https://api.github.com/repos/elasticsearch/logstash/issues/comments/{number}","contents_url":"https://api.github.com/repos/elasticsearch/logstash/contents/{+path}","compare_url":"https://api.github.com/repos/elasticsearch/logstash/compare/{base}...{head}","merges_url":"https://api.github.com/repos/elasticsearch/logstash/merges","archive_url":"https://api.github.com/repos/elasticsearch/logstash/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/elasticsearch/logstash/downloads","issues_url":"https://api.github.com/repos/elasticsearch/logstash/issues{/number}","pulls_url":"https://api.github.com/repos/elasticsearch/logstash/pulls{/number}","milestones_url":"https://api.github.com/repos/elasticsearch/logstash/milestones{/number}","notifications_url":"https://api.github.com/repos/elasticsearch/logstash/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/elasticsearch/logstash/labels{/name}","releases_url":"https://api.github.com/repos/elasticsearch/logstash/releases{/id}","created_at":"2010-11-18T01:31:50Z","updated_at":"2015-02-13T18:41:11Z","pushed_at":"2015-02-13T01:41:37Z","git_url":"git://github.com/elasticsearch/logstash.git","ssh_url":"git@github.com:elasticsearch/logstash.git","clone_url":"https://github.com/elasticsearch/logstash.git","svn_url":"https://github.com/elasticsearch/logstash","homepage":"http://logstash.net/","size":87340,"stargazers_count":3669,"watchers_count":3669,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1344,"mirror_url":null,"open_issues_count":534,"forks":1344,"open_issues":534,"watchers":3669,"default_branch":"master"}},"base":{"label":"elasticsearch:master","ref":"master","sha":"f78b74cf9aa326f9647ff95b5838d8a570acf4eb","user":{"login":"elasticsearch","id":141304,"avatar_url":"https://avatars.githubusercontent.com/u/141304?v=3","gravatar_id":"","url":"https://api.github.com/users/elasticsearch","html_url":"https://github.com/elasticsearch","followers_url":"https://api.github.com/users/elasticsearch/followers","following_url":"https://api.github.com/users/elasticsearch/following{/other_user}","gists_url":"https://api.github.com/users/elasticsearch/gists{/gist_id}","starred_url":"https://api.github.com/users/elasticsearch/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/elasticsearch/subscriptions","organizations_url":"https://api.github.com/users/elasticsearch/orgs","repos_url":"https://api.github.com/users/elasticsearch/repos","events_url":"https://api.github.com/users/elasticsearch/events{/privacy}","received_events_url":"https://api.github.com/users/elasticsearch/received_events","type":"Organization","site_admin":false},"repo":{"id":1090311,"name":"logstash","full_name":"elasticsearch/logstash","owner":{"login":"elasticsearch","id":141304,"avatar_url":"https://avatars.githubusercontent.com/u/141304?v=3","gravatar_id":"","url":"https://api.github.com/users/elasticsearch","html_url":"https://github.com/elasticsearch","followers_url":"https://api.github.com/users/elasticsearch/followers","following_url":"https://api.github.com/users/elasticsearch/following{/other_user}","gists_url":"https://api.github.com/users/elasticsearch/gists{/gist_id}","starred_url":"https://api.github.com/users/elasticsearch/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/elasticsearch/subscriptions","organizations_url":"https://api.github.com/users/elasticsearch/orgs","repos_url":"https://api.github.com/users/elasticsearch/repos","events_url":"https://api.github.com/users/elasticsearch/events{/privacy}","received_events_url":"https://api.github.com/users/elasticsearch/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/elasticsearch/logstash","description":"logstash - logs/event transport, processing, management, search.","fork":false,"url":"https://api.github.com/repos/elasticsearch/logstash","forks_url":"https://api.github.com/repos/elasticsearch/logstash/forks","keys_url":"https://api.github.com/repos/elasticsearch/logstash/keys{/key_id}","collaborators_url":"https://api.github.com/repos/elasticsearch/logstash/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/elasticsearch/logstash/teams","hooks_url":"https://api.github.com/repos/elasticsearch/logstash/hooks","issue_events_url":"https://api.github.com/repos/elasticsearch/logstash/issues/events{/number}","events_url":"https://api.github.com/repos/elasticsearch/logstash/events","assignees_url":"https://api.github.com/repos/elasticsearch/logstash/assignees{/user}","branches_url":"https://api.github.com/repos/elasticsearch/logstash/branches{/branch}","tags_url":"https://api.github.com/repos/elasticsearch/logstash/tags","blobs_url":"https://api.github.com/repos/elasticsearch/logstash/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/elasticsearch/logstash/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/elasticsearch/logstash/git/refs{/sha}","trees_url":"https://api.github.com/repos/elasticsearch/logstash/git/trees{/sha}","statuses_url":"https://api.github.com/repos/elasticsearch/logstash/statuses/{sha}","languages_url":"https://api.github.com/repos/elasticsearch/logstash/languages","stargazers_url":"https://api.github.com/repos/elasticsearch/logstash/stargazers","contributors_url":"https://api.github.com/repos/elasticsearch/logstash/contributors","subscribers_url":"https://api.github.com/repos/elasticsearch/logstash/subscribers","subscription_url":"https://api.github.com/repos/elasticsearch/logstash/subscription","commits_url":"https://api.github.com/repos/elasticsearch/logstash/commits{/sha}","git_commits_url":"https://api.github.com/repos/elasticsearch/logstash/git/commits{/sha}","comments_url":"https://api.github.com/repos/elasticsearch/logstash/comments{/number}","issue_comment_url":"https://api.github.com/repos/elasticsearch/logstash/issues/comments/{number}","contents_url":"https://api.github.com/repos/elasticsearch/logstash/contents/{+path}","compare_url":"https://api.github.com/repos/elasticsearch/logstash/compare/{base}...{head}","merges_url":"https://api.github.com/repos/elasticsearch/logstash/merges","archive_url":"https://api.github.com/repos/elasticsearch/logstash/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/elasticsearch/logstash/downloads","issues_url":"https://api.github.com/repos/elasticsearch/logstash/issues{/number}","pulls_url":"https://api.github.com/repos/elasticsearch/logstash/pulls{/number}","milestones_url":"https://api.github.com/repos/elasticsearch/logstash/milestones{/number}","notifications_url":"https://api.github.com/repos/elasticsearch/logstash/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/elasticsearch/logstash/labels{/name}","releases_url":"https://api.github.com/repos/elasticsearch/logstash/releases{/id}","created_at":"2010-11-18T01:31:50Z","updated_at":"2015-02-13T18:41:11Z","pushed_at":"2015-02-13T01:41:37Z","git_url":"git://github.com/elasticsearch/logstash.git","ssh_url":"git@github.com:elasticsearch/logstash.git","clone_url":"https://github.com/elasticsearch/logstash.git","svn_url":"https://github.com/elasticsearch/logstash","homepage":"http://logstash.net/","size":87340,"stargazers_count":3669,"watchers_count":3669,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1344,"mirror_url":null,"open_issues_count":534,"forks":1344,"open_issues":534,"watchers":3669,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/elasticsearch/logstash/pulls/2475"},"html":{"href":"https://github.com/elasticsearch/logstash/pull/2475"},"issue":{"href":"https://api.github.com/repos/elasticsearch/logstash/issues/2475"},"comments":{"href":"https://api.github.com/repos/elasticsearch/logstash/issues/2475/comments"},"review_comments":{"href":"https://api.github.com/repos/elasticsearch/logstash/pulls/2475/comments"},"review_comment":{"href":"https://api.github.com/repos/elasticsearch/logstash/pulls/comments/{number}"},"commits":{"href":"https://api.github.com/repos/elasticsearch/logstash/pulls/2475/commits"},"statuses":{"href":"https://api.github.com/repos/elasticsearch/logstash/statuses/be8b530ff758213c7664547666ff8ba384c4f46a"}}}}