{"action":"created","comment":{"url":"https://api.github.com/repos/airbrake/airbrake/pulls/comments/49437125","id":49437125,"diff_hunk":"@@ -0,0 +1,62 @@\n+require 'set'\n+require 'pathname'\n+\n+module Airbrake\n+  # Integration for Phusion Passenger\n+  module Passenger\n+    IntegrationException = Class.new(::Exception)\n+    class << self\n+      def version\n+        unless defined?(::PhusionPassenger)\n+          raise IntegrationException, \"PhusionPassenger not detected\"\n+        end\n+        @version = Gem::Version.new(::PhusionPassenger::VERSION_STRING)\n+      end\n+\n+      def version?(req)\n+        reqs = req.split(',').map(&:strip).compact\n+        Gem::Requirement.new(*reqs).satisfied_by?(version)\n+      end\n+\n+      def integrations\n+        return @integrations if defined?(@integrations)\n+        @integrations ||= Set.new\n+        dir = Pathname.new(__FILE__).dirname.join('passenger')\n+        dir.each_child do |child|\n+          next unless child.file? && child.readable?\n+          next unless child.fnmatch?('*.rb')\n+          require \"airbrake/passenger/#{child.basename '.rb'}\"\n+        end\n+        @integrations\n+      end\n+\n+      def integration\n+        return @integration if defined?(@integration)\n+        @integration = integrations.to_a.detect do |i|\n+          Array[i::VERSION_REQUIREMENT].any? do |vr|\n+            version?(vr)\n+          end\n+        end\n+        raise IntegrationException, \"Your version of PhusionPassenger \" \\\n+          \"is not currently supported by the airbrake gem.\" if @integration.nil?\n+        @integration\n+      end\n+\n+      def integrate!\n+        return @integrated if defined?(@integrated)\n+        integration.integrate!\n+      rescue IntegrationException => e\n+        Kernel.warn e\n+        @integrated = false\n+      else\n+        @integrated = true\n+      end\n+\n+      def integrated?\n+        @integrated == true\n+      end\n+    end\n+  end\n+end","path":"lib/airbrake/passenger.rb","position":60,"original_position":60,"commit_id":"66756c45e90738afed3188afe969ae9d7a7bae27","original_commit_id":"66756c45e90738afed3188afe969ae9d7a7bae27","user":{"login":"kyrylo","id":1079123,"avatar_url":"https://avatars.githubusercontent.com/u/1079123?v=3","gravatar_id":"","url":"https://api.github.com/users/kyrylo","html_url":"https://github.com/kyrylo","followers_url":"https://api.github.com/users/kyrylo/followers","following_url":"https://api.github.com/users/kyrylo/following{/other_user}","gists_url":"https://api.github.com/users/kyrylo/gists{/gist_id}","starred_url":"https://api.github.com/users/kyrylo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kyrylo/subscriptions","organizations_url":"https://api.github.com/users/kyrylo/orgs","repos_url":"https://api.github.com/users/kyrylo/repos","events_url":"https://api.github.com/users/kyrylo/events{/privacy}","received_events_url":"https://api.github.com/users/kyrylo/received_events","type":"User","site_admin":false},"body":"The convention we try to follow is to place every integration file inside its own directory. It would be nice if you could also put this file inside the passenger directory.","created_at":"2016-01-12T10:33:42Z","updated_at":"2016-01-12T10:33:42Z","html_url":"https://github.com/airbrake/airbrake/pull/472#discussion_r49437125","pull_request_url":"https://api.github.com/repos/airbrake/airbrake/pulls/472","_links":{"self":{"href":"https://api.github.com/repos/airbrake/airbrake/pulls/comments/49437125"},"html":{"href":"https://github.com/airbrake/airbrake/pull/472#discussion_r49437125"},"pull_request":{"href":"https://api.github.com/repos/airbrake/airbrake/pulls/472"}}},"pull_request":{"url":"https://api.github.com/repos/airbrake/airbrake/pulls/472","id":55577628,"html_url":"https://github.com/airbrake/airbrake/pull/472","diff_url":"https://github.com/airbrake/airbrake/pull/472.diff","patch_url":"https://github.com/airbrake/airbrake/pull/472.patch","issue_url":"https://api.github.com/repos/airbrake/airbrake/issues/472","number":472,"state":"open","locked":false,"title":"Added integration with Phusion Passenger v5.0.x","user":{"login":"mvastola","id":599767,"avatar_url":"https://avatars.githubusercontent.com/u/599767?v=3","gravatar_id":"","url":"https://api.github.com/users/mvastola","html_url":"https://github.com/mvastola","followers_url":"https://api.github.com/users/mvastola/followers","following_url":"https://api.github.com/users/mvastola/following{/other_user}","gists_url":"https://api.github.com/users/mvastola/gists{/gist_id}","starred_url":"https://api.github.com/users/mvastola/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mvastola/subscriptions","organizations_url":"https://api.github.com/users/mvastola/orgs","repos_url":"https://api.github.com/users/mvastola/repos","events_url":"https://api.github.com/users/mvastola/events{/privacy}","received_events_url":"https://api.github.com/users/mvastola/received_events","type":"User","site_admin":false},"body":"Following up on #470, here is what I have as a rough-draft. It's totally not ready for merging yet (apparently my original code greatly \"offended\" `rubocop`s style requirements), but I'd appreciate initial thoughts, both on below and the changes themselves.\r\n\r\nItems on my TODO list are (to be edited/whittled down as I go along):\r\n* Figure out how best to load the configuration information (i.e. api key, project key, whatever is needed to send the notification). \r\n  * Of course you can put it in `config.ru`, or right after doing `Bundler.require`, but that may get messy. \r\n  * Another option is to check for an initializer in `config/initializers/airbrake.rb` (relative to the `Gemfile`) and require just that file, but that will only work if the person has `rails` and used the generator, and will cause obscure problems if external modules are referenced in that initializer.\r\n  * Thoughts welcome, as I don't really want to hoist a rewrite of the configuration process on you guys for the sake of this PR.\r\n* Figure out what, if any, additional contextual info from `passenger` or elsewhere should be sent up to `airbrake`. (Perhaps a list of gems? Suggestions welcome.)\r\n* CI Testing, of course. (Not quite sure how to set this up, actually..)\r\n  * I'm used to `Travis` rather than `circle`, which is apparently what you have, but I wouldn't even be sure how to set it up on the former off the top of my head, so this may require some trial and error.\r\n    * This is if testing is to include running a web server with a `passenger` module.","created_at":"2016-01-10T23:23:54Z","updated_at":"2016-01-12T10:33:42Z","closed_at":null,"merged_at":null,"merge_commit_sha":"c2d8dcf54267327477ee3fe64edfb84b342690da","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/airbrake/airbrake/pulls/472/commits","review_comments_url":"https://api.github.com/repos/airbrake/airbrake/pulls/472/comments","review_comment_url":"https://api.github.com/repos/airbrake/airbrake/pulls/comments{/number}","comments_url":"https://api.github.com/repos/airbrake/airbrake/issues/472/comments","statuses_url":"https://api.github.com/repos/airbrake/airbrake/statuses/66756c45e90738afed3188afe969ae9d7a7bae27","head":{"label":"Partyista:master","ref":"master","sha":"66756c45e90738afed3188afe969ae9d7a7bae27","user":{"login":"Partyista","id":11988134,"avatar_url":"https://avatars.githubusercontent.com/u/11988134?v=3","gravatar_id":"","url":"https://api.github.com/users/Partyista","html_url":"https://github.com/Partyista","followers_url":"https://api.github.com/users/Partyista/followers","following_url":"https://api.github.com/users/Partyista/following{/other_user}","gists_url":"https://api.github.com/users/Partyista/gists{/gist_id}","starred_url":"https://api.github.com/users/Partyista/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Partyista/subscriptions","organizations_url":"https://api.github.com/users/Partyista/orgs","repos_url":"https://api.github.com/users/Partyista/repos","events_url":"https://api.github.com/users/Partyista/events{/privacy}","received_events_url":"https://api.github.com/users/Partyista/received_events","type":"Organization","site_admin":false},"repo":{"id":49388669,"name":"airbrake","full_name":"Partyista/airbrake","owner":{"login":"Partyista","id":11988134,"avatar_url":"https://avatars.githubusercontent.com/u/11988134?v=3","gravatar_id":"","url":"https://api.github.com/users/Partyista","html_url":"https://github.com/Partyista","followers_url":"https://api.github.com/users/Partyista/followers","following_url":"https://api.github.com/users/Partyista/following{/other_user}","gists_url":"https://api.github.com/users/Partyista/gists{/gist_id}","starred_url":"https://api.github.com/users/Partyista/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Partyista/subscriptions","organizations_url":"https://api.github.com/users/Partyista/orgs","repos_url":"https://api.github.com/users/Partyista/repos","events_url":"https://api.github.com/users/Partyista/events{/privacy}","received_events_url":"https://api.github.com/users/Partyista/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Partyista/airbrake","description":"The official Airbrake library for Ruby applications","fork":true,"url":"https://api.github.com/repos/Partyista/airbrake","forks_url":"https://api.github.com/repos/Partyista/airbrake/forks","keys_url":"https://api.github.com/repos/Partyista/airbrake/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Partyista/airbrake/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Partyista/airbrake/teams","hooks_url":"https://api.github.com/repos/Partyista/airbrake/hooks","issue_events_url":"https://api.github.com/repos/Partyista/airbrake/issues/events{/number}","events_url":"https://api.github.com/repos/Partyista/airbrake/events","assignees_url":"https://api.github.com/repos/Partyista/airbrake/assignees{/user}","branches_url":"https://api.github.com/repos/Partyista/airbrake/branches{/branch}","tags_url":"https://api.github.com/repos/Partyista/airbrake/tags","blobs_url":"https://api.github.com/repos/Partyista/airbrake/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Partyista/airbrake/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Partyista/airbrake/git/refs{/sha}","trees_url":"https://api.github.com/repos/Partyista/airbrake/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Partyista/airbrake/statuses/{sha}","languages_url":"https://api.github.com/repos/Partyista/airbrake/languages","stargazers_url":"https://api.github.com/repos/Partyista/airbrake/stargazers","contributors_url":"https://api.github.com/repos/Partyista/airbrake/contributors","subscribers_url":"https://api.github.com/repos/Partyista/airbrake/subscribers","subscription_url":"https://api.github.com/repos/Partyista/airbrake/subscription","commits_url":"https://api.github.com/repos/Partyista/airbrake/commits{/sha}","git_commits_url":"https://api.github.com/repos/Partyista/airbrake/git/commits{/sha}","comments_url":"https://api.github.com/repos/Partyista/airbrake/comments{/number}","issue_comment_url":"https://api.github.com/repos/Partyista/airbrake/issues/comments{/number}","contents_url":"https://api.github.com/repos/Partyista/airbrake/contents/{+path}","compare_url":"https://api.github.com/repos/Partyista/airbrake/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Partyista/airbrake/merges","archive_url":"https://api.github.com/repos/Partyista/airbrake/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Partyista/airbrake/downloads","issues_url":"https://api.github.com/repos/Partyista/airbrake/issues{/number}","pulls_url":"https://api.github.com/repos/Partyista/airbrake/pulls{/number}","milestones_url":"https://api.github.com/repos/Partyista/airbrake/milestones{/number}","notifications_url":"https://api.github.com/repos/Partyista/airbrake/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Partyista/airbrake/labels{/name}","releases_url":"https://api.github.com/repos/Partyista/airbrake/releases{/id}","created_at":"2016-01-10T22:33:55Z","updated_at":"2016-01-12T02:35:07Z","pushed_at":"2016-01-12T02:35:05Z","git_url":"git://github.com/Partyista/airbrake.git","ssh_url":"git@github.com:Partyista/airbrake.git","clone_url":"https://github.com/Partyista/airbrake.git","svn_url":"https://github.com/Partyista/airbrake","homepage":"https://airbrake.io","size":2166,"stargazers_count":0,"watchers_count":0,"language":"Ruby","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":0,"forks":1,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"airbrake:master","ref":"master","sha":"795c6314cd312d0823d0d55d580f4bf8f42a303e","user":{"login":"airbrake","id":1015434,"avatar_url":"https://avatars.githubusercontent.com/u/1015434?v=3","gravatar_id":"","url":"https://api.github.com/users/airbrake","html_url":"https://github.com/airbrake","followers_url":"https://api.github.com/users/airbrake/followers","following_url":"https://api.github.com/users/airbrake/following{/other_user}","gists_url":"https://api.github.com/users/airbrake/gists{/gist_id}","starred_url":"https://api.github.com/users/airbrake/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/airbrake/subscriptions","organizations_url":"https://api.github.com/users/airbrake/orgs","repos_url":"https://api.github.com/users/airbrake/repos","events_url":"https://api.github.com/users/airbrake/events{/privacy}","received_events_url":"https://api.github.com/users/airbrake/received_events","type":"Organization","site_admin":false},"repo":{"id":2263819,"name":"airbrake","full_name":"airbrake/airbrake","owner":{"login":"airbrake","id":1015434,"avatar_url":"https://avatars.githubusercontent.com/u/1015434?v=3","gravatar_id":"","url":"https://api.github.com/users/airbrake","html_url":"https://github.com/airbrake","followers_url":"https://api.github.com/users/airbrake/followers","following_url":"https://api.github.com/users/airbrake/following{/other_user}","gists_url":"https://api.github.com/users/airbrake/gists{/gist_id}","starred_url":"https://api.github.com/users/airbrake/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/airbrake/subscriptions","organizations_url":"https://api.github.com/users/airbrake/orgs","repos_url":"https://api.github.com/users/airbrake/repos","events_url":"https://api.github.com/users/airbrake/events{/privacy}","received_events_url":"https://api.github.com/users/airbrake/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/airbrake/airbrake","description":"The official Airbrake library for Ruby applications","fork":false,"url":"https://api.github.com/repos/airbrake/airbrake","forks_url":"https://api.github.com/repos/airbrake/airbrake/forks","keys_url":"https://api.github.com/repos/airbrake/airbrake/keys{/key_id}","collaborators_url":"https://api.github.com/repos/airbrake/airbrake/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/airbrake/airbrake/teams","hooks_url":"https://api.github.com/repos/airbrake/airbrake/hooks","issue_events_url":"https://api.github.com/repos/airbrake/airbrake/issues/events{/number}","events_url":"https://api.github.com/repos/airbrake/airbrake/events","assignees_url":"https://api.github.com/repos/airbrake/airbrake/assignees{/user}","branches_url":"https://api.github.com/repos/airbrake/airbrake/branches{/branch}","tags_url":"https://api.github.com/repos/airbrake/airbrake/tags","blobs_url":"https://api.github.com/repos/airbrake/airbrake/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/airbrake/airbrake/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/airbrake/airbrake/git/refs{/sha}","trees_url":"https://api.github.com/repos/airbrake/airbrake/git/trees{/sha}","statuses_url":"https://api.github.com/repos/airbrake/airbrake/statuses/{sha}","languages_url":"https://api.github.com/repos/airbrake/airbrake/languages","stargazers_url":"https://api.github.com/repos/airbrake/airbrake/stargazers","contributors_url":"https://api.github.com/repos/airbrake/airbrake/contributors","subscribers_url":"https://api.github.com/repos/airbrake/airbrake/subscribers","subscription_url":"https://api.github.com/repos/airbrake/airbrake/subscription","commits_url":"https://api.github.com/repos/airbrake/airbrake/commits{/sha}","git_commits_url":"https://api.github.com/repos/airbrake/airbrake/git/commits{/sha}","comments_url":"https://api.github.com/repos/airbrake/airbrake/comments{/number}","issue_comment_url":"https://api.github.com/repos/airbrake/airbrake/issues/comments{/number}","contents_url":"https://api.github.com/repos/airbrake/airbrake/contents/{+path}","compare_url":"https://api.github.com/repos/airbrake/airbrake/compare/{base}...{head}","merges_url":"https://api.github.com/repos/airbrake/airbrake/merges","archive_url":"https://api.github.com/repos/airbrake/airbrake/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/airbrake/airbrake/downloads","issues_url":"https://api.github.com/repos/airbrake/airbrake/issues{/number}","pulls_url":"https://api.github.com/repos/airbrake/airbrake/pulls{/number}","milestones_url":"https://api.github.com/repos/airbrake/airbrake/milestones{/number}","notifications_url":"https://api.github.com/repos/airbrake/airbrake/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/airbrake/airbrake/labels{/name}","releases_url":"https://api.github.com/repos/airbrake/airbrake/releases{/id}","created_at":"2011-08-24T19:33:00Z","updated_at":"2016-01-08T21:03:42Z","pushed_at":"2016-01-12T02:35:06Z","git_url":"git://github.com/airbrake/airbrake.git","ssh_url":"git@github.com:airbrake/airbrake.git","clone_url":"https://github.com/airbrake/airbrake.git","svn_url":"https://github.com/airbrake/airbrake","homepage":"https://airbrake.io","size":2345,"stargazers_count":661,"watchers_count":661,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":296,"mirror_url":null,"open_issues_count":5,"forks":296,"open_issues":5,"watchers":661,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/airbrake/airbrake/pulls/472"},"html":{"href":"https://github.com/airbrake/airbrake/pull/472"},"issue":{"href":"https://api.github.com/repos/airbrake/airbrake/issues/472"},"comments":{"href":"https://api.github.com/repos/airbrake/airbrake/issues/472/comments"},"review_comments":{"href":"https://api.github.com/repos/airbrake/airbrake/pulls/472/comments"},"review_comment":{"href":"https://api.github.com/repos/airbrake/airbrake/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/airbrake/airbrake/pulls/472/commits"},"statuses":{"href":"https://api.github.com/repos/airbrake/airbrake/statuses/66756c45e90738afed3188afe969ae9d7a7bae27"}}}}