{"action":"created","comment":{"url":"https://api.github.com/repos/chef/chef-rfc/pulls/comments/29405097","id":29405097,"diff_hunk":"@@ -0,0 +1,147 @@\n+---\n+RFC: unassigned\n+Author: John Keiser <john@johnkeiser.com>\n+Status: Draft\n+Type: Standards Track\n+---\n+\n+# Resource Actions\n+\n+In this proposal, we allow actions to be specified as recipes, directly in resources.\n+\n+## Motivation\n+\n+    As a Chef user,\n+    I want to be able to write actions in resources,\n+    so that I don't have to learn and reason about `Provider`s (less friction).\n+\n+    As a Chef user,\n+    I want to be able to write actions in resources,\n+    so that I don't have to switch contexts to understand what resources do.\n+\n+    As a Chef user,\n+    I want actions to be specified as recipes by default,\n+    so that I can use concepts I already know to create good test-and-set resources.\n+\n+## Specification\n+\n+To create an action on a resource, users specify `action <action> do ... end`.\n+The recipe in between the do ... end block will be run when the action is\n+performed.\n+\n+```ruby\n+class MyResource < Chef::Resource::LWRPBase\n+  attribute :path, name_attribute: true\n+  attribute :content\n+  attribute :mode\n+\n+  action :create do\n+    ruby_block \"Update content of #{path}\" do\n+      only_if { content != IO.read(path) }\n+      block { IO.write(path, content) }\n+    end\n+\n+    execute \"Update mode of #{path}\" do\n+      not_if { File.stat(path).mode == mode }\n+      command \"chmod #{mode} #{path}\"\n+    end\n+  end\n+end\n+```\n+\n+There is no change to providers or the way we run actions.  This is just a way\n+of defining a provider without having to type or think about the word.  Providers\n+do not go away, so much as become a secondary concept, a sort of house for the\n+primary concept of actions.\n+\n+`action` will work for any resource extending from `Chef::Resource`.\n+\n+### Action details\n+\n+#### Action recipe execution\n+\n+The action recipe works like a Chef run, in that it is an isolated resource\n+collection and runs actions and notifications the same way as a top level Chef\n+run.\n+\n+- The entire action recipe is compiled (just like a normal recipe) before\n+  converging.\n+- This compile happens when the action is *run*, not when the parent resource\n+  is declared.\n+- Delayed and immediate notifications are local to the action.\n+\n+This is equivalent to what `use_inline_resources` in an LWRP does, and we will\n+keep them orthogonal as much as possible.\n+\n+#### Action composition and inheritance\n+\n+The action recipes are all added to a `Provider` class which inherits from the\n+parent resource's provider class.  You may call `super` to call the parent\n+class's version of the current action.\n+\n+```ruby\n+class MyFile < Chef::Resource::File\n+  action :create do\n+    puts \"I am a file yo\"\n+    super()\n+  end\n+end\n+```\n+\n+### inline_recipe resource\n+\n+People need to support test-and-set and why-run in their resources. Given that\n+actions are defined as recipes, the typical (and best) way to do that is\n+resources (which have `not_if` and `only_if`, etc.). These resources work well,\n+but sometimes you want to do a clump of actions based on a single `if`, or you\n+want to nest them.\n+\n+`inline_recipe` is designed to do that job.  resource lets you write recipe\n+code. It also has the parent in scope (so you can still access instance\n+variables). The resources inside will compile immediately and be available in\n+`inline_recipe.resources`.  The resources will converge when the `inline_recipe`\n+converges.\n+\n+Like recipe actions, the resources inside the `inline_recipe` are not\n+referenceable by `notifies` outside.  Unlike recipe actions, the resources show\n+up in nested output (because the user typed them in the recipe).\n+\n+```ruby\n+inline_recipe 'Create that one file' do\n+  only_if { File.exist?('/please_create_that_file.txt') }\n+\n+  directory '/x' do\n+  end\n+  file '/x/y.txt' do\n+  end\n+end\n+```\n+\n+`converge_by` (the current way of converging / updating) a resource will still\n+be available for those who are used to it.\n+\n+## Changes to existing things\n+\n+### Resource\n+\n+We add the following public API to `Resource`:\n+\n+- `self.action(action, class: nil, &block)`: creates a Provider with the given\n+  action\n+\n+And modify the following:\n+\n+- `allowed_actions`: defaults to all actions in the resource's provider class(es).\n+- `default_action`: defaults to `allowed_actions.first`.\n+\n+### Provider\n+\n+Resources in LWRP actions will no longer report in output as nested actions","path":"new/resource-actions.md","position":139,"original_position":139,"commit_id":"dc9ae219deb135cf17612db2ab10ea749fd168d3","original_commit_id":"dc9ae219deb135cf17612db2ab10ea749fd168d3","user":{"login":"jkeiser","id":654882,"avatar_url":"https://avatars.githubusercontent.com/u/654882?v=3","gravatar_id":"","url":"https://api.github.com/users/jkeiser","html_url":"https://github.com/jkeiser","followers_url":"https://api.github.com/users/jkeiser/followers","following_url":"https://api.github.com/users/jkeiser/following{/other_user}","gists_url":"https://api.github.com/users/jkeiser/gists{/gist_id}","starred_url":"https://api.github.com/users/jkeiser/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jkeiser/subscriptions","organizations_url":"https://api.github.com/users/jkeiser/orgs","repos_url":"https://api.github.com/users/jkeiser/repos","events_url":"https://api.github.com/users/jkeiser/events{/privacy}","received_events_url":"https://api.github.com/users/jkeiser/received_events","type":"User","site_admin":false},"body":"Yeah, I didn't realize this section was still here.  It's not meant to be.","created_at":"2015-04-30T05:50:10Z","updated_at":"2015-04-30T05:50:10Z","html_url":"https://github.com/chef/chef-rfc/pull/121#discussion_r29405097","pull_request_url":"https://api.github.com/repos/chef/chef-rfc/pulls/121","_links":{"self":{"href":"https://api.github.com/repos/chef/chef-rfc/pulls/comments/29405097"},"html":{"href":"https://github.com/chef/chef-rfc/pull/121#discussion_r29405097"},"pull_request":{"href":"https://api.github.com/repos/chef/chef-rfc/pulls/121"}}},"pull_request":{"url":"https://api.github.com/repos/chef/chef-rfc/pulls/121","id":34410921,"html_url":"https://github.com/chef/chef-rfc/pull/121","diff_url":"https://github.com/chef/chef-rfc/pull/121.diff","patch_url":"https://github.com/chef/chef-rfc/pull/121.patch","issue_url":"https://api.github.com/repos/chef/chef-rfc/issues/121","number":121,"state":"open","locked":false,"title":"Define actions directly on resources","user":{"login":"jkeiser","id":654882,"avatar_url":"https://avatars.githubusercontent.com/u/654882?v=3","gravatar_id":"","url":"https://api.github.com/users/jkeiser","html_url":"https://github.com/jkeiser","followers_url":"https://api.github.com/users/jkeiser/followers","following_url":"https://api.github.com/users/jkeiser/following{/other_user}","gists_url":"https://api.github.com/users/jkeiser/gists{/gist_id}","starred_url":"https://api.github.com/users/jkeiser/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jkeiser/subscriptions","organizations_url":"https://api.github.com/users/jkeiser/orgs","repos_url":"https://api.github.com/users/jkeiser/repos","events_url":"https://api.github.com/users/jkeiser/events{/privacy}","received_events_url":"https://api.github.com/users/jkeiser/received_events","type":"User","site_admin":false},"body":"","created_at":"2015-04-29T22:04:22Z","updated_at":"2015-04-30T05:50:10Z","closed_at":null,"merged_at":null,"merge_commit_sha":"1a35ce670bd493c10009d46c74f697bc99a8ddf0","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/chef/chef-rfc/pulls/121/commits","review_comments_url":"https://api.github.com/repos/chef/chef-rfc/pulls/121/comments","review_comment_url":"https://api.github.com/repos/chef/chef-rfc/pulls/comments{/number}","comments_url":"https://api.github.com/repos/chef/chef-rfc/issues/121/comments","statuses_url":"https://api.github.com/repos/chef/chef-rfc/statuses/dc9ae219deb135cf17612db2ab10ea749fd168d3","head":{"label":"chef:jk/resource-actions","ref":"jk/resource-actions","sha":"dc9ae219deb135cf17612db2ab10ea749fd168d3","user":{"login":"chef","id":29740,"avatar_url":"https://avatars.githubusercontent.com/u/29740?v=3","gravatar_id":"","url":"https://api.github.com/users/chef","html_url":"https://github.com/chef","followers_url":"https://api.github.com/users/chef/followers","following_url":"https://api.github.com/users/chef/following{/other_user}","gists_url":"https://api.github.com/users/chef/gists{/gist_id}","starred_url":"https://api.github.com/users/chef/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chef/subscriptions","organizations_url":"https://api.github.com/users/chef/orgs","repos_url":"https://api.github.com/users/chef/repos","events_url":"https://api.github.com/users/chef/events{/privacy}","received_events_url":"https://api.github.com/users/chef/received_events","type":"Organization","site_admin":false},"repo":{"id":15090814,"name":"chef-rfc","full_name":"chef/chef-rfc","owner":{"login":"chef","id":29740,"avatar_url":"https://avatars.githubusercontent.com/u/29740?v=3","gravatar_id":"","url":"https://api.github.com/users/chef","html_url":"https://github.com/chef","followers_url":"https://api.github.com/users/chef/followers","following_url":"https://api.github.com/users/chef/following{/other_user}","gists_url":"https://api.github.com/users/chef/gists{/gist_id}","starred_url":"https://api.github.com/users/chef/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chef/subscriptions","organizations_url":"https://api.github.com/users/chef/orgs","repos_url":"https://api.github.com/users/chef/repos","events_url":"https://api.github.com/users/chef/events{/privacy}","received_events_url":"https://api.github.com/users/chef/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/chef/chef-rfc","description":"Public RFCs for Chef and related projects","fork":false,"url":"https://api.github.com/repos/chef/chef-rfc","forks_url":"https://api.github.com/repos/chef/chef-rfc/forks","keys_url":"https://api.github.com/repos/chef/chef-rfc/keys{/key_id}","collaborators_url":"https://api.github.com/repos/chef/chef-rfc/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/chef/chef-rfc/teams","hooks_url":"https://api.github.com/repos/chef/chef-rfc/hooks","issue_events_url":"https://api.github.com/repos/chef/chef-rfc/issues/events{/number}","events_url":"https://api.github.com/repos/chef/chef-rfc/events","assignees_url":"https://api.github.com/repos/chef/chef-rfc/assignees{/user}","branches_url":"https://api.github.com/repos/chef/chef-rfc/branches{/branch}","tags_url":"https://api.github.com/repos/chef/chef-rfc/tags","blobs_url":"https://api.github.com/repos/chef/chef-rfc/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/chef/chef-rfc/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/chef/chef-rfc/git/refs{/sha}","trees_url":"https://api.github.com/repos/chef/chef-rfc/git/trees{/sha}","statuses_url":"https://api.github.com/repos/chef/chef-rfc/statuses/{sha}","languages_url":"https://api.github.com/repos/chef/chef-rfc/languages","stargazers_url":"https://api.github.com/repos/chef/chef-rfc/stargazers","contributors_url":"https://api.github.com/repos/chef/chef-rfc/contributors","subscribers_url":"https://api.github.com/repos/chef/chef-rfc/subscribers","subscription_url":"https://api.github.com/repos/chef/chef-rfc/subscription","commits_url":"https://api.github.com/repos/chef/chef-rfc/commits{/sha}","git_commits_url":"https://api.github.com/repos/chef/chef-rfc/git/commits{/sha}","comments_url":"https://api.github.com/repos/chef/chef-rfc/comments{/number}","issue_comment_url":"https://api.github.com/repos/chef/chef-rfc/issues/comments{/number}","contents_url":"https://api.github.com/repos/chef/chef-rfc/contents/{+path}","compare_url":"https://api.github.com/repos/chef/chef-rfc/compare/{base}...{head}","merges_url":"https://api.github.com/repos/chef/chef-rfc/merges","archive_url":"https://api.github.com/repos/chef/chef-rfc/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/chef/chef-rfc/downloads","issues_url":"https://api.github.com/repos/chef/chef-rfc/issues{/number}","pulls_url":"https://api.github.com/repos/chef/chef-rfc/pulls{/number}","milestones_url":"https://api.github.com/repos/chef/chef-rfc/milestones{/number}","notifications_url":"https://api.github.com/repos/chef/chef-rfc/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/chef/chef-rfc/labels{/name}","releases_url":"https://api.github.com/repos/chef/chef-rfc/releases{/id}","created_at":"2013-12-10T22:10:56Z","updated_at":"2015-04-28T15:56:28Z","pushed_at":"2015-04-29T22:52:04Z","git_url":"git://github.com/chef/chef-rfc.git","ssh_url":"git@github.com:chef/chef-rfc.git","clone_url":"https://github.com/chef/chef-rfc.git","svn_url":"https://github.com/chef/chef-rfc","homepage":null,"size":3316,"stargazers_count":78,"watchers_count":78,"language":null,"has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":35,"mirror_url":null,"open_issues_count":18,"forks":35,"open_issues":18,"watchers":78,"default_branch":"master"}},"base":{"label":"chef:master","ref":"master","sha":"f977b43b5e8d33e80045d4ddcf223bb664a371be","user":{"login":"chef","id":29740,"avatar_url":"https://avatars.githubusercontent.com/u/29740?v=3","gravatar_id":"","url":"https://api.github.com/users/chef","html_url":"https://github.com/chef","followers_url":"https://api.github.com/users/chef/followers","following_url":"https://api.github.com/users/chef/following{/other_user}","gists_url":"https://api.github.com/users/chef/gists{/gist_id}","starred_url":"https://api.github.com/users/chef/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chef/subscriptions","organizations_url":"https://api.github.com/users/chef/orgs","repos_url":"https://api.github.com/users/chef/repos","events_url":"https://api.github.com/users/chef/events{/privacy}","received_events_url":"https://api.github.com/users/chef/received_events","type":"Organization","site_admin":false},"repo":{"id":15090814,"name":"chef-rfc","full_name":"chef/chef-rfc","owner":{"login":"chef","id":29740,"avatar_url":"https://avatars.githubusercontent.com/u/29740?v=3","gravatar_id":"","url":"https://api.github.com/users/chef","html_url":"https://github.com/chef","followers_url":"https://api.github.com/users/chef/followers","following_url":"https://api.github.com/users/chef/following{/other_user}","gists_url":"https://api.github.com/users/chef/gists{/gist_id}","starred_url":"https://api.github.com/users/chef/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chef/subscriptions","organizations_url":"https://api.github.com/users/chef/orgs","repos_url":"https://api.github.com/users/chef/repos","events_url":"https://api.github.com/users/chef/events{/privacy}","received_events_url":"https://api.github.com/users/chef/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/chef/chef-rfc","description":"Public RFCs for Chef and related projects","fork":false,"url":"https://api.github.com/repos/chef/chef-rfc","forks_url":"https://api.github.com/repos/chef/chef-rfc/forks","keys_url":"https://api.github.com/repos/chef/chef-rfc/keys{/key_id}","collaborators_url":"https://api.github.com/repos/chef/chef-rfc/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/chef/chef-rfc/teams","hooks_url":"https://api.github.com/repos/chef/chef-rfc/hooks","issue_events_url":"https://api.github.com/repos/chef/chef-rfc/issues/events{/number}","events_url":"https://api.github.com/repos/chef/chef-rfc/events","assignees_url":"https://api.github.com/repos/chef/chef-rfc/assignees{/user}","branches_url":"https://api.github.com/repos/chef/chef-rfc/branches{/branch}","tags_url":"https://api.github.com/repos/chef/chef-rfc/tags","blobs_url":"https://api.github.com/repos/chef/chef-rfc/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/chef/chef-rfc/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/chef/chef-rfc/git/refs{/sha}","trees_url":"https://api.github.com/repos/chef/chef-rfc/git/trees{/sha}","statuses_url":"https://api.github.com/repos/chef/chef-rfc/statuses/{sha}","languages_url":"https://api.github.com/repos/chef/chef-rfc/languages","stargazers_url":"https://api.github.com/repos/chef/chef-rfc/stargazers","contributors_url":"https://api.github.com/repos/chef/chef-rfc/contributors","subscribers_url":"https://api.github.com/repos/chef/chef-rfc/subscribers","subscription_url":"https://api.github.com/repos/chef/chef-rfc/subscription","commits_url":"https://api.github.com/repos/chef/chef-rfc/commits{/sha}","git_commits_url":"https://api.github.com/repos/chef/chef-rfc/git/commits{/sha}","comments_url":"https://api.github.com/repos/chef/chef-rfc/comments{/number}","issue_comment_url":"https://api.github.com/repos/chef/chef-rfc/issues/comments{/number}","contents_url":"https://api.github.com/repos/chef/chef-rfc/contents/{+path}","compare_url":"https://api.github.com/repos/chef/chef-rfc/compare/{base}...{head}","merges_url":"https://api.github.com/repos/chef/chef-rfc/merges","archive_url":"https://api.github.com/repos/chef/chef-rfc/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/chef/chef-rfc/downloads","issues_url":"https://api.github.com/repos/chef/chef-rfc/issues{/number}","pulls_url":"https://api.github.com/repos/chef/chef-rfc/pulls{/number}","milestones_url":"https://api.github.com/repos/chef/chef-rfc/milestones{/number}","notifications_url":"https://api.github.com/repos/chef/chef-rfc/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/chef/chef-rfc/labels{/name}","releases_url":"https://api.github.com/repos/chef/chef-rfc/releases{/id}","created_at":"2013-12-10T22:10:56Z","updated_at":"2015-04-28T15:56:28Z","pushed_at":"2015-04-29T22:52:04Z","git_url":"git://github.com/chef/chef-rfc.git","ssh_url":"git@github.com:chef/chef-rfc.git","clone_url":"https://github.com/chef/chef-rfc.git","svn_url":"https://github.com/chef/chef-rfc","homepage":null,"size":3316,"stargazers_count":78,"watchers_count":78,"language":null,"has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":35,"mirror_url":null,"open_issues_count":18,"forks":35,"open_issues":18,"watchers":78,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/chef/chef-rfc/pulls/121"},"html":{"href":"https://github.com/chef/chef-rfc/pull/121"},"issue":{"href":"https://api.github.com/repos/chef/chef-rfc/issues/121"},"comments":{"href":"https://api.github.com/repos/chef/chef-rfc/issues/121/comments"},"review_comments":{"href":"https://api.github.com/repos/chef/chef-rfc/pulls/121/comments"},"review_comment":{"href":"https://api.github.com/repos/chef/chef-rfc/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/chef/chef-rfc/pulls/121/commits"},"statuses":{"href":"https://api.github.com/repos/chef/chef-rfc/statuses/dc9ae219deb135cf17612db2ab10ea749fd168d3"}}}}