{"action":"created","comment":{"url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/pulls/comments/67151170","id":67151170,"diff_hunk":"@@ -60,4 +60,66 @@ module Create() = struct\n   let warning f = message Warning ~section:name f\n   let error f = message Error ~section:name f\n \n+  module Config = struct\n+    let plugin_name = name\n+    include Bap_config\n+\n+    let (/) = Filename.concat\n+    let confdir = confdir / plugin_name\n+    let conf_filename = confdir / \"config\"\n+\n+    let get_env_options () =\n+      let prefix = \"BAP_\" ^ String.uppercase plugin_name ^ \"_\" in\n+      let prefix_chop_key (k, v) =\n+        match String.chop_prefix ~prefix k with\n+        | Some k -> Some (k, v)\n+        | None -> None in\n+      let plugin_filter_map str =\n+        match String.split str ~on:'=' with\n+        | k :: vs -> prefix_chop_key (k, String.concat ~sep:\"=\" vs)\n+        | [] -> None in\n+      Unix.environment () |>\n+      Array.to_list |>\n+      List.filter_map ~f:plugin_filter_map\n+\n+    let conf_file_options () =\n+      let string_splitter str =\n+        match String.split str ~on:'=' with\n+        | k :: vs -> k, String.concat ~sep:\"=\" vs\n+        | [] -> invalid_arg \"empty string\" in\n+      let split_filter = List.map ~f:string_splitter in\n+      try\n+        In_channel.with_file\n+          conf_filename ~f:(fun ch -> In_channel.input_lines ch\n+                                      |> split_filter)\n+      with Sys_error _ -> []\n+\n+    let options () =\n+      get_env_options () |>\n+      List.fold ~init:(conf_file_options ())\n+        ~f:(fun o (k, v) -> List.Assoc.add o k v)\n+\n+    let get = options () |> List.Assoc.find ~equal:String.Caseless.equal\n+\n+    let set ~name ~data =\n+      let name = String.lowercase name in\n+      let old_conf = conf_file_options () in\n+      let remaining_conf = List.Assoc.remove old_conf name in\n+      let new_conf = List.Assoc.add remaining_conf name data in\n+      let conf_lines = List.map new_conf ~f:(fun (k, v) -> k ^ \"=\" ^ v) in\n+      let write_lines () = Out_channel.write_lines\n+          conf_filename conf_lines in\n+      try","path":"lib/bap/bap_self.ml","position":53,"original_position":53,"commit_id":"f75445defccd6f9edbb1a6a069e2ba1bc707b2bd","original_commit_id":"f75445defccd6f9edbb1a6a069e2ba1bc707b2bd","user":{"login":"ivg","id":2336698,"avatar_url":"https://avatars.githubusercontent.com/u/2336698?v=3","gravatar_id":"","url":"https://api.github.com/users/ivg","html_url":"https://github.com/ivg","followers_url":"https://api.github.com/users/ivg/followers","following_url":"https://api.github.com/users/ivg/following{/other_user}","gists_url":"https://api.github.com/users/ivg/gists{/gist_id}","starred_url":"https://api.github.com/users/ivg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ivg/subscriptions","organizations_url":"https://api.github.com/users/ivg/orgs","repos_url":"https://api.github.com/users/ivg/repos","events_url":"https://api.github.com/users/ivg/events{/privacy}","received_events_url":"https://api.github.com/users/ivg/received_events","type":"User","site_admin":false},"body":"I still think that using exceptions for control flow here is unjustified. Use `Sys.is_directory` and `Sys.file_exists` to ensure the precondition. ","created_at":"2016-06-15T12:25:47Z","updated_at":"2016-06-15T12:25:47Z","html_url":"https://github.com/BinaryAnalysisPlatform/bap/pull/468#discussion_r67151170","pull_request_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/pulls/468","_links":{"self":{"href":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/pulls/comments/67151170"},"html":{"href":"https://github.com/BinaryAnalysisPlatform/bap/pull/468#discussion_r67151170"},"pull_request":{"href":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/pulls/468"}}},"pull_request":{"url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/pulls/468","id":73815857,"html_url":"https://github.com/BinaryAnalysisPlatform/bap/pull/468","diff_url":"https://github.com/BinaryAnalysisPlatform/bap/pull/468.diff","patch_url":"https://github.com/BinaryAnalysisPlatform/bap/pull/468.patch","issue_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/issues/468","number":468,"state":"open","locked":false,"title":"Allow runtime configuration of plugins","user":{"login":"jaybosamiya","id":5683582,"avatar_url":"https://avatars.githubusercontent.com/u/5683582?v=3","gravatar_id":"","url":"https://api.github.com/users/jaybosamiya","html_url":"https://github.com/jaybosamiya","followers_url":"https://api.github.com/users/jaybosamiya/followers","following_url":"https://api.github.com/users/jaybosamiya/following{/other_user}","gists_url":"https://api.github.com/users/jaybosamiya/gists{/gist_id}","starred_url":"https://api.github.com/users/jaybosamiya/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jaybosamiya/subscriptions","organizations_url":"https://api.github.com/users/jaybosamiya/orgs","repos_url":"https://api.github.com/users/jaybosamiya/repos","events_url":"https://api.github.com/users/jaybosamiya/events{/privacy}","received_events_url":"https://api.github.com/users/jaybosamiya/received_events","type":"User","site_admin":false},"body":"### Background\r\n\r\nPreviously, one could access compilation time configuration information in plugins through `Config` (for example, `Config.version` used commonly in many plugins). However, this would not allow for runtime configuration.\r\n\r\n### Current PR\r\n\r\nThis PR adds the ability for plugins to\r\n+ `Config.get name` -- get the value assigned to `name`\r\n+ `Config.set name data` -- assign `name` to value `data`\r\n+ `Config.options ()` -- get a list of all options that are currently set for the plugin\r\n\r\nEach plugin stores its options in its own subdirectory within a configuration directory that is localized to that specific installation of bap. This allows users to have multiple installations of bap with many different plugins using same/similar names, and still not have conflicts.\r\n\r\nAlso, the configuration values can be overridden for some runs using environment variables. For example, consider a plugin `P`. If the configuration file for `P` has a variable `K` set to `V1`, but the user executes bap using `BAP_P_K=V2 bap`, then `Config.get \"K\"` returns `V2`. This allows users to modify configuration for single runs if they wish to.\r\n\r\n### Design decisions\r\n\r\n+ The configuration format is chosen to be a key-value dictionary with both key and value being strings. This allows users to come up with their own serialization format if they want/need to.\r\n+ The configuration storage format is abstracted away from the user (and the developer of the plugin)\r\n    + This allows us to change it later if we wish to, without upsetting users\r\n+ Plugin developer can get a list of _all_ set values for configuration as a `(string*string) list`, which can be used for caching etc (i.e. if configuration changes, usually it means that the cached value should not be used).\r\n+ Each plugin stores its configuration separately\r\n    + This means that no plugin unwittingly clobbers the configuration of another\r\n    + It also allows users to targettedly configure plugins\r\n+ Configuration variable names are case insensitive. This is due to the logical reason configuration variable names should be descriptive, and not confusing due to different capitalizations having different meaning.\r\n+ Internally, the configuration (currently) is stored as a bunch of files on the `confdir` directory. Each plugin stores in a flat text file `PLUGINNAME/config`, and each line corresponds to one key-value pair (stored in the format `KEY=VALUE`).\r\n+ Environment variable overriding - Using the format `BAP_PLUGINNAME_CONFIGVARNAME=CONFIGVALUE`, one can override the corresponding config variable.","created_at":"2016-06-14T21:21:14Z","updated_at":"2016-06-15T12:25:47Z","closed_at":null,"merged_at":null,"merge_commit_sha":"19a1ec336f22e92f1aed9c56cb49af706fab656e","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/pulls/468/commits","review_comments_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/pulls/468/comments","review_comment_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/pulls/comments{/number}","comments_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/issues/468/comments","statuses_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/statuses/f75445defccd6f9edbb1a6a069e2ba1bc707b2bd","head":{"label":"jaybosamiya:bap-config","ref":"bap-config","sha":"f75445defccd6f9edbb1a6a069e2ba1bc707b2bd","user":{"login":"jaybosamiya","id":5683582,"avatar_url":"https://avatars.githubusercontent.com/u/5683582?v=3","gravatar_id":"","url":"https://api.github.com/users/jaybosamiya","html_url":"https://github.com/jaybosamiya","followers_url":"https://api.github.com/users/jaybosamiya/followers","following_url":"https://api.github.com/users/jaybosamiya/following{/other_user}","gists_url":"https://api.github.com/users/jaybosamiya/gists{/gist_id}","starred_url":"https://api.github.com/users/jaybosamiya/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jaybosamiya/subscriptions","organizations_url":"https://api.github.com/users/jaybosamiya/orgs","repos_url":"https://api.github.com/users/jaybosamiya/repos","events_url":"https://api.github.com/users/jaybosamiya/events{/privacy}","received_events_url":"https://api.github.com/users/jaybosamiya/received_events","type":"User","site_admin":false},"repo":{"id":59225447,"name":"bap","full_name":"jaybosamiya/bap","owner":{"login":"jaybosamiya","id":5683582,"avatar_url":"https://avatars.githubusercontent.com/u/5683582?v=3","gravatar_id":"","url":"https://api.github.com/users/jaybosamiya","html_url":"https://github.com/jaybosamiya","followers_url":"https://api.github.com/users/jaybosamiya/followers","following_url":"https://api.github.com/users/jaybosamiya/following{/other_user}","gists_url":"https://api.github.com/users/jaybosamiya/gists{/gist_id}","starred_url":"https://api.github.com/users/jaybosamiya/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jaybosamiya/subscriptions","organizations_url":"https://api.github.com/users/jaybosamiya/orgs","repos_url":"https://api.github.com/users/jaybosamiya/repos","events_url":"https://api.github.com/users/jaybosamiya/events{/privacy}","received_events_url":"https://api.github.com/users/jaybosamiya/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/jaybosamiya/bap","description":"BAP Core Library","fork":true,"url":"https://api.github.com/repos/jaybosamiya/bap","forks_url":"https://api.github.com/repos/jaybosamiya/bap/forks","keys_url":"https://api.github.com/repos/jaybosamiya/bap/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jaybosamiya/bap/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jaybosamiya/bap/teams","hooks_url":"https://api.github.com/repos/jaybosamiya/bap/hooks","issue_events_url":"https://api.github.com/repos/jaybosamiya/bap/issues/events{/number}","events_url":"https://api.github.com/repos/jaybosamiya/bap/events","assignees_url":"https://api.github.com/repos/jaybosamiya/bap/assignees{/user}","branches_url":"https://api.github.com/repos/jaybosamiya/bap/branches{/branch}","tags_url":"https://api.github.com/repos/jaybosamiya/bap/tags","blobs_url":"https://api.github.com/repos/jaybosamiya/bap/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jaybosamiya/bap/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jaybosamiya/bap/git/refs{/sha}","trees_url":"https://api.github.com/repos/jaybosamiya/bap/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jaybosamiya/bap/statuses/{sha}","languages_url":"https://api.github.com/repos/jaybosamiya/bap/languages","stargazers_url":"https://api.github.com/repos/jaybosamiya/bap/stargazers","contributors_url":"https://api.github.com/repos/jaybosamiya/bap/contributors","subscribers_url":"https://api.github.com/repos/jaybosamiya/bap/subscribers","subscription_url":"https://api.github.com/repos/jaybosamiya/bap/subscription","commits_url":"https://api.github.com/repos/jaybosamiya/bap/commits{/sha}","git_commits_url":"https://api.github.com/repos/jaybosamiya/bap/git/commits{/sha}","comments_url":"https://api.github.com/repos/jaybosamiya/bap/comments{/number}","issue_comment_url":"https://api.github.com/repos/jaybosamiya/bap/issues/comments{/number}","contents_url":"https://api.github.com/repos/jaybosamiya/bap/contents/{+path}","compare_url":"https://api.github.com/repos/jaybosamiya/bap/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jaybosamiya/bap/merges","archive_url":"https://api.github.com/repos/jaybosamiya/bap/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jaybosamiya/bap/downloads","issues_url":"https://api.github.com/repos/jaybosamiya/bap/issues{/number}","pulls_url":"https://api.github.com/repos/jaybosamiya/bap/pulls{/number}","milestones_url":"https://api.github.com/repos/jaybosamiya/bap/milestones{/number}","notifications_url":"https://api.github.com/repos/jaybosamiya/bap/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jaybosamiya/bap/labels{/name}","releases_url":"https://api.github.com/repos/jaybosamiya/bap/releases{/id}","deployments_url":"https://api.github.com/repos/jaybosamiya/bap/deployments","created_at":"2016-05-19T16:52:50Z","updated_at":"2016-05-26T10:00:12Z","pushed_at":"2016-06-14T22:49:53Z","git_url":"git://github.com/jaybosamiya/bap.git","ssh_url":"git@github.com:jaybosamiya/bap.git","clone_url":"https://github.com/jaybosamiya/bap.git","svn_url":"https://github.com/jaybosamiya/bap","homepage":null,"size":2728,"stargazers_count":2,"watchers_count":2,"language":"OCaml","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":2,"default_branch":"master"}},"base":{"label":"BinaryAnalysisPlatform:master","ref":"master","sha":"a64d5b5744b9db0a9917797f83493cd18dc7c421","user":{"login":"BinaryAnalysisPlatform","id":8669375,"avatar_url":"https://avatars.githubusercontent.com/u/8669375?v=3","gravatar_id":"","url":"https://api.github.com/users/BinaryAnalysisPlatform","html_url":"https://github.com/BinaryAnalysisPlatform","followers_url":"https://api.github.com/users/BinaryAnalysisPlatform/followers","following_url":"https://api.github.com/users/BinaryAnalysisPlatform/following{/other_user}","gists_url":"https://api.github.com/users/BinaryAnalysisPlatform/gists{/gist_id}","starred_url":"https://api.github.com/users/BinaryAnalysisPlatform/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/BinaryAnalysisPlatform/subscriptions","organizations_url":"https://api.github.com/users/BinaryAnalysisPlatform/orgs","repos_url":"https://api.github.com/users/BinaryAnalysisPlatform/repos","events_url":"https://api.github.com/users/BinaryAnalysisPlatform/events{/privacy}","received_events_url":"https://api.github.com/users/BinaryAnalysisPlatform/received_events","type":"Organization","site_admin":false},"repo":{"id":25968851,"name":"bap","full_name":"BinaryAnalysisPlatform/bap","owner":{"login":"BinaryAnalysisPlatform","id":8669375,"avatar_url":"https://avatars.githubusercontent.com/u/8669375?v=3","gravatar_id":"","url":"https://api.github.com/users/BinaryAnalysisPlatform","html_url":"https://github.com/BinaryAnalysisPlatform","followers_url":"https://api.github.com/users/BinaryAnalysisPlatform/followers","following_url":"https://api.github.com/users/BinaryAnalysisPlatform/following{/other_user}","gists_url":"https://api.github.com/users/BinaryAnalysisPlatform/gists{/gist_id}","starred_url":"https://api.github.com/users/BinaryAnalysisPlatform/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/BinaryAnalysisPlatform/subscriptions","organizations_url":"https://api.github.com/users/BinaryAnalysisPlatform/orgs","repos_url":"https://api.github.com/users/BinaryAnalysisPlatform/repos","events_url":"https://api.github.com/users/BinaryAnalysisPlatform/events{/privacy}","received_events_url":"https://api.github.com/users/BinaryAnalysisPlatform/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/BinaryAnalysisPlatform/bap","description":"BAP Core Library","fork":false,"url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap","forks_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/forks","keys_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/keys{/key_id}","collaborators_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/teams","hooks_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/hooks","issue_events_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/issues/events{/number}","events_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/events","assignees_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/assignees{/user}","branches_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/branches{/branch}","tags_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/tags","blobs_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/git/refs{/sha}","trees_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/git/trees{/sha}","statuses_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/statuses/{sha}","languages_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/languages","stargazers_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/stargazers","contributors_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/contributors","subscribers_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/subscribers","subscription_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/subscription","commits_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/commits{/sha}","git_commits_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/git/commits{/sha}","comments_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/comments{/number}","issue_comment_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/issues/comments{/number}","contents_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/contents/{+path}","compare_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/compare/{base}...{head}","merges_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/merges","archive_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/downloads","issues_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/issues{/number}","pulls_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/pulls{/number}","milestones_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/milestones{/number}","notifications_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/labels{/name}","releases_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/releases{/id}","deployments_url":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/deployments","created_at":"2014-10-30T11:59:43Z","updated_at":"2016-06-15T08:37:27Z","pushed_at":"2016-06-14T22:49:54Z","git_url":"git://github.com/BinaryAnalysisPlatform/bap.git","ssh_url":"git@github.com:BinaryAnalysisPlatform/bap.git","clone_url":"https://github.com/BinaryAnalysisPlatform/bap.git","svn_url":"https://github.com/BinaryAnalysisPlatform/bap","homepage":null,"size":4443,"stargazers_count":229,"watchers_count":229,"language":"OCaml","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":57,"mirror_url":null,"open_issues_count":22,"forks":57,"open_issues":22,"watchers":229,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/pulls/468"},"html":{"href":"https://github.com/BinaryAnalysisPlatform/bap/pull/468"},"issue":{"href":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/issues/468"},"comments":{"href":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/issues/468/comments"},"review_comments":{"href":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/pulls/468/comments"},"review_comment":{"href":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/pulls/468/commits"},"statuses":{"href":"https://api.github.com/repos/BinaryAnalysisPlatform/bap/statuses/f75445defccd6f9edbb1a6a069e2ba1bc707b2bd"}}}}
{"actor":{"display_login":"ivg"}}