{"action":"created","comment":{"url":"https://api.github.com/repos/qutheory/vapor/pulls/comments/55844207","id":55844207,"diff_hunk":"@@ -104,6 +108,16 @@ public class Application {\n \t\tself.providers = []\n \n \t\tself.middleware.append(SessionMiddleware)\n+\n+\t\tself.config = Config()\n+\n+\t\tif NSFileManager.defaultManager().fileExistsAtPath(Config.configDir) {","path":"Sources/Vapor/Core/Application.swift","position":27,"original_position":27,"commit_id":"625ed304d557bbab7a2fb5f17b6e6cb1ecb2e867","original_commit_id":"a7a7f75e6038c8e6cf933d8ff9f43e2291fee277","user":{"login":"tannernelson","id":1342803,"avatar_url":"https://avatars.githubusercontent.com/u/1342803?v=3","gravatar_id":"","url":"https://api.github.com/users/tannernelson","html_url":"https://github.com/tannernelson","followers_url":"https://api.github.com/users/tannernelson/followers","following_url":"https://api.github.com/users/tannernelson/following{/other_user}","gists_url":"https://api.github.com/users/tannernelson/gists{/gist_id}","starred_url":"https://api.github.com/users/tannernelson/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tannernelson/subscriptions","organizations_url":"https://api.github.com/users/tannernelson/orgs","repos_url":"https://api.github.com/users/tannernelson/repos","events_url":"https://api.github.com/users/tannernelson/events{/privacy}","received_events_url":"https://api.github.com/users/tannernelson/received_events","type":"User","site_admin":false},"body":"Ah, we don't wanna make Application.init throwable I don't think. \r\n\r\nBut you can at least have Config try to populate itself in the init or as a method. ","created_at":"2016-03-11T15:33:35Z","updated_at":"2016-03-11T15:33:35Z","html_url":"https://github.com/qutheory/vapor/pull/125#discussion_r55844207","pull_request_url":"https://api.github.com/repos/qutheory/vapor/pulls/125","_links":{"self":{"href":"https://api.github.com/repos/qutheory/vapor/pulls/comments/55844207"},"html":{"href":"https://github.com/qutheory/vapor/pull/125#discussion_r55844207"},"pull_request":{"href":"https://api.github.com/repos/qutheory/vapor/pulls/125"}}},"pull_request":{"url":"https://api.github.com/repos/qutheory/vapor/pulls/125","id":62474796,"html_url":"https://github.com/qutheory/vapor/pull/125","diff_url":"https://github.com/qutheory/vapor/pull/125.diff","patch_url":"https://github.com/qutheory/vapor/pull/125.patch","issue_url":"https://api.github.com/repos/qutheory/vapor/issues/125","number":125,"state":"open","locked":false,"title":"Config support","user":{"login":"shnhrrsn","id":42901,"avatar_url":"https://avatars.githubusercontent.com/u/42901?v=3","gravatar_id":"","url":"https://api.github.com/users/shnhrrsn","html_url":"https://github.com/shnhrrsn","followers_url":"https://api.github.com/users/shnhrrsn/followers","following_url":"https://api.github.com/users/shnhrrsn/following{/other_user}","gists_url":"https://api.github.com/users/shnhrrsn/gists{/gist_id}","starred_url":"https://api.github.com/users/shnhrrsn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/shnhrrsn/subscriptions","organizations_url":"https://api.github.com/users/shnhrrsn/orgs","repos_url":"https://api.github.com/users/shnhrrsn/repos","events_url":"https://api.github.com/users/shnhrrsn/events{/privacy}","received_events_url":"https://api.github.com/users/shnhrrsn/received_events","type":"User","site_admin":false},"body":"# Config\r\n\r\nJSON-based config with support for cascading config based on the current environment.\r\n\r\n## Basic Usage\r\n\r\nConfig will look for a `Config` directory at the root level of your project, alongside `App` and `Resources`\r\n\r\nYour directory structure should look like this:\r\n\r\n```\r\nApp\r\nConfig\r\n   app.json\r\n   logs.json\r\nPublic\r\nResources\r\n```\r\n\r\nEach JSON file represents a different group of config.  When querying a value in `app.json` You’ll make a call such as:\r\n\r\n```swift\r\napp.config.get(\"app.port\")?.int\r\n```\r\n\r\nIf you wanted to access a value in `logs.json`:\r\n\r\n```swift\r\napp.config.get(\"logs.level\")?.int\r\n```\r\n\r\nYou can also use typesafe convenience getters with a fallback value if the config setting doesn’t exist:\r\n\r\n```swift\r\napp.config.get(\"app.port\", 8080)\r\n```\r\n\r\n\r\n### Example: Config based server ports\r\n\r\n`app.json`\r\n\r\n```json\r\n{\r\n\t\"port\": 8888\r\n}\r\n```\r\n\r\n`main.swift`\r\n\r\n```swift\r\napp.start(port: app.config.get(\"app.port\", 8080))\r\n```\r\n\r\nWhen running Vapor now, it should start up on port `8888` instead of `8080`.\r\n\r\n## Cascading Environment Config\r\n\r\nConfig uses folders for each environment, cascading downwards.  When loading files from a `production` folder, config will cascade down to the root so you don’t need to redefine every single setting, you can just override the settings you need.\r\n\r\nYour directory structure with an environment folder will look like this:\r\n\r\n```\r\nApp\r\nConfig\r\n   production\r\n      app.json\r\n   app.json\r\n   logs.json\r\nPublic\r\nResources\r\n```\r\n\r\n### Example: Config based server ports, Redux\r\n\r\nWhile port `8888` may be ideal during develoment with Vapor, in production you’re probably going to want to run on port `80`.\r\n\r\nThis is simple enough to do with config:\r\n\r\n`app.json`\r\n\r\n```json\r\n{\r\n\t\"port\": 8888,\r\n\t\"title\": \"My Awesome Vapor App\"\r\n}\r\n```\r\n\r\n`production/app.json`\r\n\r\n```json\r\n{\r\n\t\"port\": 80\r\n}\r\n```\r\n\r\nUsing the same code from the previous example:\r\n\r\n`main.swift`\r\n\r\n```swift\r\napp.start(port: app.config.get(\"app.port\", 8080))\r\n```\r\n\r\nYour app will still run on `8888` locally, but now when you run it in production, it’ll switch to run on `80`.\r\n\r\nSince config cascades, you can still query for the `title` config option without having to redefine it in `production/app.json`:\r\n\r\n```swift\r\nLog.info(\"App title: \\(app.config.get(\"app.title\")?.string)\") // Will output the same both locally and in production.\r\n```\r\n\r\n## Sensitive information & .env.json\r\n\r\nConfig supports a special type of config file, `.env.json`.  This is where sensitive information such as database passwords should go.  The `.env.json` file should never be committed to version control; instead you should have a `.env.json` file locally for your development environment, and then during your deploy process inject a version of `.env.json` with values matching your production environment.\r\n\r\nUnlike other config files `.env.json` is processed differently to allow you to define top level groups within it.  Where other config files have a one to one relationship with their file to a config group, `.env.json` contains multiple groups. If you have `\"app\": { \"key\": \"value\"}` in your `.env.json` file, you’re overriding `key` in the `app.json` file and not creating a new `env` config group.\r\n\r\n### Example: Databases Passwords and Encryption Keys\r\n\r\nAssuming the following directory structure:\r\n\r\n```\r\nConfig\r\n   encryption.json\r\n   database.json\r\n```\r\n\r\nWhile it’s perfectly safe to store non-sensitive config values in `encryption.json` and `database.json`, when it comes to credentials and passwords, you probably don’t want those living in version control.\r\n\r\n`encryption.json`\r\n\r\n```json\r\n{\r\n   \"key\": null,\r\n   \"cipher\": \"AES-256-CBC\"\r\n}\r\n```\r\n\r\n`database.json`\r\n\r\n```json\r\n{\r\n   \"database\": \"my-app\",\r\n   \"driver\": \"mysql\",\r\n   \"username\": null,\r\n   \"password\": null\r\n}\r\n```\r\n\r\nWith a basic schema now defined for these groups, you can create `Config/.env.json` and fill out the sensitive values:\r\n\r\n`.env.json`\r\n\r\n```json\r\n{\r\n   \"encryption\": {\r\n      \"key\": \"my-super-seret-key\"\r\n   },\r\n   \"database\": {\r\n      \"username\": \"my-user\",\r\n      \"password\": \"my-secret-password\"\r\n   }\r\n}\r\n```\r\n\r\nThese values will now override the null values originally defined when being queried in your app.","created_at":"2016-03-10T23:33:37Z","updated_at":"2016-03-11T15:33:35Z","closed_at":null,"merged_at":null,"merge_commit_sha":"3cd7c01e9f7bdb059ced9d1385d8246b25e5c5cf","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/qutheory/vapor/pulls/125/commits","review_comments_url":"https://api.github.com/repos/qutheory/vapor/pulls/125/comments","review_comment_url":"https://api.github.com/repos/qutheory/vapor/pulls/comments{/number}","comments_url":"https://api.github.com/repos/qutheory/vapor/issues/125/comments","statuses_url":"https://api.github.com/repos/qutheory/vapor/statuses/625ed304d557bbab7a2fb5f17b6e6cb1ecb2e867","head":{"label":"qutheory:sh/config","ref":"sh/config","sha":"625ed304d557bbab7a2fb5f17b6e6cb1ecb2e867","user":{"login":"qutheory","id":17364220,"avatar_url":"https://avatars.githubusercontent.com/u/17364220?v=3","gravatar_id":"","url":"https://api.github.com/users/qutheory","html_url":"https://github.com/qutheory","followers_url":"https://api.github.com/users/qutheory/followers","following_url":"https://api.github.com/users/qutheory/following{/other_user}","gists_url":"https://api.github.com/users/qutheory/gists{/gist_id}","starred_url":"https://api.github.com/users/qutheory/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/qutheory/subscriptions","organizations_url":"https://api.github.com/users/qutheory/orgs","repos_url":"https://api.github.com/users/qutheory/repos","events_url":"https://api.github.com/users/qutheory/events{/privacy}","received_events_url":"https://api.github.com/users/qutheory/received_events","type":"Organization","site_admin":false},"repo":{"id":49910095,"name":"vapor","full_name":"qutheory/vapor","owner":{"login":"qutheory","id":17364220,"avatar_url":"https://avatars.githubusercontent.com/u/17364220?v=3","gravatar_id":"","url":"https://api.github.com/users/qutheory","html_url":"https://github.com/qutheory","followers_url":"https://api.github.com/users/qutheory/followers","following_url":"https://api.github.com/users/qutheory/following{/other_user}","gists_url":"https://api.github.com/users/qutheory/gists{/gist_id}","starred_url":"https://api.github.com/users/qutheory/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/qutheory/subscriptions","organizations_url":"https://api.github.com/users/qutheory/orgs","repos_url":"https://api.github.com/users/qutheory/repos","events_url":"https://api.github.com/users/qutheory/events{/privacy}","received_events_url":"https://api.github.com/users/qutheory/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/qutheory/vapor","description":"Elegant web framework for Swift that works on iOS, OS X, and Ubuntu.","fork":false,"url":"https://api.github.com/repos/qutheory/vapor","forks_url":"https://api.github.com/repos/qutheory/vapor/forks","keys_url":"https://api.github.com/repos/qutheory/vapor/keys{/key_id}","collaborators_url":"https://api.github.com/repos/qutheory/vapor/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/qutheory/vapor/teams","hooks_url":"https://api.github.com/repos/qutheory/vapor/hooks","issue_events_url":"https://api.github.com/repos/qutheory/vapor/issues/events{/number}","events_url":"https://api.github.com/repos/qutheory/vapor/events","assignees_url":"https://api.github.com/repos/qutheory/vapor/assignees{/user}","branches_url":"https://api.github.com/repos/qutheory/vapor/branches{/branch}","tags_url":"https://api.github.com/repos/qutheory/vapor/tags","blobs_url":"https://api.github.com/repos/qutheory/vapor/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/qutheory/vapor/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/qutheory/vapor/git/refs{/sha}","trees_url":"https://api.github.com/repos/qutheory/vapor/git/trees{/sha}","statuses_url":"https://api.github.com/repos/qutheory/vapor/statuses/{sha}","languages_url":"https://api.github.com/repos/qutheory/vapor/languages","stargazers_url":"https://api.github.com/repos/qutheory/vapor/stargazers","contributors_url":"https://api.github.com/repos/qutheory/vapor/contributors","subscribers_url":"https://api.github.com/repos/qutheory/vapor/subscribers","subscription_url":"https://api.github.com/repos/qutheory/vapor/subscription","commits_url":"https://api.github.com/repos/qutheory/vapor/commits{/sha}","git_commits_url":"https://api.github.com/repos/qutheory/vapor/git/commits{/sha}","comments_url":"https://api.github.com/repos/qutheory/vapor/comments{/number}","issue_comment_url":"https://api.github.com/repos/qutheory/vapor/issues/comments{/number}","contents_url":"https://api.github.com/repos/qutheory/vapor/contents/{+path}","compare_url":"https://api.github.com/repos/qutheory/vapor/compare/{base}...{head}","merges_url":"https://api.github.com/repos/qutheory/vapor/merges","archive_url":"https://api.github.com/repos/qutheory/vapor/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/qutheory/vapor/downloads","issues_url":"https://api.github.com/repos/qutheory/vapor/issues{/number}","pulls_url":"https://api.github.com/repos/qutheory/vapor/pulls{/number}","milestones_url":"https://api.github.com/repos/qutheory/vapor/milestones{/number}","notifications_url":"https://api.github.com/repos/qutheory/vapor/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/qutheory/vapor/labels{/name}","releases_url":"https://api.github.com/repos/qutheory/vapor/releases{/id}","deployments_url":"https://api.github.com/repos/qutheory/vapor/deployments","created_at":"2016-01-18T22:37:52Z","updated_at":"2016-03-11T13:01:26Z","pushed_at":"2016-03-11T15:14:26Z","git_url":"git://github.com/qutheory/vapor.git","ssh_url":"git@github.com:qutheory/vapor.git","clone_url":"https://github.com/qutheory/vapor.git","svn_url":"https://github.com/qutheory/vapor","homepage":"","size":1075,"stargazers_count":3216,"watchers_count":3216,"language":"Swift","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":136,"mirror_url":null,"open_issues_count":10,"forks":136,"open_issues":10,"watchers":3216,"default_branch":"master"}},"base":{"label":"qutheory:master","ref":"master","sha":"907d12ea2f9252d93dfafc85f416204d1a3dd74f","user":{"login":"qutheory","id":17364220,"avatar_url":"https://avatars.githubusercontent.com/u/17364220?v=3","gravatar_id":"","url":"https://api.github.com/users/qutheory","html_url":"https://github.com/qutheory","followers_url":"https://api.github.com/users/qutheory/followers","following_url":"https://api.github.com/users/qutheory/following{/other_user}","gists_url":"https://api.github.com/users/qutheory/gists{/gist_id}","starred_url":"https://api.github.com/users/qutheory/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/qutheory/subscriptions","organizations_url":"https://api.github.com/users/qutheory/orgs","repos_url":"https://api.github.com/users/qutheory/repos","events_url":"https://api.github.com/users/qutheory/events{/privacy}","received_events_url":"https://api.github.com/users/qutheory/received_events","type":"Organization","site_admin":false},"repo":{"id":49910095,"name":"vapor","full_name":"qutheory/vapor","owner":{"login":"qutheory","id":17364220,"avatar_url":"https://avatars.githubusercontent.com/u/17364220?v=3","gravatar_id":"","url":"https://api.github.com/users/qutheory","html_url":"https://github.com/qutheory","followers_url":"https://api.github.com/users/qutheory/followers","following_url":"https://api.github.com/users/qutheory/following{/other_user}","gists_url":"https://api.github.com/users/qutheory/gists{/gist_id}","starred_url":"https://api.github.com/users/qutheory/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/qutheory/subscriptions","organizations_url":"https://api.github.com/users/qutheory/orgs","repos_url":"https://api.github.com/users/qutheory/repos","events_url":"https://api.github.com/users/qutheory/events{/privacy}","received_events_url":"https://api.github.com/users/qutheory/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/qutheory/vapor","description":"Elegant web framework for Swift that works on iOS, OS X, and Ubuntu.","fork":false,"url":"https://api.github.com/repos/qutheory/vapor","forks_url":"https://api.github.com/repos/qutheory/vapor/forks","keys_url":"https://api.github.com/repos/qutheory/vapor/keys{/key_id}","collaborators_url":"https://api.github.com/repos/qutheory/vapor/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/qutheory/vapor/teams","hooks_url":"https://api.github.com/repos/qutheory/vapor/hooks","issue_events_url":"https://api.github.com/repos/qutheory/vapor/issues/events{/number}","events_url":"https://api.github.com/repos/qutheory/vapor/events","assignees_url":"https://api.github.com/repos/qutheory/vapor/assignees{/user}","branches_url":"https://api.github.com/repos/qutheory/vapor/branches{/branch}","tags_url":"https://api.github.com/repos/qutheory/vapor/tags","blobs_url":"https://api.github.com/repos/qutheory/vapor/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/qutheory/vapor/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/qutheory/vapor/git/refs{/sha}","trees_url":"https://api.github.com/repos/qutheory/vapor/git/trees{/sha}","statuses_url":"https://api.github.com/repos/qutheory/vapor/statuses/{sha}","languages_url":"https://api.github.com/repos/qutheory/vapor/languages","stargazers_url":"https://api.github.com/repos/qutheory/vapor/stargazers","contributors_url":"https://api.github.com/repos/qutheory/vapor/contributors","subscribers_url":"https://api.github.com/repos/qutheory/vapor/subscribers","subscription_url":"https://api.github.com/repos/qutheory/vapor/subscription","commits_url":"https://api.github.com/repos/qutheory/vapor/commits{/sha}","git_commits_url":"https://api.github.com/repos/qutheory/vapor/git/commits{/sha}","comments_url":"https://api.github.com/repos/qutheory/vapor/comments{/number}","issue_comment_url":"https://api.github.com/repos/qutheory/vapor/issues/comments{/number}","contents_url":"https://api.github.com/repos/qutheory/vapor/contents/{+path}","compare_url":"https://api.github.com/repos/qutheory/vapor/compare/{base}...{head}","merges_url":"https://api.github.com/repos/qutheory/vapor/merges","archive_url":"https://api.github.com/repos/qutheory/vapor/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/qutheory/vapor/downloads","issues_url":"https://api.github.com/repos/qutheory/vapor/issues{/number}","pulls_url":"https://api.github.com/repos/qutheory/vapor/pulls{/number}","milestones_url":"https://api.github.com/repos/qutheory/vapor/milestones{/number}","notifications_url":"https://api.github.com/repos/qutheory/vapor/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/qutheory/vapor/labels{/name}","releases_url":"https://api.github.com/repos/qutheory/vapor/releases{/id}","deployments_url":"https://api.github.com/repos/qutheory/vapor/deployments","created_at":"2016-01-18T22:37:52Z","updated_at":"2016-03-11T13:01:26Z","pushed_at":"2016-03-11T15:14:26Z","git_url":"git://github.com/qutheory/vapor.git","ssh_url":"git@github.com:qutheory/vapor.git","clone_url":"https://github.com/qutheory/vapor.git","svn_url":"https://github.com/qutheory/vapor","homepage":"","size":1075,"stargazers_count":3216,"watchers_count":3216,"language":"Swift","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":136,"mirror_url":null,"open_issues_count":10,"forks":136,"open_issues":10,"watchers":3216,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/qutheory/vapor/pulls/125"},"html":{"href":"https://github.com/qutheory/vapor/pull/125"},"issue":{"href":"https://api.github.com/repos/qutheory/vapor/issues/125"},"comments":{"href":"https://api.github.com/repos/qutheory/vapor/issues/125/comments"},"review_comments":{"href":"https://api.github.com/repos/qutheory/vapor/pulls/125/comments"},"review_comment":{"href":"https://api.github.com/repos/qutheory/vapor/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/qutheory/vapor/pulls/125/commits"},"statuses":{"href":"https://api.github.com/repos/qutheory/vapor/statuses/625ed304d557bbab7a2fb5f17b6e6cb1ecb2e867"}}}}