{"action":"created","comment":{"url":"https://api.github.com/repos/SUSE/machinery/pulls/comments/66425147","id":66425147,"diff_hunk":"@@ -0,0 +1,204 @@\n+# Copyright (c) 2013-2016 SUSE LLC\n+#\n+# This program is free software; you can redistribute it and/or\n+# modify it under the terms of version 3 of the GNU General Public License as\n+# published by the Free Software Foundation.\n+#\n+# This program 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 this program; if not, contact SUSE LLC.\n+#\n+# To contact SUSE about this file by physical or electronic mail,\n+# you may find current contact information at www.suse.com\n+\n+require_relative \"spec_helper\"\n+\n+describe Machinery::Query do\n+\n+  let(:store) {\n+    SystemDescriptionStore.new(\n+      File.join(Machinery::ROOT, 'spec/data/descriptions/jeos'))\n+  }\n+\n+  let(:opensuse131) { SystemDescription.load!('opensuse131', store) }\n+  let(:opensuse132) { SystemDescription.load!('opensuse132', store) }\n+\n+  describe Machinery::Query::Element do\n+\n+    let(:packages_scope) { opensuse131['packages'] }\n+    let(:users_scope) { opensuse131['users'] }\n+ \n+    let(:full_element) { Machinery::Query::Element.new(\"zypper\", \"version\") }\n+    let(:simple_element) { Machinery::Query::Element.new(\"root\") }\n+\n+    describe \"#eval\" do\n+\n+      it 'evalutates a element + attribute' do\n+        expect(full_element.eval(packages_scope).result).to eq \"1.9.16\"\n+      end\n+\n+      it 'returns the whole object if no attribute is given' do\n+        result = simple_element.eval(users_scope).result\n+        expect(result).to be_a(User)\n+        expect(result.name).to eq('root')\n+      end\n+    end\n+  end\n+\n+  describe Machinery::Query::Value do\n+    let(:scalar) { Machinery::Query::Value.new(:scalar, \"4.12\") }\n+    let(:array) { Machinery::Query::Value.new(:array, [\"1\", \"2\", \"3\"]) }\n+\n+    describe '#evaluate' do\n+      it 'returns a scalar if filled with a scalar' do\n+        expect(scalar.eval(opensuse131).result).to eq('4.12')\n+      end\n+\n+      it 'returns a array if filled with a array' do\n+        expect(array.eval(opensuse131).result).to be_a(Array)\n+      end\n+    end\n+  end\n+\n+  describe Machinery::Query::Scope do\n+    let(:element) { Machinery::Query::Element.new(\"zypper\", \"version\") }\n+\n+    subject { Machinery::Query::Scope.new(\"packages\", element) }\n+    \n+    describe '#evaluate' do\n+      it 'evaluates to a actual value' do\n+        result = subject.eval(opensuse131).result\n+        expect(result).to be_a(String)\n+        expect(result).to eq(\"1.9.16\")\n+      end\n+    end\n+  end\n+\n+  describe Machinery::Query::Operator do\n+    let(:zypper_version) { Machinery::Query::Element.new(\"zypper\", \"version\") }\n+    let(:root) { Machinery::Query::Element.new(\"root\") }\n+\n+    let(:packages_scope) { Machinery::Query::Scope.new(\"packages\", zypper_version) }\n+    let(:users_scope) { Machinery::Query::Scope.new(\"users\", root) }\n+\n+    let(:value) { Machinery::Query::Value.new(:scalar, \"1.9.16\") }\n+    let(:value_less) { Machinery::Query::Value.new(:scalar, \"1.8.17\") }\n+\n+    let(:equal) { Machinery::Query::Operator.new('==', packages_scope, value) }\n+    let(:unequal) { Machinery::Query::Operator.new('!=', packages_scope, value) }\n+    let(:exists) { Machinery::Query::Operator.new('exist', users_scope, nil) }\n+    let(:greater) { Machinery::Query::Operator.new('>', packages_scope, value_less) }\n+    let(:lesser) { Machinery::Query::Operator.new('<', packages_scope, value_less) }\n+\n+    describe '#evaluate' do\n+      it 'evalutate a complete statement testing the (==) operator' do\n+        expect(equal.eval(opensuse131).result).to eq(true)\n+      end\n+\n+      it 'evalutate a complete statement testing the (!=) operator' do\n+        expect(unequal.eval(opensuse131).result).to eq(false)\n+      end\n+\n+      it 'evalutate a complete statement testing the (exist) operator' do\n+        expect(exists.eval(opensuse131).result).to eq(true)\n+      end\n+\n+      it 'evalutate a complete statement testing the (>) operator' do","path":"spec/unit/query_spec.rb","position":110,"original_position":110,"commit_id":"8941d22cf48b673433e8d4e9cdbd3165fa412822","original_commit_id":"8941d22cf48b673433e8d4e9cdbd3165fa412822","user":{"login":"houndci-bot","id":6697940,"avatar_url":"https://avatars.githubusercontent.com/u/6697940?v=3","gravatar_id":"","url":"https://api.github.com/users/houndci-bot","html_url":"https://github.com/houndci-bot","followers_url":"https://api.github.com/users/houndci-bot/followers","following_url":"https://api.github.com/users/houndci-bot/following{/other_user}","gists_url":"https://api.github.com/users/houndci-bot/gists{/gist_id}","starred_url":"https://api.github.com/users/houndci-bot/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/houndci-bot/subscriptions","organizations_url":"https://api.github.com/users/houndci-bot/orgs","repos_url":"https://api.github.com/users/houndci-bot/repos","events_url":"https://api.github.com/users/houndci-bot/events{/privacy}","received_events_url":"https://api.github.com/users/houndci-bot/received_events","type":"User","site_admin":false},"body":"Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.","created_at":"2016-06-09T11:38:33Z","updated_at":"2016-06-09T11:38:33Z","html_url":"https://github.com/SUSE/machinery/pull/2106#discussion_r66425147","pull_request_url":"https://api.github.com/repos/SUSE/machinery/pulls/2106","_links":{"self":{"href":"https://api.github.com/repos/SUSE/machinery/pulls/comments/66425147"},"html":{"href":"https://github.com/SUSE/machinery/pull/2106#discussion_r66425147"},"pull_request":{"href":"https://api.github.com/repos/SUSE/machinery/pulls/2106"}}},"pull_request":{"url":"https://api.github.com/repos/SUSE/machinery/pulls/2106","id":73198889,"html_url":"https://github.com/SUSE/machinery/pull/2106","diff_url":"https://github.com/SUSE/machinery/pull/2106.diff","patch_url":"https://github.com/SUSE/machinery/pull/2106.patch","issue_url":"https://api.github.com/repos/SUSE/machinery/issues/2106","number":2106,"state":"open","locked":false,"title":"Add query command feature","user":{"login":"felixsch","id":4460715,"avatar_url":"https://avatars.githubusercontent.com/u/4460715?v=3","gravatar_id":"","url":"https://api.github.com/users/felixsch","html_url":"https://github.com/felixsch","followers_url":"https://api.github.com/users/felixsch/followers","following_url":"https://api.github.com/users/felixsch/following{/other_user}","gists_url":"https://api.github.com/users/felixsch/gists{/gist_id}","starred_url":"https://api.github.com/users/felixsch/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/felixsch/subscriptions","organizations_url":"https://api.github.com/users/felixsch/orgs","repos_url":"https://api.github.com/users/felixsch/repos","events_url":"https://api.github.com/users/felixsch/events{/privacy}","received_events_url":"https://api.github.com/users/felixsch/received_events","type":"User","site_admin":false},"body":"Hey Hey,\r\n\r\nDue lack of creativity what to program next (at home and break),  I looked up the mentoring page of openSUSE and found [this](https://github.com/openSUSE/mentoring/issues/33) nice project.\r\nI implemented a basic version using [ragel](http://www.colm.net/open-source/ragel/) to parse a simple query language.\r\n\r\nA query consists of _scope element[:attribute] operator value_ such as\r\n\r\n* `packages zypper:version > 1.9.10`\r\n* `users root exist`\r\n* `packages zypper exist && packages zypper:version > 1.9`\r\n\r\n\r\nExample:\r\n\r\n```\r\nx250 ❯ machinery query \"packages zypper:version > 1.10.0 || users felixsch exist\" \r\nMatched: 192.168.2.112\r\n  -- felixsch exists\r\n  ++ 1.12.37 > 1.10.0\r\n\r\nMatched: 192.168.2.115\r\n  ++ felixsch exists\r\n  ++ 1.12.37 > 1.10.0\r\n\r\nMatched: opensuse132\r\n  -- felixsch exists\r\n  ++ 1.11.14 > 1.10.0\r\n\r\nMatched: opensuse_leap\r\n  -- felixsch exists\r\n  ++ 1.12.23 > 1.10.0\r\n\r\nTotal found: 4\r\n```\r\n\r\n__Current problems__:\r\n\r\n- __Casting issues__:\r\n  -  Currently its possible to run a query without attribute tag -> How to convert a element when compared to an integer `e.g packages zypper >= 1.9.10` (default to element.name?)\r\n  - I'm not really sure how to safely parse version numbers without breaking all other number comparisions. Currently the code uses a regex to determine if a string has the form \"1.9xx\" or \"1.9.1xx\", everything else is casted to integer.\r\n- __Error handling__: Currently the code prints out where an parsing error was found or when parsing failed. I bet this can improved\r\n- __Output__: I implemented a basic output which is able to show what matched and what failed to match. `e.g ++ 1.9.16 == 1.9.16` maybe this can be made more readable\r\n- __Performance__: Because it works file based, speed depends on the performance of the json parser. I implemented threaded reading but this will not solve the problem if, say more than 200 manifest needs to be read\r\n\r\nWhat do you think is needed to make this a successfull pull request?","created_at":"2016-06-09T11:38:23Z","updated_at":"2016-06-09T11:38:33Z","closed_at":null,"merged_at":null,"merge_commit_sha":"6f7c939a36d30b10fc22cebec5b17d701d89dec6","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/SUSE/machinery/pulls/2106/commits","review_comments_url":"https://api.github.com/repos/SUSE/machinery/pulls/2106/comments","review_comment_url":"https://api.github.com/repos/SUSE/machinery/pulls/comments{/number}","comments_url":"https://api.github.com/repos/SUSE/machinery/issues/2106/comments","statuses_url":"https://api.github.com/repos/SUSE/machinery/statuses/8941d22cf48b673433e8d4e9cdbd3165fa412822","head":{"label":"felixsch:query-feature","ref":"query-feature","sha":"8941d22cf48b673433e8d4e9cdbd3165fa412822","user":{"login":"felixsch","id":4460715,"avatar_url":"https://avatars.githubusercontent.com/u/4460715?v=3","gravatar_id":"","url":"https://api.github.com/users/felixsch","html_url":"https://github.com/felixsch","followers_url":"https://api.github.com/users/felixsch/followers","following_url":"https://api.github.com/users/felixsch/following{/other_user}","gists_url":"https://api.github.com/users/felixsch/gists{/gist_id}","starred_url":"https://api.github.com/users/felixsch/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/felixsch/subscriptions","organizations_url":"https://api.github.com/users/felixsch/orgs","repos_url":"https://api.github.com/users/felixsch/repos","events_url":"https://api.github.com/users/felixsch/events{/privacy}","received_events_url":"https://api.github.com/users/felixsch/received_events","type":"User","site_admin":false},"repo":{"id":60192540,"name":"machinery","full_name":"felixsch/machinery","owner":{"login":"felixsch","id":4460715,"avatar_url":"https://avatars.githubusercontent.com/u/4460715?v=3","gravatar_id":"","url":"https://api.github.com/users/felixsch","html_url":"https://github.com/felixsch","followers_url":"https://api.github.com/users/felixsch/followers","following_url":"https://api.github.com/users/felixsch/following{/other_user}","gists_url":"https://api.github.com/users/felixsch/gists{/gist_id}","starred_url":"https://api.github.com/users/felixsch/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/felixsch/subscriptions","organizations_url":"https://api.github.com/users/felixsch/orgs","repos_url":"https://api.github.com/users/felixsch/repos","events_url":"https://api.github.com/users/felixsch/events{/privacy}","received_events_url":"https://api.github.com/users/felixsch/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/felixsch/machinery","description":"A systems management toolkit for Linux","fork":true,"url":"https://api.github.com/repos/felixsch/machinery","forks_url":"https://api.github.com/repos/felixsch/machinery/forks","keys_url":"https://api.github.com/repos/felixsch/machinery/keys{/key_id}","collaborators_url":"https://api.github.com/repos/felixsch/machinery/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/felixsch/machinery/teams","hooks_url":"https://api.github.com/repos/felixsch/machinery/hooks","issue_events_url":"https://api.github.com/repos/felixsch/machinery/issues/events{/number}","events_url":"https://api.github.com/repos/felixsch/machinery/events","assignees_url":"https://api.github.com/repos/felixsch/machinery/assignees{/user}","branches_url":"https://api.github.com/repos/felixsch/machinery/branches{/branch}","tags_url":"https://api.github.com/repos/felixsch/machinery/tags","blobs_url":"https://api.github.com/repos/felixsch/machinery/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/felixsch/machinery/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/felixsch/machinery/git/refs{/sha}","trees_url":"https://api.github.com/repos/felixsch/machinery/git/trees{/sha}","statuses_url":"https://api.github.com/repos/felixsch/machinery/statuses/{sha}","languages_url":"https://api.github.com/repos/felixsch/machinery/languages","stargazers_url":"https://api.github.com/repos/felixsch/machinery/stargazers","contributors_url":"https://api.github.com/repos/felixsch/machinery/contributors","subscribers_url":"https://api.github.com/repos/felixsch/machinery/subscribers","subscription_url":"https://api.github.com/repos/felixsch/machinery/subscription","commits_url":"https://api.github.com/repos/felixsch/machinery/commits{/sha}","git_commits_url":"https://api.github.com/repos/felixsch/machinery/git/commits{/sha}","comments_url":"https://api.github.com/repos/felixsch/machinery/comments{/number}","issue_comment_url":"https://api.github.com/repos/felixsch/machinery/issues/comments{/number}","contents_url":"https://api.github.com/repos/felixsch/machinery/contents/{+path}","compare_url":"https://api.github.com/repos/felixsch/machinery/compare/{base}...{head}","merges_url":"https://api.github.com/repos/felixsch/machinery/merges","archive_url":"https://api.github.com/repos/felixsch/machinery/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/felixsch/machinery/downloads","issues_url":"https://api.github.com/repos/felixsch/machinery/issues{/number}","pulls_url":"https://api.github.com/repos/felixsch/machinery/pulls{/number}","milestones_url":"https://api.github.com/repos/felixsch/machinery/milestones{/number}","notifications_url":"https://api.github.com/repos/felixsch/machinery/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/felixsch/machinery/labels{/name}","releases_url":"https://api.github.com/repos/felixsch/machinery/releases{/id}","deployments_url":"https://api.github.com/repos/felixsch/machinery/deployments","created_at":"2016-06-01T16:15:48Z","updated_at":"2016-06-01T16:15:50Z","pushed_at":"2016-06-09T11:23:40Z","git_url":"git://github.com/felixsch/machinery.git","ssh_url":"git@github.com:felixsch/machinery.git","clone_url":"https://github.com/felixsch/machinery.git","svn_url":"https://github.com/felixsch/machinery","homepage":"machinery-project.org","size":10996,"stargazers_count":0,"watchers_count":0,"language":"Ruby","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"SUSE:master","ref":"master","sha":"1a64562f80da624a1581edf53b11514c358d0de5","user":{"login":"SUSE","id":1067733,"avatar_url":"https://avatars.githubusercontent.com/u/1067733?v=3","gravatar_id":"","url":"https://api.github.com/users/SUSE","html_url":"https://github.com/SUSE","followers_url":"https://api.github.com/users/SUSE/followers","following_url":"https://api.github.com/users/SUSE/following{/other_user}","gists_url":"https://api.github.com/users/SUSE/gists{/gist_id}","starred_url":"https://api.github.com/users/SUSE/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/SUSE/subscriptions","organizations_url":"https://api.github.com/users/SUSE/orgs","repos_url":"https://api.github.com/users/SUSE/repos","events_url":"https://api.github.com/users/SUSE/events{/privacy}","received_events_url":"https://api.github.com/users/SUSE/received_events","type":"Organization","site_admin":false},"repo":{"id":21424418,"name":"machinery","full_name":"SUSE/machinery","owner":{"login":"SUSE","id":1067733,"avatar_url":"https://avatars.githubusercontent.com/u/1067733?v=3","gravatar_id":"","url":"https://api.github.com/users/SUSE","html_url":"https://github.com/SUSE","followers_url":"https://api.github.com/users/SUSE/followers","following_url":"https://api.github.com/users/SUSE/following{/other_user}","gists_url":"https://api.github.com/users/SUSE/gists{/gist_id}","starred_url":"https://api.github.com/users/SUSE/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/SUSE/subscriptions","organizations_url":"https://api.github.com/users/SUSE/orgs","repos_url":"https://api.github.com/users/SUSE/repos","events_url":"https://api.github.com/users/SUSE/events{/privacy}","received_events_url":"https://api.github.com/users/SUSE/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/SUSE/machinery","description":"A systems management toolkit for Linux","fork":false,"url":"https://api.github.com/repos/SUSE/machinery","forks_url":"https://api.github.com/repos/SUSE/machinery/forks","keys_url":"https://api.github.com/repos/SUSE/machinery/keys{/key_id}","collaborators_url":"https://api.github.com/repos/SUSE/machinery/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/SUSE/machinery/teams","hooks_url":"https://api.github.com/repos/SUSE/machinery/hooks","issue_events_url":"https://api.github.com/repos/SUSE/machinery/issues/events{/number}","events_url":"https://api.github.com/repos/SUSE/machinery/events","assignees_url":"https://api.github.com/repos/SUSE/machinery/assignees{/user}","branches_url":"https://api.github.com/repos/SUSE/machinery/branches{/branch}","tags_url":"https://api.github.com/repos/SUSE/machinery/tags","blobs_url":"https://api.github.com/repos/SUSE/machinery/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/SUSE/machinery/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/SUSE/machinery/git/refs{/sha}","trees_url":"https://api.github.com/repos/SUSE/machinery/git/trees{/sha}","statuses_url":"https://api.github.com/repos/SUSE/machinery/statuses/{sha}","languages_url":"https://api.github.com/repos/SUSE/machinery/languages","stargazers_url":"https://api.github.com/repos/SUSE/machinery/stargazers","contributors_url":"https://api.github.com/repos/SUSE/machinery/contributors","subscribers_url":"https://api.github.com/repos/SUSE/machinery/subscribers","subscription_url":"https://api.github.com/repos/SUSE/machinery/subscription","commits_url":"https://api.github.com/repos/SUSE/machinery/commits{/sha}","git_commits_url":"https://api.github.com/repos/SUSE/machinery/git/commits{/sha}","comments_url":"https://api.github.com/repos/SUSE/machinery/comments{/number}","issue_comment_url":"https://api.github.com/repos/SUSE/machinery/issues/comments{/number}","contents_url":"https://api.github.com/repos/SUSE/machinery/contents/{+path}","compare_url":"https://api.github.com/repos/SUSE/machinery/compare/{base}...{head}","merges_url":"https://api.github.com/repos/SUSE/machinery/merges","archive_url":"https://api.github.com/repos/SUSE/machinery/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/SUSE/machinery/downloads","issues_url":"https://api.github.com/repos/SUSE/machinery/issues{/number}","pulls_url":"https://api.github.com/repos/SUSE/machinery/pulls{/number}","milestones_url":"https://api.github.com/repos/SUSE/machinery/milestones{/number}","notifications_url":"https://api.github.com/repos/SUSE/machinery/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/SUSE/machinery/labels{/name}","releases_url":"https://api.github.com/repos/SUSE/machinery/releases{/id}","deployments_url":"https://api.github.com/repos/SUSE/machinery/deployments","created_at":"2014-07-02T13:07:04Z","updated_at":"2016-06-01T00:13:49Z","pushed_at":"2016-06-09T11:38:24Z","git_url":"git://github.com/SUSE/machinery.git","ssh_url":"git@github.com:SUSE/machinery.git","clone_url":"https://github.com/SUSE/machinery.git","svn_url":"https://github.com/SUSE/machinery","homepage":"machinery-project.org","size":62721,"stargazers_count":91,"watchers_count":91,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":22,"mirror_url":null,"open_issues_count":44,"forks":22,"open_issues":44,"watchers":91,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/SUSE/machinery/pulls/2106"},"html":{"href":"https://github.com/SUSE/machinery/pull/2106"},"issue":{"href":"https://api.github.com/repos/SUSE/machinery/issues/2106"},"comments":{"href":"https://api.github.com/repos/SUSE/machinery/issues/2106/comments"},"review_comments":{"href":"https://api.github.com/repos/SUSE/machinery/pulls/2106/comments"},"review_comment":{"href":"https://api.github.com/repos/SUSE/machinery/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/SUSE/machinery/pulls/2106/commits"},"statuses":{"href":"https://api.github.com/repos/SUSE/machinery/statuses/8941d22cf48b673433e8d4e9cdbd3165fa412822"}}}}
{"actor":{"display_login":"houndci-bot"}}