{"action":"created","comment":{"url":"https://api.github.com/repos/ansible/ansible-modules-extras/pulls/comments/31829328","id":31829328,"diff_hunk":"@@ -0,0 +1,230 @@\n+#!/usr/bin/python -tt\n+# -*- coding: utf-8 -*-\n+\n+# (c) 2012, Afterburn <http://github.com/afterburn>\n+# (c) 2013, Aaron Bull Schaefer <aaron@elasticdog.com>\n+# (c) 2015, Jonathan Lestrelin <jonathan.lestrelin@gmail.com>\n+#\n+# This file is part of Ansible\n+#\n+# Ansible is free software: you can redistribute it and/or modify\n+# it under the terms of the GNU General Public License as published by\n+# the Free Software Foundation, either version 3 of the License, or\n+# (at your option) any later version.\n+#\n+# Ansible is distributed in the hope that it will be useful,\n+# but WITHOUT ANY WARRANTY; without even the implied warranty of\n+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+# GNU General Public License for more details.\n+#\n+# You should have received a copy of the GNU General Public License\n+# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.\n+\n+DOCUMENTATION = '''\n+---\n+module: pear\n+short_description: Manage pear/pecl packages\n+description:\n+    - Manage PHP packages with the pear package manager.\n+author:\n+    - \"'jonathan.lestrelin' <jonathan.lestrelin@gmail.com>\"\n+notes: []\n+requirements: []\n+options:\n+    name:\n+        description:\n+            - Name of the package to install, upgrade, or remove.\n+        required: true\n+        default: null\n+\n+    state:\n+        description:\n+            - Desired state of the package.\n+        required: false\n+        default: \"present\"\n+        choices: [\"present\", \"absent\", \"latest\"]\n+'''\n+\n+EXAMPLES = '''\n+# Install pear package\n+- pear: name=Net_URL2 state=present\n+\n+# Install pecl package\n+- pear: name=pecl/json_post state=present\n+\n+# Upgrade package\n+- pear: name=Net_URL2 state=latest\n+\n+# Remove packages\n+- pear: name=Net_URL2,pecl/json_post state=absent\n+'''\n+\n+import os\n+\n+def get_local_version(pear_output):\n+    \"\"\"Take pear remoteinfo output and get the installed version\"\"\"\n+    lines = pear_output.split('\\n')\n+    for line in lines:\n+        if 'Installed ' in line:\n+            installed = line.rsplit(None, 1)[-1].strip()\n+            if installed == '-': continue\n+            return installed\n+    return None\n+\n+def get_repository_version(pear_output):\n+    \"\"\"Take pear remote-info output and get the latest version\"\"\"\n+    lines = pear_output.split('\\n')\n+    for line in lines:\n+        if 'Latest ' in line:\n+            return line.rsplit(None, 1)[-1].strip()\n+    return None\n+\n+def query_package(module, name, state=\"present\"):\n+    \"\"\"Query the package status in both the local system and the repository.\n+    Returns a boolean to indicate if the package is installed,\n+    and a second boolean to indicate if the package is up-to-date.\"\"\"\n+    if state == \"present\":\n+        lcmd = \"pear info %s\" % (name)\n+        lrc, lstdout, lstderr = module.run_command(lcmd, check_rc=False)\n+        if lrc != 0:\n+            # package is not installed locally\n+            return False, False\n+\n+        rcmd = \"pear remote-info %s\" % (name)\n+        rrc, rstdout, rstderr = module.run_command(rcmd, check_rc=False)\n+\n+        # get the version installed locally (if any)\n+        lversion = get_local_version(rstdout)\n+\n+        # get the version in the repository\n+        rversion = get_repository_version(rstdout)\n+\n+        if rrc == 0:\n+            # Return True to indicate that the package is installed locally,\n+            # and the result of the version number comparison\n+            # to determine if the package is up-to-date.\n+            return True, (lversion == rversion)\n+\n+        return False, False\n+\n+\n+def remove_packages(module, packages):\n+    remove_c = 0\n+    # Using a for loop incase of error, we can report the package that failed\n+    for package in packages:\n+        # Query the package first, to see if we even need to remove\n+        installed, updated = query_package(module, package)\n+        if not installed:\n+            continue\n+\n+        cmd = \"pear uninstall %s\" % (package)\n+        rc, stdout, stderr = module.run_command(cmd, check_rc=False)\n+\n+        if rc != 0:\n+            module.fail_json(msg=\"failed to remove %s\" % (package))\n+\n+        remove_c += 1\n+\n+    if remove_c > 0:\n+\n+        module.exit_json(changed=True, msg=\"removed %s package(s)\" % remove_c)\n+\n+    module.exit_json(changed=False, msg=\"package(s) already absent\")\n+\n+\n+def install_packages(module, state, packages, package_files):","path":"packaging/language/pear.py","position":135,"original_position":135,"commit_id":"ab8dbd90f9869b343573391c2639e17c15e10071","original_commit_id":"ab8dbd90f9869b343573391c2639e17c15e10071","user":{"login":"sivel","id":39340,"avatar_url":"https://avatars.githubusercontent.com/u/39340?v=3","gravatar_id":"","url":"https://api.github.com/users/sivel","html_url":"https://github.com/sivel","followers_url":"https://api.github.com/users/sivel/followers","following_url":"https://api.github.com/users/sivel/following{/other_user}","gists_url":"https://api.github.com/users/sivel/gists{/gist_id}","starred_url":"https://api.github.com/users/sivel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sivel/subscriptions","organizations_url":"https://api.github.com/users/sivel/orgs","repos_url":"https://api.github.com/users/sivel/repos","events_url":"https://api.github.com/users/sivel/events{/privacy}","received_events_url":"https://api.github.com/users/sivel/received_events","type":"User","site_admin":false},"body":"`package_files` does not appear to be used in this function","created_at":"2015-06-05T16:43:25Z","updated_at":"2015-06-05T16:43:25Z","html_url":"https://github.com/ansible/ansible-modules-extras/pull/584#discussion_r31829328","pull_request_url":"https://api.github.com/repos/ansible/ansible-modules-extras/pulls/584","_links":{"self":{"href":"https://api.github.com/repos/ansible/ansible-modules-extras/pulls/comments/31829328"},"html":{"href":"https://github.com/ansible/ansible-modules-extras/pull/584#discussion_r31829328"},"pull_request":{"href":"https://api.github.com/repos/ansible/ansible-modules-extras/pulls/584"}}},"pull_request":{"url":"https://api.github.com/repos/ansible/ansible-modules-extras/pulls/584","id":37046851,"html_url":"https://github.com/ansible/ansible-modules-extras/pull/584","diff_url":"https://github.com/ansible/ansible-modules-extras/pull/584.diff","patch_url":"https://github.com/ansible/ansible-modules-extras/pull/584.patch","issue_url":"https://api.github.com/repos/ansible/ansible-modules-extras/issues/584","number":584,"state":"open","locked":false,"title":"Add pear packaging module to manage PHP PEAR an PECL packages","user":{"login":"gentledevil","id":7120882,"avatar_url":"https://avatars.githubusercontent.com/u/7120882?v=3","gravatar_id":"","url":"https://api.github.com/users/gentledevil","html_url":"https://github.com/gentledevil","followers_url":"https://api.github.com/users/gentledevil/followers","following_url":"https://api.github.com/users/gentledevil/following{/other_user}","gists_url":"https://api.github.com/users/gentledevil/gists{/gist_id}","starred_url":"https://api.github.com/users/gentledevil/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gentledevil/subscriptions","organizations_url":"https://api.github.com/users/gentledevil/orgs","repos_url":"https://api.github.com/users/gentledevil/repos","events_url":"https://api.github.com/users/gentledevil/events{/privacy}","received_events_url":"https://api.github.com/users/gentledevil/received_events","type":"User","site_admin":false},"body":"Hi,\r\n\r\nI would like to suggest the inclusion of this module  that manages PHP PEAR an PECL packages.\r\n\r\nThanks","created_at":"2015-06-05T16:21:55Z","updated_at":"2015-06-05T16:43:25Z","closed_at":null,"merged_at":null,"merge_commit_sha":"84c9ec1caf761d326833c30fb1b3a531184c4331","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/ansible/ansible-modules-extras/pulls/584/commits","review_comments_url":"https://api.github.com/repos/ansible/ansible-modules-extras/pulls/584/comments","review_comment_url":"https://api.github.com/repos/ansible/ansible-modules-extras/pulls/comments{/number}","comments_url":"https://api.github.com/repos/ansible/ansible-modules-extras/issues/584/comments","statuses_url":"https://api.github.com/repos/ansible/ansible-modules-extras/statuses/ab8dbd90f9869b343573391c2639e17c15e10071","head":{"label":"gentledevil:pear","ref":"pear","sha":"ab8dbd90f9869b343573391c2639e17c15e10071","user":{"login":"gentledevil","id":7120882,"avatar_url":"https://avatars.githubusercontent.com/u/7120882?v=3","gravatar_id":"","url":"https://api.github.com/users/gentledevil","html_url":"https://github.com/gentledevil","followers_url":"https://api.github.com/users/gentledevil/followers","following_url":"https://api.github.com/users/gentledevil/following{/other_user}","gists_url":"https://api.github.com/users/gentledevil/gists{/gist_id}","starred_url":"https://api.github.com/users/gentledevil/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gentledevil/subscriptions","organizations_url":"https://api.github.com/users/gentledevil/orgs","repos_url":"https://api.github.com/users/gentledevil/repos","events_url":"https://api.github.com/users/gentledevil/events{/privacy}","received_events_url":"https://api.github.com/users/gentledevil/received_events","type":"User","site_admin":false},"repo":{"id":36942579,"name":"ansible-modules-extras","full_name":"gentledevil/ansible-modules-extras","owner":{"login":"gentledevil","id":7120882,"avatar_url":"https://avatars.githubusercontent.com/u/7120882?v=3","gravatar_id":"","url":"https://api.github.com/users/gentledevil","html_url":"https://github.com/gentledevil","followers_url":"https://api.github.com/users/gentledevil/followers","following_url":"https://api.github.com/users/gentledevil/following{/other_user}","gists_url":"https://api.github.com/users/gentledevil/gists{/gist_id}","starred_url":"https://api.github.com/users/gentledevil/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gentledevil/subscriptions","organizations_url":"https://api.github.com/users/gentledevil/orgs","repos_url":"https://api.github.com/users/gentledevil/repos","events_url":"https://api.github.com/users/gentledevil/events{/privacy}","received_events_url":"https://api.github.com/users/gentledevil/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/gentledevil/ansible-modules-extras","description":"Ansible extra modules - these modules ship with ansible","fork":true,"url":"https://api.github.com/repos/gentledevil/ansible-modules-extras","forks_url":"https://api.github.com/repos/gentledevil/ansible-modules-extras/forks","keys_url":"https://api.github.com/repos/gentledevil/ansible-modules-extras/keys{/key_id}","collaborators_url":"https://api.github.com/repos/gentledevil/ansible-modules-extras/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/gentledevil/ansible-modules-extras/teams","hooks_url":"https://api.github.com/repos/gentledevil/ansible-modules-extras/hooks","issue_events_url":"https://api.github.com/repos/gentledevil/ansible-modules-extras/issues/events{/number}","events_url":"https://api.github.com/repos/gentledevil/ansible-modules-extras/events","assignees_url":"https://api.github.com/repos/gentledevil/ansible-modules-extras/assignees{/user}","branches_url":"https://api.github.com/repos/gentledevil/ansible-modules-extras/branches{/branch}","tags_url":"https://api.github.com/repos/gentledevil/ansible-modules-extras/tags","blobs_url":"https://api.github.com/repos/gentledevil/ansible-modules-extras/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/gentledevil/ansible-modules-extras/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/gentledevil/ansible-modules-extras/git/refs{/sha}","trees_url":"https://api.github.com/repos/gentledevil/ansible-modules-extras/git/trees{/sha}","statuses_url":"https://api.github.com/repos/gentledevil/ansible-modules-extras/statuses/{sha}","languages_url":"https://api.github.com/repos/gentledevil/ansible-modules-extras/languages","stargazers_url":"https://api.github.com/repos/gentledevil/ansible-modules-extras/stargazers","contributors_url":"https://api.github.com/repos/gentledevil/ansible-modules-extras/contributors","subscribers_url":"https://api.github.com/repos/gentledevil/ansible-modules-extras/subscribers","subscription_url":"https://api.github.com/repos/gentledevil/ansible-modules-extras/subscription","commits_url":"https://api.github.com/repos/gentledevil/ansible-modules-extras/commits{/sha}","git_commits_url":"https://api.github.com/repos/gentledevil/ansible-modules-extras/git/commits{/sha}","comments_url":"https://api.github.com/repos/gentledevil/ansible-modules-extras/comments{/number}","issue_comment_url":"https://api.github.com/repos/gentledevil/ansible-modules-extras/issues/comments{/number}","contents_url":"https://api.github.com/repos/gentledevil/ansible-modules-extras/contents/{+path}","compare_url":"https://api.github.com/repos/gentledevil/ansible-modules-extras/compare/{base}...{head}","merges_url":"https://api.github.com/repos/gentledevil/ansible-modules-extras/merges","archive_url":"https://api.github.com/repos/gentledevil/ansible-modules-extras/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/gentledevil/ansible-modules-extras/downloads","issues_url":"https://api.github.com/repos/gentledevil/ansible-modules-extras/issues{/number}","pulls_url":"https://api.github.com/repos/gentledevil/ansible-modules-extras/pulls{/number}","milestones_url":"https://api.github.com/repos/gentledevil/ansible-modules-extras/milestones{/number}","notifications_url":"https://api.github.com/repos/gentledevil/ansible-modules-extras/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/gentledevil/ansible-modules-extras/labels{/name}","releases_url":"https://api.github.com/repos/gentledevil/ansible-modules-extras/releases{/id}","created_at":"2015-06-05T16:16:28Z","updated_at":"2015-06-05T16:16:29Z","pushed_at":"2015-06-05T16:19:00Z","git_url":"git://github.com/gentledevil/ansible-modules-extras.git","ssh_url":"git@github.com:gentledevil/ansible-modules-extras.git","clone_url":"https://github.com/gentledevil/ansible-modules-extras.git","svn_url":"https://github.com/gentledevil/ansible-modules-extras","homepage":"","size":25097,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"devel"}},"base":{"label":"ansible:devel","ref":"devel","sha":"84b9ab435de312ddac377cb2f57f52da0a28f04d","user":{"login":"ansible","id":1507452,"avatar_url":"https://avatars.githubusercontent.com/u/1507452?v=3","gravatar_id":"","url":"https://api.github.com/users/ansible","html_url":"https://github.com/ansible","followers_url":"https://api.github.com/users/ansible/followers","following_url":"https://api.github.com/users/ansible/following{/other_user}","gists_url":"https://api.github.com/users/ansible/gists{/gist_id}","starred_url":"https://api.github.com/users/ansible/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ansible/subscriptions","organizations_url":"https://api.github.com/users/ansible/orgs","repos_url":"https://api.github.com/users/ansible/repos","events_url":"https://api.github.com/users/ansible/events{/privacy}","received_events_url":"https://api.github.com/users/ansible/received_events","type":"Organization","site_admin":false},"repo":{"id":24474138,"name":"ansible-modules-extras","full_name":"ansible/ansible-modules-extras","owner":{"login":"ansible","id":1507452,"avatar_url":"https://avatars.githubusercontent.com/u/1507452?v=3","gravatar_id":"","url":"https://api.github.com/users/ansible","html_url":"https://github.com/ansible","followers_url":"https://api.github.com/users/ansible/followers","following_url":"https://api.github.com/users/ansible/following{/other_user}","gists_url":"https://api.github.com/users/ansible/gists{/gist_id}","starred_url":"https://api.github.com/users/ansible/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ansible/subscriptions","organizations_url":"https://api.github.com/users/ansible/orgs","repos_url":"https://api.github.com/users/ansible/repos","events_url":"https://api.github.com/users/ansible/events{/privacy}","received_events_url":"https://api.github.com/users/ansible/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/ansible/ansible-modules-extras","description":"Ansible extra modules - these modules ship with ansible","fork":false,"url":"https://api.github.com/repos/ansible/ansible-modules-extras","forks_url":"https://api.github.com/repos/ansible/ansible-modules-extras/forks","keys_url":"https://api.github.com/repos/ansible/ansible-modules-extras/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ansible/ansible-modules-extras/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ansible/ansible-modules-extras/teams","hooks_url":"https://api.github.com/repos/ansible/ansible-modules-extras/hooks","issue_events_url":"https://api.github.com/repos/ansible/ansible-modules-extras/issues/events{/number}","events_url":"https://api.github.com/repos/ansible/ansible-modules-extras/events","assignees_url":"https://api.github.com/repos/ansible/ansible-modules-extras/assignees{/user}","branches_url":"https://api.github.com/repos/ansible/ansible-modules-extras/branches{/branch}","tags_url":"https://api.github.com/repos/ansible/ansible-modules-extras/tags","blobs_url":"https://api.github.com/repos/ansible/ansible-modules-extras/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ansible/ansible-modules-extras/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ansible/ansible-modules-extras/git/refs{/sha}","trees_url":"https://api.github.com/repos/ansible/ansible-modules-extras/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ansible/ansible-modules-extras/statuses/{sha}","languages_url":"https://api.github.com/repos/ansible/ansible-modules-extras/languages","stargazers_url":"https://api.github.com/repos/ansible/ansible-modules-extras/stargazers","contributors_url":"https://api.github.com/repos/ansible/ansible-modules-extras/contributors","subscribers_url":"https://api.github.com/repos/ansible/ansible-modules-extras/subscribers","subscription_url":"https://api.github.com/repos/ansible/ansible-modules-extras/subscription","commits_url":"https://api.github.com/repos/ansible/ansible-modules-extras/commits{/sha}","git_commits_url":"https://api.github.com/repos/ansible/ansible-modules-extras/git/commits{/sha}","comments_url":"https://api.github.com/repos/ansible/ansible-modules-extras/comments{/number}","issue_comment_url":"https://api.github.com/repos/ansible/ansible-modules-extras/issues/comments{/number}","contents_url":"https://api.github.com/repos/ansible/ansible-modules-extras/contents/{+path}","compare_url":"https://api.github.com/repos/ansible/ansible-modules-extras/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ansible/ansible-modules-extras/merges","archive_url":"https://api.github.com/repos/ansible/ansible-modules-extras/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ansible/ansible-modules-extras/downloads","issues_url":"https://api.github.com/repos/ansible/ansible-modules-extras/issues{/number}","pulls_url":"https://api.github.com/repos/ansible/ansible-modules-extras/pulls{/number}","milestones_url":"https://api.github.com/repos/ansible/ansible-modules-extras/milestones{/number}","notifications_url":"https://api.github.com/repos/ansible/ansible-modules-extras/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ansible/ansible-modules-extras/labels{/name}","releases_url":"https://api.github.com/repos/ansible/ansible-modules-extras/releases{/id}","created_at":"2014-09-25T20:28:42Z","updated_at":"2015-06-05T10:47:05Z","pushed_at":"2015-06-05T16:21:55Z","git_url":"git://github.com/ansible/ansible-modules-extras.git","ssh_url":"git@github.com:ansible/ansible-modules-extras.git","clone_url":"https://github.com/ansible/ansible-modules-extras.git","svn_url":"https://github.com/ansible/ansible-modules-extras","homepage":"","size":25097,"stargazers_count":226,"watchers_count":226,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":481,"mirror_url":null,"open_issues_count":197,"forks":481,"open_issues":197,"watchers":226,"default_branch":"devel"}},"_links":{"self":{"href":"https://api.github.com/repos/ansible/ansible-modules-extras/pulls/584"},"html":{"href":"https://github.com/ansible/ansible-modules-extras/pull/584"},"issue":{"href":"https://api.github.com/repos/ansible/ansible-modules-extras/issues/584"},"comments":{"href":"https://api.github.com/repos/ansible/ansible-modules-extras/issues/584/comments"},"review_comments":{"href":"https://api.github.com/repos/ansible/ansible-modules-extras/pulls/584/comments"},"review_comment":{"href":"https://api.github.com/repos/ansible/ansible-modules-extras/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/ansible/ansible-modules-extras/pulls/584/commits"},"statuses":{"href":"https://api.github.com/repos/ansible/ansible-modules-extras/statuses/ab8dbd90f9869b343573391c2639e17c15e10071"}}}}