{"action":"created","comment":{"url":"https://api.github.com/repos/Homebrew/brew/pulls/comments/194434732","pull_request_review_id":127605941,"id":194434732,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDE5NDQzNDczMg==","diff_hunk":"@@ -0,0 +1,56 @@\n+require \"formula\"\n+\n+# A meta-formula is a special kind of formula which will\n+# * Allow bulk management of several related formulae (only `install `now)\n+# * extend the semantics of 'dependency' to casks(TODO)\n+#\n+# As a result, {MetaFormula} differs from {Formula} in that\n+# * `url` is not mandatory\n+# * `version` is mandatory, (since it can not be deduced from `url` now)\n+# * the keg directory can be empty now (which will influence the \"empty installation\" check in audit.rb)\n+\n+class MetaFormula < Formula\n+  # Allow specs with no url\n+  def spec_eval(name)\n+    super\n+\n+    return unless name.equal? :stable\n+    # we allow :stable spec with no url here\n+    # unnecessary to keep three specs\n+    # if we do, {Formula#installed_prefix} will report an error when `brew install xxx`\n+    @stable = self.class.send(:stable)\n+    @stable.owner = self\n+    # `Formula#determine_active_spec` should now raise no \"formulae require at least a URL\" error\n+  end\n+\n+  # Ignore url error in attribute validation\n+  def validate_attributes!\n+    super\n+  rescue FormulaValidationError => e\n+    raise unless e.attr.equal? :url\n+  end\n+\n+  # Metaformula is not designed to be bottled for now\n+  def pour_bottle?\n+    false\n+  end\n+\n+  # DSL not designed to be used in MetaFormula for now are disabled to avoid undefined behaviors\n+  # This is subject to change if certain functions should be assigned to them\n+  def self.disable_dsl(name)\n+    old_method = method(name)\n+    define_singleton_method(name) do |*args, &block|\n+      if block\n+        opoo \"#{name} DSL is ignored in MetaFormula\"\n+      else\n+        old_method.call(*args)","path":"Library/Homebrew/metaformula.rb","position":46,"original_position":46,"commit_id":"01ca1a5bce662a5769460efc8bce95f3af498f41","original_commit_id":"01ca1a5bce662a5769460efc8bce95f3af498f41","user":{"login":"gigaflw","id":13916180,"node_id":"MDQ6VXNlcjEzOTE2MTgw","avatar_url":"https://avatars1.githubusercontent.com/u/13916180?v=4","gravatar_id":"","url":"https://api.github.com/users/gigaflw","html_url":"https://github.com/gigaflw","followers_url":"https://api.github.com/users/gigaflw/followers","following_url":"https://api.github.com/users/gigaflw/following{/other_user}","gists_url":"https://api.github.com/users/gigaflw/gists{/gist_id}","starred_url":"https://api.github.com/users/gigaflw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gigaflw/subscriptions","organizations_url":"https://api.github.com/users/gigaflw/orgs","repos_url":"https://api.github.com/users/gigaflw/repos","events_url":"https://api.github.com/users/gigaflw/events{/privacy}","received_events_url":"https://api.github.com/users/gigaflw/received_events","type":"User","site_admin":false},"body":"Oh. That's true. Then how about using caller to detect who calls the function ?\r\n```ruby\r\nif come_from_formula_file(caller(0)[1]) then\r\n   block_it\r\nelse\r\n   pass_through\r\nend\r\n```","created_at":"2018-06-11T14:57:08Z","updated_at":"2018-06-11T14:57:08Z","html_url":"https://github.com/Homebrew/brew/pull/4324#discussion_r194434732","pull_request_url":"https://api.github.com/repos/Homebrew/brew/pulls/4324","author_association":"NONE","_links":{"self":{"href":"https://api.github.com/repos/Homebrew/brew/pulls/comments/194434732"},"html":{"href":"https://github.com/Homebrew/brew/pull/4324#discussion_r194434732"},"pull_request":{"href":"https://api.github.com/repos/Homebrew/brew/pulls/4324"}},"in_reply_to_id":194319989},"pull_request":{"url":"https://api.github.com/repos/Homebrew/brew/pulls/4324","id":193829598,"node_id":"MDExOlB1bGxSZXF1ZXN0MTkzODI5NTk4","html_url":"https://github.com/Homebrew/brew/pull/4324","diff_url":"https://github.com/Homebrew/brew/pull/4324.diff","patch_url":"https://github.com/Homebrew/brew/pull/4324.patch","issue_url":"https://api.github.com/repos/Homebrew/brew/issues/4324","number":4324,"state":"open","locked":false,"title":"[WIP] Add meta-formula supprt","user":{"login":"gigaflw","id":13916180,"node_id":"MDQ6VXNlcjEzOTE2MTgw","avatar_url":"https://avatars1.githubusercontent.com/u/13916180?v=4","gravatar_id":"","url":"https://api.github.com/users/gigaflw","html_url":"https://github.com/gigaflw","followers_url":"https://api.github.com/users/gigaflw/followers","following_url":"https://api.github.com/users/gigaflw/following{/other_user}","gists_url":"https://api.github.com/users/gigaflw/gists{/gist_id}","starred_url":"https://api.github.com/users/gigaflw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gigaflw/subscriptions","organizations_url":"https://api.github.com/users/gigaflw/orgs","repos_url":"https://api.github.com/users/gigaflw/repos","events_url":"https://api.github.com/users/gigaflw/events{/privacy}","received_events_url":"https://api.github.com/users/gigaflw/received_events","type":"User","site_admin":false},"body":"- [x] Have you followed the guidelines in our [Contributing](https://github.com/Homebrew/brew/blob/master/CONTRIBUTING.md) document?\r\n- [x] Have you checked to ensure there aren't other open [Pull Requests](https://github.com/Homebrew/brew/pulls) for the same change?\r\n- [x] Have you added an explanation of what your changes do and why you'd like us to include them?\r\n- [ ] Have you written new tests for your changes? [Here's an example](https://github.com/Homebrew/homebrew/pull/49031).\r\n- [x] Have you successfully run `brew style` with your changes locally?\r\n- [x] Have you successfully run `brew tests` with your changes locally?\r\n\r\n-----\r\n\r\nHi! This is the first commit for GSoC project [add meta-formula support](https://github.com/Homebrew/gsoc/issues/10)\r\nHere I report my current progress.\r\n\r\nMeta-formula is a special kind of formula which will\r\n* Allow bulk management of several related formulae\r\n* extend the semantics of 'dependency' to casks\r\n\r\n## Usage\r\nIn this commit, the following use case is covered:\r\n```ruby\r\n# in metafoo.rb\r\nclass MetaFoo < MetaFormula\r\n    desc \"hello world\"\r\n    version \"0.1.0\"\t# mandatory, for `url` is not\r\n    depends_on \"dep_a\"\r\n    depends_on \"dep_b\"\r\nend\r\n```\r\nThen, in command line\r\n\r\n\t$ brew install metafoo   // dep_a and dep_b will be installed\r\n\r\nAfter this, `dep_a` and `dep_b` will be added as common dependencies, but `metafoo` will still have its own keg folder (PATH/Cellar/metafoo/0.1.0/...) even if it is empty. I think it might be better to keep the behavior of formula and metaformula consistent.\r\n\r\n## Files Changed\r\n\r\n**`Library/Homebrew/metaformula.rb`**\r\n\r\n`MetaFormula` is a subclass of `Formula` in which\r\n* `Formula#spec_eval` and `Formula#validate_attributes!` are overridden to allow a formula without a url attribute\r\n* certain DSL which is not designed to be used in MetaFormula are disabled for now to avoid undefined behavior\r\n\r\n```ruby\r\nclass MetaFormula < Formula\r\n    # override to allow spec without a url\r\n    def spec_eval(name); ...; end\r\n\r\n    # override to allow passing validation without a url\r\n    def validate_attributes!; ...; end\r\n\r\n    # disable undefined DSL\r\n    def self.disable_dsl(name); ...; end\r\n    disable_dsl :xxx\r\n     ...\r\nend\r\n```\r\n\r\n**`Library/Homebrew/download_strategy.rb`**\r\n\r\n`NoDownloadStrategy` is a new subclass of `AbstractDownloadStrategy` to accommodate the fact that `MetaFormula` can download nothing.\r\n\r\n```ruby\r\nclass NoDownloadStrategy < AbstractDownloadStrategy; end\r\n```\r\nThis class is set to be the default value of  `Resouce@download_strategy`. I think this is safe because whenever `url` is called (and it must be) in regular formula DSL, `Resouce@download_strategy` will be deduced and be set to a value other than `NoDownloadStrategy`.\r\nI still have the concern of changing the default behavior of these stable code though, let me know if I am not doing this right.\r\n\r\n**`Library/Homebrew/resource.rb`**\r\nAnd some code is added to use the class:\r\n \r\n```ruby\r\nclass Resource\r\n    def initialize\r\n        ...\r\n        @download_strategy = NoDownloadStrategy  # use this as default\r\n    end\r\n    def stage\r\n        ...\r\n\t# do not download if NoDownloadStrategy\r\n        verify_download_integrity(fetch) unless @download_strategy == NoDownloadStrategy\r\n        ...\r\n    end\r\n    ...\r\nend\r\n```\r\n## Future Work\r\nThis commit only covers a small part of the intended functions. Future work includes\r\n* Dependency on casks\r\n* Bulk management other than `install` (upgrade, uninstall, etc.) \r\n\r\nLet me know if I am doing anything improperly :pray: and I'll try my best to improve. Thanks!","created_at":"2018-06-10T14:40:34Z","updated_at":"2018-06-11T14:57:08Z","closed_at":null,"merged_at":null,"merge_commit_sha":"1e0dc483af25ed7c4ff5072e77f40b280a084086","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/Homebrew/brew/pulls/4324/commits","review_comments_url":"https://api.github.com/repos/Homebrew/brew/pulls/4324/comments","review_comment_url":"https://api.github.com/repos/Homebrew/brew/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Homebrew/brew/issues/4324/comments","statuses_url":"https://api.github.com/repos/Homebrew/brew/statuses/01ca1a5bce662a5769460efc8bce95f3af498f41","head":{"label":"gigaflw:metaformula","ref":"metaformula","sha":"01ca1a5bce662a5769460efc8bce95f3af498f41","user":{"login":"gigaflw","id":13916180,"node_id":"MDQ6VXNlcjEzOTE2MTgw","avatar_url":"https://avatars1.githubusercontent.com/u/13916180?v=4","gravatar_id":"","url":"https://api.github.com/users/gigaflw","html_url":"https://github.com/gigaflw","followers_url":"https://api.github.com/users/gigaflw/followers","following_url":"https://api.github.com/users/gigaflw/following{/other_user}","gists_url":"https://api.github.com/users/gigaflw/gists{/gist_id}","starred_url":"https://api.github.com/users/gigaflw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gigaflw/subscriptions","organizations_url":"https://api.github.com/users/gigaflw/orgs","repos_url":"https://api.github.com/users/gigaflw/repos","events_url":"https://api.github.com/users/gigaflw/events{/privacy}","received_events_url":"https://api.github.com/users/gigaflw/received_events","type":"User","site_admin":false},"repo":{"id":134128390,"node_id":"MDEwOlJlcG9zaXRvcnkxMzQxMjgzOTA=","name":"brew","full_name":"gigaflw/brew","owner":{"login":"gigaflw","id":13916180,"node_id":"MDQ6VXNlcjEzOTE2MTgw","avatar_url":"https://avatars1.githubusercontent.com/u/13916180?v=4","gravatar_id":"","url":"https://api.github.com/users/gigaflw","html_url":"https://github.com/gigaflw","followers_url":"https://api.github.com/users/gigaflw/followers","following_url":"https://api.github.com/users/gigaflw/following{/other_user}","gists_url":"https://api.github.com/users/gigaflw/gists{/gist_id}","starred_url":"https://api.github.com/users/gigaflw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gigaflw/subscriptions","organizations_url":"https://api.github.com/users/gigaflw/orgs","repos_url":"https://api.github.com/users/gigaflw/repos","events_url":"https://api.github.com/users/gigaflw/events{/privacy}","received_events_url":"https://api.github.com/users/gigaflw/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/gigaflw/brew","description":"🍺 The missing package manager for macOS","fork":true,"url":"https://api.github.com/repos/gigaflw/brew","forks_url":"https://api.github.com/repos/gigaflw/brew/forks","keys_url":"https://api.github.com/repos/gigaflw/brew/keys{/key_id}","collaborators_url":"https://api.github.com/repos/gigaflw/brew/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/gigaflw/brew/teams","hooks_url":"https://api.github.com/repos/gigaflw/brew/hooks","issue_events_url":"https://api.github.com/repos/gigaflw/brew/issues/events{/number}","events_url":"https://api.github.com/repos/gigaflw/brew/events","assignees_url":"https://api.github.com/repos/gigaflw/brew/assignees{/user}","branches_url":"https://api.github.com/repos/gigaflw/brew/branches{/branch}","tags_url":"https://api.github.com/repos/gigaflw/brew/tags","blobs_url":"https://api.github.com/repos/gigaflw/brew/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/gigaflw/brew/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/gigaflw/brew/git/refs{/sha}","trees_url":"https://api.github.com/repos/gigaflw/brew/git/trees{/sha}","statuses_url":"https://api.github.com/repos/gigaflw/brew/statuses/{sha}","languages_url":"https://api.github.com/repos/gigaflw/brew/languages","stargazers_url":"https://api.github.com/repos/gigaflw/brew/stargazers","contributors_url":"https://api.github.com/repos/gigaflw/brew/contributors","subscribers_url":"https://api.github.com/repos/gigaflw/brew/subscribers","subscription_url":"https://api.github.com/repos/gigaflw/brew/subscription","commits_url":"https://api.github.com/repos/gigaflw/brew/commits{/sha}","git_commits_url":"https://api.github.com/repos/gigaflw/brew/git/commits{/sha}","comments_url":"https://api.github.com/repos/gigaflw/brew/comments{/number}","issue_comment_url":"https://api.github.com/repos/gigaflw/brew/issues/comments{/number}","contents_url":"https://api.github.com/repos/gigaflw/brew/contents/{+path}","compare_url":"https://api.github.com/repos/gigaflw/brew/compare/{base}...{head}","merges_url":"https://api.github.com/repos/gigaflw/brew/merges","archive_url":"https://api.github.com/repos/gigaflw/brew/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/gigaflw/brew/downloads","issues_url":"https://api.github.com/repos/gigaflw/brew/issues{/number}","pulls_url":"https://api.github.com/repos/gigaflw/brew/pulls{/number}","milestones_url":"https://api.github.com/repos/gigaflw/brew/milestones{/number}","notifications_url":"https://api.github.com/repos/gigaflw/brew/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/gigaflw/brew/labels{/name}","releases_url":"https://api.github.com/repos/gigaflw/brew/releases{/id}","deployments_url":"https://api.github.com/repos/gigaflw/brew/deployments","created_at":"2018-05-20T07:19:05Z","updated_at":"2018-05-20T07:19:10Z","pushed_at":"2018-06-10T14:24:08Z","git_url":"git://github.com/gigaflw/brew.git","ssh_url":"git@github.com:gigaflw/brew.git","clone_url":"https://github.com/gigaflw/brew.git","svn_url":"https://github.com/gigaflw/brew","homepage":"https://brew.sh","size":23825,"stargazers_count":0,"watchers_count":0,"language":"Ruby","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"bsd-2-clause","name":"BSD 2-Clause \"Simplified\" License","spdx_id":"BSD-2-Clause","url":"https://api.github.com/licenses/bsd-2-clause","node_id":"MDc6TGljZW5zZTQ="},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"Homebrew:master","ref":"master","sha":"5614f114ef6423192f182c9bb9d8f047d15aa5ca","user":{"login":"Homebrew","id":1503512,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE1MDM1MTI=","avatar_url":"https://avatars2.githubusercontent.com/u/1503512?v=4","gravatar_id":"","url":"https://api.github.com/users/Homebrew","html_url":"https://github.com/Homebrew","followers_url":"https://api.github.com/users/Homebrew/followers","following_url":"https://api.github.com/users/Homebrew/following{/other_user}","gists_url":"https://api.github.com/users/Homebrew/gists{/gist_id}","starred_url":"https://api.github.com/users/Homebrew/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Homebrew/subscriptions","organizations_url":"https://api.github.com/users/Homebrew/orgs","repos_url":"https://api.github.com/users/Homebrew/repos","events_url":"https://api.github.com/users/Homebrew/events{/privacy}","received_events_url":"https://api.github.com/users/Homebrew/received_events","type":"Organization","site_admin":false},"repo":{"id":53238813,"node_id":"MDEwOlJlcG9zaXRvcnk1MzIzODgxMw==","name":"brew","full_name":"Homebrew/brew","owner":{"login":"Homebrew","id":1503512,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE1MDM1MTI=","avatar_url":"https://avatars2.githubusercontent.com/u/1503512?v=4","gravatar_id":"","url":"https://api.github.com/users/Homebrew","html_url":"https://github.com/Homebrew","followers_url":"https://api.github.com/users/Homebrew/followers","following_url":"https://api.github.com/users/Homebrew/following{/other_user}","gists_url":"https://api.github.com/users/Homebrew/gists{/gist_id}","starred_url":"https://api.github.com/users/Homebrew/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Homebrew/subscriptions","organizations_url":"https://api.github.com/users/Homebrew/orgs","repos_url":"https://api.github.com/users/Homebrew/repos","events_url":"https://api.github.com/users/Homebrew/events{/privacy}","received_events_url":"https://api.github.com/users/Homebrew/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Homebrew/brew","description":"🍺 The missing package manager for macOS","fork":false,"url":"https://api.github.com/repos/Homebrew/brew","forks_url":"https://api.github.com/repos/Homebrew/brew/forks","keys_url":"https://api.github.com/repos/Homebrew/brew/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Homebrew/brew/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Homebrew/brew/teams","hooks_url":"https://api.github.com/repos/Homebrew/brew/hooks","issue_events_url":"https://api.github.com/repos/Homebrew/brew/issues/events{/number}","events_url":"https://api.github.com/repos/Homebrew/brew/events","assignees_url":"https://api.github.com/repos/Homebrew/brew/assignees{/user}","branches_url":"https://api.github.com/repos/Homebrew/brew/branches{/branch}","tags_url":"https://api.github.com/repos/Homebrew/brew/tags","blobs_url":"https://api.github.com/repos/Homebrew/brew/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Homebrew/brew/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Homebrew/brew/git/refs{/sha}","trees_url":"https://api.github.com/repos/Homebrew/brew/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Homebrew/brew/statuses/{sha}","languages_url":"https://api.github.com/repos/Homebrew/brew/languages","stargazers_url":"https://api.github.com/repos/Homebrew/brew/stargazers","contributors_url":"https://api.github.com/repos/Homebrew/brew/contributors","subscribers_url":"https://api.github.com/repos/Homebrew/brew/subscribers","subscription_url":"https://api.github.com/repos/Homebrew/brew/subscription","commits_url":"https://api.github.com/repos/Homebrew/brew/commits{/sha}","git_commits_url":"https://api.github.com/repos/Homebrew/brew/git/commits{/sha}","comments_url":"https://api.github.com/repos/Homebrew/brew/comments{/number}","issue_comment_url":"https://api.github.com/repos/Homebrew/brew/issues/comments{/number}","contents_url":"https://api.github.com/repos/Homebrew/brew/contents/{+path}","compare_url":"https://api.github.com/repos/Homebrew/brew/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Homebrew/brew/merges","archive_url":"https://api.github.com/repos/Homebrew/brew/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Homebrew/brew/downloads","issues_url":"https://api.github.com/repos/Homebrew/brew/issues{/number}","pulls_url":"https://api.github.com/repos/Homebrew/brew/pulls{/number}","milestones_url":"https://api.github.com/repos/Homebrew/brew/milestones{/number}","notifications_url":"https://api.github.com/repos/Homebrew/brew/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Homebrew/brew/labels{/name}","releases_url":"https://api.github.com/repos/Homebrew/brew/releases{/id}","deployments_url":"https://api.github.com/repos/Homebrew/brew/deployments","created_at":"2016-03-06T05:08:38Z","updated_at":"2018-06-11T13:29:16Z","pushed_at":"2018-06-11T14:39:09Z","git_url":"git://github.com/Homebrew/brew.git","ssh_url":"git@github.com:Homebrew/brew.git","clone_url":"https://github.com/Homebrew/brew.git","svn_url":"https://github.com/Homebrew/brew","homepage":"https://brew.sh","size":24082,"stargazers_count":12539,"watchers_count":12539,"language":"Ruby","has_issues":true,"has_projects":false,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":2914,"mirror_url":null,"archived":false,"open_issues_count":36,"license":{"key":"bsd-2-clause","name":"BSD 2-Clause \"Simplified\" License","spdx_id":"BSD-2-Clause","url":"https://api.github.com/licenses/bsd-2-clause","node_id":"MDc6TGljZW5zZTQ="},"forks":2914,"open_issues":36,"watchers":12539,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Homebrew/brew/pulls/4324"},"html":{"href":"https://github.com/Homebrew/brew/pull/4324"},"issue":{"href":"https://api.github.com/repos/Homebrew/brew/issues/4324"},"comments":{"href":"https://api.github.com/repos/Homebrew/brew/issues/4324/comments"},"review_comments":{"href":"https://api.github.com/repos/Homebrew/brew/pulls/4324/comments"},"review_comment":{"href":"https://api.github.com/repos/Homebrew/brew/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Homebrew/brew/pulls/4324/commits"},"statuses":{"href":"https://api.github.com/repos/Homebrew/brew/statuses/01ca1a5bce662a5769460efc8bce95f3af498f41"}},"author_association":"NONE"}}
{"actor":{"display_login":"gigaflw"}}