{"action":"created","comment":{"url":"https://api.github.com/repos/wyeworks/blog/pulls/comments/43333943","id":43333943,"diff_hunk":"@@ -0,0 +1,414 @@\n+---\n+layout: post\n+title: \"Using UNIX tools\"\n+category: \n+date: 2015-10-28 16:15:37 -0300\n+comments: true\n+author:\n+  name: Santiago Ferreira\n+  email: santiago.ferreira@wyeworks.com\n+  twitter_handle: san650\n+  github_handle: san650\n+  image: /images/team/santiago-ferreira.jpg\n+  description: \n+---\n+\n+When I began studying Ruby, one of the things that most caught my attention was\n+the length of time between having an idea and being able to validate the first\n+step; if this were an article about TDD, I would refer to this as the speed\n+with which we receive feedback. The _feedback loop_ is very short.\n+\n+<!--more-->\n+\n+Why? My first years as an IT professional I worked as a programmer using mainly\n+Microsoft Windows and, more specifically, .NET technologies.\n+\n+In that environment, the _distance_ (of time) between an idea and obtaining the\n+first feedback requires many steps. Open Visual Studio, create a console\n+project  (or Windows Forms or web project), then open the file that contains\n+the `main` method declaration (the entry point to all Windows programs) in\n+order to enter the code that I want to test.\n+\n+This is followed by compiling, fixing the errors at compile time, and\n+recompiling until finally seeing a window that opens and closes automatically\n+(in less than one second) in order to go to the console within Visual Studio\n+and finally see the much-awaited feedback.\n+\n+When I began using Ruby, the first thing I did was create a text file, write\n+the first \"Hello World\" and run `ruby hello_world.rb`, and voilà, feedback! In\n+that moment I fell in love with Ruby as a language and a platform.\n+\n+For software developers, it is essential to receive immediate feedback from the\n+tests we are running, which in turn leads us to the solution for a given\n+problem. Ruby is wonderful at this given that the length of time between the\n+idea and the feedback is minimal which creates a great environment for\n+experimentation.\n+\n+## Not everything is that simple...\n+\n+While working on a project, we encountered a problem. In reality, it was not so\n+much a problem as a desire. In the console, we wanted to generate a list of all\n+the defined routes in a specific web application. The project was fairly large\n+and had been active for many years, and therefore the existing solutions didn’t\n+work for us either because the version of the `sinatra` web framework was very\n+old or because the project was not very standardized.\n+\n+One day when I had a bit of free time I thought about testing some solutions in\n+order to generate a list of routes. After giving some thought to the solution,\n+I said to myself...\n+\n+> The only thing I have to do is redefine the methods `get`, `post`, `put` and\n+> `delete`, generate a new proxy class, save the route definition and call the\n+> original implementation, then…\n+\n+There I realized I had again fallen into a trap. The _cognitive distance_\n+between the problem I wanted to solve and the means of reaching a solution via\n+Ruby was quite long, especially as there was no immediate feedback.\n+\n+I took a step back and returned to thinking about the problem.\n+\n+> I have a list of files that can be found in the `app/routes/` folder. From\n+> these files I want all the lines that begin with `get \"…\" do` or `post \"…\"\n+> do`, etc.\n+\n+When I began working with Ruby, I also began working quite a bit with UNIX.\n+Some of the UNIX features I fell in love with include that all the system’s\n+resources are exposed as files; that the commands or utilities perform a task\n+and perform it well; and lastly, that all the utilities can be combined to\n+resolve more complex problems.\n+\n+This permits us to obtain immediate feedback when working with UNIX utilities.\n+\n+## On to UNIX\n+\n+The following is a step-by-step example of how to solve a problem utilizing a\n+few UNIX tools. Additionally, we will see how we can achieve good results while\n+obtaining almost instantaneous feedback by taking small steps and building on\n+previous tests.\n+\n+The problem presented here is as follows: We want to generate a list in the\n+console of all the defined routes in a `sinatra` application. The code for the\n+routes has the following format:\n+\n+```sh\n+$ cat app/routes/schedules.rb\n+\n+get \"/schedules\" do\n+  # … route code …\n+end\n+\n+post \"/schedules/new\" do\n+  # … route code …\n+end\n+\n+put \"/schedules/:id\" do\n+  # … route code …\n+end\n+\n+delete '/schedules/:id' do\n+  # … route code …\n+end\n+```\n+\n+The first thing to know is that for the problem at hand, we’re not interested\n+in 100% effectiveness; we'll settle for a sufficiently well-functioning\n+solution. Hence, we can take some shortcuts while testing the code.\n+\n+The first test is to obtain a list of all the lines that begin with `get`,\n+`post`, `put` or `delete`. For this we can use the `grep` utility.\n+\n+```sh\n+$ grep --line-number --extended-regexp '^\\s*(get|post|put|delete) ' app/routes/*.rb\n+```\n+\n+Note: Moving forward the short versions of the utility options will be used in\n+the examples to make them more concise.\n+\n+The first utility we use is `grep` (*g*lobal *r*egular *e*xpression *p*rint)\n+which looks for patterns within text files and, by default, prints the results.\n+It receives a regular expression as a parameter and a list of files to search.\n+In this case, it searches within all route files for lines that begin with the\n+text `get`, `post`, `put` or `delete` (ignoring the spaces at the beginning of\n+each line).\n+\n+The search result is:\n+\n+```\n+app/routes/schedules.rb:5 get \"/schedules\" do\n+app/routes/schedules.rb:25 post \"/schedules/new\" do\n+app/routes/schedules.rb:55 put \"/schedules/:id\" do\n+app/routes/schedules.rb:60 delete '/schedules/:id' do\n+app/routes/jobs.rb:2    get '/jobs' do\n+app/routes/dummy:25 post %r{/post\\d+} do\n+...\n+```\n+\n+Success! With a simple command we have already come a long way; we have a list\n+of routes and for each one the file and line number where the route is defined.\n+\n+The strategy we will utilize to achieve what we want is very similar to that\n+which Business Intelligence analysts use, in the sense that what we want is to\n+create a three-step process referred to as ETL:\n+\n+1. Extract data\n+2. Transform data\n+3. Load data\n+\n+The first thing we want to do is extract the information (what we just did),\n+then transform this information into a more manageable format and finally load\n+the information somewhere (in our case we simply want to display it on the\n+screen).\n+\n+The second step, then, is to _adjust_ the format of the output to make it\n+uniform. For this we use a command called `sed` (*s*tream *ed*itor). The\n+idea behind this command is to, given a text file, transform one line at a time\n+and return the result of the transformation. It's ideal for \"cleaning\" and\n+filtering the output of other utilities.\n+\n+In our case we would like to:\n+\n+* Standardize the use of quotation marks\n+* Eliminate multiple spaces\n+* Eliminate the text that appears after the route path (the string \"… do\")\n+* Eliminate the use of the character `:` separating the name of the file from\n+  the line number\n+\n+To achieve the first bullet point we simply have to redirect the output of the\n+previous command to `sed` and apply a transformation.\n+\n+```sh\n+$ grep -n -E '^\\s*(get|post|put|delete) ' app/routes/*.rb \\\n+  | sed \"s/'/\\\"/g\"\n+```\n+\n+Two side notes about the command described above: In the first line we use a\n+backslash to indicate that the command continues on the next line, and later,\n+in the second line, we use the \"pipe\" character `|` to indicate that the output\n+of the first command is the input of the second command. This allows us to\n+combine commands in a very simple way.\n+\n+Here we are _telling_ `sed` to replace (command `s/.../.../`) that which is\n+caught by the regular expression `/'/` (single quotation marks), with double\n+quotation marks (`/\"/`). We use the `g` modifier to substitute for all\n+occurrences, not just the first.\n+\n+The output of the combination of these commands is as follows:\n+\n+```\n+app/routes/schedules.rb:5 get \"/schedules\" do\n+app/routes/schedules.rb:25 post \"/schedules/new\" do\n+app/routes/schedules.rb:55 put \"/schedules/:id\" do\n+app/routes/schedules.rb:60 delete \"/schedules/:id\" do\n+app/routes/jobs.rb:2    get \"/jobs\" do\n+app/routes/dummy:25 post %r{/post\\d+} do\n+...\n+```\n+\n+Now there are no single quotation marks! `sed` allows us to specify more than\n+one transformation at a time, separated by semicolons. Continuing with the\n+example, the transformations we want to apply are:\n+\n+* `s/'/\"/g` Standardize the use of quotation marks\n+* `s/  */ /g` Eliminate multiple spaces\n+* `s/ do//` Eliminate the text that appears after the route path (the string\n+  `… do`)\n+* `s/:/ /` Eliminate the use of the character `:` separating the name of the\n+  file from the line number\n+\n+All together it would be:\n+\n+```sh\n+$ grep -n -E '^\\s*(get|post|put|delete) ' app/routes/*.rb \\\n+  | sed \"s/'/\\\"/g; s/  *//g; s/ do//; s/:/ /\"\n+```\n+\n+Executing the command we obtain:\n+\n+```\n+app/routes/schedules.rb 5 get \"/schedules\"\n+app/routes/schedules.rb 25 post \"/schedules/new\"\n+app/routes/schedules.rb 55 put \"/schedules/:id\"\n+app/routes/schedules.rb 60 delete \"/schedules/:id\"\n+app/routes/jobs.rb 2 get \"/jobs\"\n+app/routes/dummy 25 post %r{/post\\d+}\n+```\n+\n+With this we conclude the second stage of our process to standardize the\n+results. Now we start preparing the print format we want. The aim is to achieve\n+a list like the following:\n+\n+```\n+  post %r{/post\\d+}     app/routes/dummy:25\n+   get \"/jobs\"          app/routes/jobs.rb:2\n+   put \"/schedules/:id\" app/routes/schedules.rb:55\n+delete \"/schedules/:id\" app/routes/schedules.rb:60\n+  post \"/schedules/new\" app/routes/schedules.rb:25\n+   get \"/schedules\"     app/routes/schedules.rb:5\n+```\n+\n+That is to say, we want to print the HTTP verb in the first column with\n+right-alignment, followed by the route path and lastly the route file with the\n+line number. We must also note that we want the list ordered by the route path\n+(second column).\n+\n+To achieve this we first rearrange the fields of each line in the desired\n+order. For this we will utilize another UNIX utility called `awk`.\n+\n+`awk` is a scanning and text-processing language. It is extremely useful when\n+we want to treat each line as a sequence of fields separated by a space (or\n+another separator).\n+\n+To reorder the fields in each line we simply have to:\n+\n+```sh\n+$ grep -n -E '^\\s*(get|post|put|delete) ' app/routes/*.rb \\\n+  | sed \"s/'/\\\"/g;  s/  *//g;  s/ do//; s/:/ /\" \\\n+  | awk '{ print $3, $4, $1, $2 }'\n+```\n+\n+Each field is identified by its position starting from 1, hence the sequence we\n+are left with is 3,4,1 and lastly 2. The combination of these commands results\n+in the following:\n+\n+```\n+get \"/schedules\" app/routes/schedules.rb 5\n+post \"/schedules/new\" app/routes/schedules.rb 25\n+put \"/schedules/:id\" app/routes/schedules.rb 55\n+delete \"/schedules/:id\" app/routes/schedules.rb 60\n+get \"/jobs\" app/routes/jobs.rb 2\n+post %r{/post\\d+} app/routes/dummy 25\n+```\n+\n+It’s almost what we want, but first a few touch ups. To begin with, we have to\n+right-align the HTTP verbs. If we take a closer look, the verb with the most\n+characters is `delete` with 6. `awk` has another command similar to `print`\n+called `printf`, which allows for the addition of some formatting information.\n+\n+```sh\n+$ grep -n -E '^\\s*(get|post|put|delete) ' app/routes/*.rb \\\n+  | sed \"s/'/\\\"/g;  s/  *//g;  s/ do//; s/://\" \\\n+  | awk '{ printf(\"%6s %s %s %s\\n\", $3, $4, $1, $2) }'\n+\n+   get \"/schedules\" app/routes/schedules.rb 5\n+  post \"/schedules/new\" app/routes/schedules.rb 25\n+   put \"/schedules/:id\" app/routes/schedules.rb 55\n+delete \"/schedules/:id\" app/routes/schedules.rb 60\n+   get \"/jobs\" app/routes/jobs.rb 2\n+  post %r{/post\\d+} app/routes/dummy 25\n+```\n+\n+Next, we want to sort the list by the route path. To do this we will use\n+another command called `sort`. This utility sorts the lines in alphabetical\n+order by default, but it has a parameter that allows us to indicate which field\n+from each line should be used for the comparison. Thus, indicating that we want\n+to sort by the second field, the command looks like:\n+\n+```sh\n+$ grep -n -E '^\\s*(get|post|put|delete) ' app/routes/*.rb \\\n+  | sed \"s/'/\\\"/g;  s/  *//g;  s/ do//; s/://\" \\\n+  | awk '{ printf(\"%6s %s %s %s\\n\", $3, $4, $1, $2) }' \\\n+  | sort --key=2\n+\n+   get \"/jobs\" app/routes/jobs.rb 2\n+   get \"/schedules\" app/routes/schedules.rb 5\n+   put \"/schedules/:id\" app/routes/schedules.rb 55\n+delete \"/schedules/:id\" app/routes/schedules.rb 60\n+  post \"/schedules/new\" app/routes/schedules.rb 25\n+  post %r{/post\\d+} app/routes/dummy 25\n+```\n+\n+Finally and to conclude, we will use the `column` utility, which allows us to\n+separate another command's output into columns. For example, if we utilize the\n+command with the `-t` option, it prints the following:\n+\n+```sh\n+$ grep -n -E '^\\s*(get|post|put|delete) ' app/routes/*.rb \\\n+  | sed \"s/'/\\\"/g;  s/  *//g;  s/ do//; s/://\" \\\n+  | awk '{ printf(\"%6s %s %s %s\\n\", $3, $4, $1, $2) }' \\","path":"source/_posts/2015-10-28-using-unix-tools.markdown","position":327,"original_position":327,"commit_id":"7c22e3329224810409ca988c12f14e9f48a1c13e","original_commit_id":"7c22e3329224810409ca988c12f14e9f48a1c13e","user":{"login":"san650","id":1234607,"avatar_url":"https://avatars.githubusercontent.com/u/1234607?v=3","gravatar_id":"","url":"https://api.github.com/users/san650","html_url":"https://github.com/san650","followers_url":"https://api.github.com/users/san650/followers","following_url":"https://api.github.com/users/san650/following{/other_user}","gists_url":"https://api.github.com/users/san650/gists{/gist_id}","starred_url":"https://api.github.com/users/san650/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/san650/subscriptions","organizations_url":"https://api.github.com/users/san650/orgs","repos_url":"https://api.github.com/users/san650/repos","events_url":"https://api.github.com/users/san650/events{/privacy}","received_events_url":"https://api.github.com/users/san650/received_events","type":"User","site_admin":false},"body":"True, but in the next step you do. So I tried not to modify the `awk` expression so I don't have to explain that change :smile: \r\n\r\nYou do need it for the last command though, so I leaved it there just for convenience.","created_at":"2015-10-28T23:47:34Z","updated_at":"2015-10-28T23:47:34Z","html_url":"https://github.com/wyeworks/blog/pull/13#discussion_r43333943","pull_request_url":"https://api.github.com/repos/wyeworks/blog/pulls/13","_links":{"self":{"href":"https://api.github.com/repos/wyeworks/blog/pulls/comments/43333943"},"html":{"href":"https://github.com/wyeworks/blog/pull/13#discussion_r43333943"},"pull_request":{"href":"https://api.github.com/repos/wyeworks/blog/pulls/13"}}},"pull_request":{"url":"https://api.github.com/repos/wyeworks/blog/pulls/13","id":49079654,"html_url":"https://github.com/wyeworks/blog/pull/13","diff_url":"https://github.com/wyeworks/blog/pull/13.diff","patch_url":"https://github.com/wyeworks/blog/pull/13.patch","issue_url":"https://api.github.com/repos/wyeworks/blog/issues/13","number":13,"state":"open","locked":false,"title":"Using UNIX tools","user":{"login":"san650","id":1234607,"avatar_url":"https://avatars.githubusercontent.com/u/1234607?v=3","gravatar_id":"","url":"https://api.github.com/users/san650","html_url":"https://github.com/san650","followers_url":"https://api.github.com/users/san650/followers","following_url":"https://api.github.com/users/san650/following{/other_user}","gists_url":"https://api.github.com/users/san650/gists{/gist_id}","starred_url":"https://api.github.com/users/san650/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/san650/subscriptions","organizations_url":"https://api.github.com/users/san650/orgs","repos_url":"https://api.github.com/users/san650/repos","events_url":"https://api.github.com/users/san650/events{/privacy}","received_events_url":"https://api.github.com/users/san650/received_events","type":"User","site_admin":false},"body":"","created_at":"2015-10-28T23:08:11Z","updated_at":"2015-10-28T23:47:34Z","closed_at":null,"merged_at":null,"merge_commit_sha":"04ac3901e8ea24ca8d28ed3eb28ef2b38535d80f","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/wyeworks/blog/pulls/13/commits","review_comments_url":"https://api.github.com/repos/wyeworks/blog/pulls/13/comments","review_comment_url":"https://api.github.com/repos/wyeworks/blog/pulls/comments{/number}","comments_url":"https://api.github.com/repos/wyeworks/blog/issues/13/comments","statuses_url":"https://api.github.com/repos/wyeworks/blog/statuses/7c22e3329224810409ca988c12f14e9f48a1c13e","head":{"label":"san650:using-unix-tools","ref":"using-unix-tools","sha":"7c22e3329224810409ca988c12f14e9f48a1c13e","user":{"login":"san650","id":1234607,"avatar_url":"https://avatars.githubusercontent.com/u/1234607?v=3","gravatar_id":"","url":"https://api.github.com/users/san650","html_url":"https://github.com/san650","followers_url":"https://api.github.com/users/san650/followers","following_url":"https://api.github.com/users/san650/following{/other_user}","gists_url":"https://api.github.com/users/san650/gists{/gist_id}","starred_url":"https://api.github.com/users/san650/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/san650/subscriptions","organizations_url":"https://api.github.com/users/san650/orgs","repos_url":"https://api.github.com/users/san650/repos","events_url":"https://api.github.com/users/san650/events{/privacy}","received_events_url":"https://api.github.com/users/san650/received_events","type":"User","site_admin":false},"repo":{"id":45145533,"name":"wyeworks-blog","full_name":"san650/wyeworks-blog","owner":{"login":"san650","id":1234607,"avatar_url":"https://avatars.githubusercontent.com/u/1234607?v=3","gravatar_id":"","url":"https://api.github.com/users/san650","html_url":"https://github.com/san650","followers_url":"https://api.github.com/users/san650/followers","following_url":"https://api.github.com/users/san650/following{/other_user}","gists_url":"https://api.github.com/users/san650/gists{/gist_id}","starred_url":"https://api.github.com/users/san650/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/san650/subscriptions","organizations_url":"https://api.github.com/users/san650/orgs","repos_url":"https://api.github.com/users/san650/repos","events_url":"https://api.github.com/users/san650/events{/privacy}","received_events_url":"https://api.github.com/users/san650/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/san650/wyeworks-blog","description":"WyeWorks Blog","fork":true,"url":"https://api.github.com/repos/san650/wyeworks-blog","forks_url":"https://api.github.com/repos/san650/wyeworks-blog/forks","keys_url":"https://api.github.com/repos/san650/wyeworks-blog/keys{/key_id}","collaborators_url":"https://api.github.com/repos/san650/wyeworks-blog/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/san650/wyeworks-blog/teams","hooks_url":"https://api.github.com/repos/san650/wyeworks-blog/hooks","issue_events_url":"https://api.github.com/repos/san650/wyeworks-blog/issues/events{/number}","events_url":"https://api.github.com/repos/san650/wyeworks-blog/events","assignees_url":"https://api.github.com/repos/san650/wyeworks-blog/assignees{/user}","branches_url":"https://api.github.com/repos/san650/wyeworks-blog/branches{/branch}","tags_url":"https://api.github.com/repos/san650/wyeworks-blog/tags","blobs_url":"https://api.github.com/repos/san650/wyeworks-blog/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/san650/wyeworks-blog/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/san650/wyeworks-blog/git/refs{/sha}","trees_url":"https://api.github.com/repos/san650/wyeworks-blog/git/trees{/sha}","statuses_url":"https://api.github.com/repos/san650/wyeworks-blog/statuses/{sha}","languages_url":"https://api.github.com/repos/san650/wyeworks-blog/languages","stargazers_url":"https://api.github.com/repos/san650/wyeworks-blog/stargazers","contributors_url":"https://api.github.com/repos/san650/wyeworks-blog/contributors","subscribers_url":"https://api.github.com/repos/san650/wyeworks-blog/subscribers","subscription_url":"https://api.github.com/repos/san650/wyeworks-blog/subscription","commits_url":"https://api.github.com/repos/san650/wyeworks-blog/commits{/sha}","git_commits_url":"https://api.github.com/repos/san650/wyeworks-blog/git/commits{/sha}","comments_url":"https://api.github.com/repos/san650/wyeworks-blog/comments{/number}","issue_comment_url":"https://api.github.com/repos/san650/wyeworks-blog/issues/comments{/number}","contents_url":"https://api.github.com/repos/san650/wyeworks-blog/contents/{+path}","compare_url":"https://api.github.com/repos/san650/wyeworks-blog/compare/{base}...{head}","merges_url":"https://api.github.com/repos/san650/wyeworks-blog/merges","archive_url":"https://api.github.com/repos/san650/wyeworks-blog/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/san650/wyeworks-blog/downloads","issues_url":"https://api.github.com/repos/san650/wyeworks-blog/issues{/number}","pulls_url":"https://api.github.com/repos/san650/wyeworks-blog/pulls{/number}","milestones_url":"https://api.github.com/repos/san650/wyeworks-blog/milestones{/number}","notifications_url":"https://api.github.com/repos/san650/wyeworks-blog/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/san650/wyeworks-blog/labels{/name}","releases_url":"https://api.github.com/repos/san650/wyeworks-blog/releases{/id}","created_at":"2015-10-28T22:26:50Z","updated_at":"2015-10-28T22:27:11Z","pushed_at":"2015-10-28T23:19:07Z","git_url":"git://github.com/san650/wyeworks-blog.git","ssh_url":"git@github.com:san650/wyeworks-blog.git","clone_url":"https://github.com/san650/wyeworks-blog.git","svn_url":"https://github.com/san650/wyeworks-blog","homepage":"http://wyeworks.com/blog/","size":2523,"stargazers_count":0,"watchers_count":0,"language":"CSS","has_issues":false,"has_downloads":true,"has_wiki":false,"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":"wyeworks:master","ref":"master","sha":"41ff40106e0bb65204fb13859f7c89f8792d603e","user":{"login":"wyeworks","id":135745,"avatar_url":"https://avatars.githubusercontent.com/u/135745?v=3","gravatar_id":"","url":"https://api.github.com/users/wyeworks","html_url":"https://github.com/wyeworks","followers_url":"https://api.github.com/users/wyeworks/followers","following_url":"https://api.github.com/users/wyeworks/following{/other_user}","gists_url":"https://api.github.com/users/wyeworks/gists{/gist_id}","starred_url":"https://api.github.com/users/wyeworks/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wyeworks/subscriptions","organizations_url":"https://api.github.com/users/wyeworks/orgs","repos_url":"https://api.github.com/users/wyeworks/repos","events_url":"https://api.github.com/users/wyeworks/events{/privacy}","received_events_url":"https://api.github.com/users/wyeworks/received_events","type":"Organization","site_admin":false},"repo":{"id":5289689,"name":"blog","full_name":"wyeworks/blog","owner":{"login":"wyeworks","id":135745,"avatar_url":"https://avatars.githubusercontent.com/u/135745?v=3","gravatar_id":"","url":"https://api.github.com/users/wyeworks","html_url":"https://github.com/wyeworks","followers_url":"https://api.github.com/users/wyeworks/followers","following_url":"https://api.github.com/users/wyeworks/following{/other_user}","gists_url":"https://api.github.com/users/wyeworks/gists{/gist_id}","starred_url":"https://api.github.com/users/wyeworks/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wyeworks/subscriptions","organizations_url":"https://api.github.com/users/wyeworks/orgs","repos_url":"https://api.github.com/users/wyeworks/repos","events_url":"https://api.github.com/users/wyeworks/events{/privacy}","received_events_url":"https://api.github.com/users/wyeworks/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/wyeworks/blog","description":"WyeWorks Blog","fork":false,"url":"https://api.github.com/repos/wyeworks/blog","forks_url":"https://api.github.com/repos/wyeworks/blog/forks","keys_url":"https://api.github.com/repos/wyeworks/blog/keys{/key_id}","collaborators_url":"https://api.github.com/repos/wyeworks/blog/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/wyeworks/blog/teams","hooks_url":"https://api.github.com/repos/wyeworks/blog/hooks","issue_events_url":"https://api.github.com/repos/wyeworks/blog/issues/events{/number}","events_url":"https://api.github.com/repos/wyeworks/blog/events","assignees_url":"https://api.github.com/repos/wyeworks/blog/assignees{/user}","branches_url":"https://api.github.com/repos/wyeworks/blog/branches{/branch}","tags_url":"https://api.github.com/repos/wyeworks/blog/tags","blobs_url":"https://api.github.com/repos/wyeworks/blog/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/wyeworks/blog/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/wyeworks/blog/git/refs{/sha}","trees_url":"https://api.github.com/repos/wyeworks/blog/git/trees{/sha}","statuses_url":"https://api.github.com/repos/wyeworks/blog/statuses/{sha}","languages_url":"https://api.github.com/repos/wyeworks/blog/languages","stargazers_url":"https://api.github.com/repos/wyeworks/blog/stargazers","contributors_url":"https://api.github.com/repos/wyeworks/blog/contributors","subscribers_url":"https://api.github.com/repos/wyeworks/blog/subscribers","subscription_url":"https://api.github.com/repos/wyeworks/blog/subscription","commits_url":"https://api.github.com/repos/wyeworks/blog/commits{/sha}","git_commits_url":"https://api.github.com/repos/wyeworks/blog/git/commits{/sha}","comments_url":"https://api.github.com/repos/wyeworks/blog/comments{/number}","issue_comment_url":"https://api.github.com/repos/wyeworks/blog/issues/comments{/number}","contents_url":"https://api.github.com/repos/wyeworks/blog/contents/{+path}","compare_url":"https://api.github.com/repos/wyeworks/blog/compare/{base}...{head}","merges_url":"https://api.github.com/repos/wyeworks/blog/merges","archive_url":"https://api.github.com/repos/wyeworks/blog/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/wyeworks/blog/downloads","issues_url":"https://api.github.com/repos/wyeworks/blog/issues{/number}","pulls_url":"https://api.github.com/repos/wyeworks/blog/pulls{/number}","milestones_url":"https://api.github.com/repos/wyeworks/blog/milestones{/number}","notifications_url":"https://api.github.com/repos/wyeworks/blog/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/wyeworks/blog/labels{/name}","releases_url":"https://api.github.com/repos/wyeworks/blog/releases{/id}","created_at":"2012-08-03T19:50:29Z","updated_at":"2015-07-16T19:32:56Z","pushed_at":"2015-10-28T23:19:24Z","git_url":"git://github.com/wyeworks/blog.git","ssh_url":"git@github.com:wyeworks/blog.git","clone_url":"https://github.com/wyeworks/blog.git","svn_url":"https://github.com/wyeworks/blog","homepage":"http://wyeworks.com/blog/","size":5772,"stargazers_count":0,"watchers_count":0,"language":"CSS","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":2,"mirror_url":null,"open_issues_count":2,"forks":2,"open_issues":2,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/wyeworks/blog/pulls/13"},"html":{"href":"https://github.com/wyeworks/blog/pull/13"},"issue":{"href":"https://api.github.com/repos/wyeworks/blog/issues/13"},"comments":{"href":"https://api.github.com/repos/wyeworks/blog/issues/13/comments"},"review_comments":{"href":"https://api.github.com/repos/wyeworks/blog/pulls/13/comments"},"review_comment":{"href":"https://api.github.com/repos/wyeworks/blog/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/wyeworks/blog/pulls/13/commits"},"statuses":{"href":"https://api.github.com/repos/wyeworks/blog/statuses/7c22e3329224810409ca988c12f14e9f48a1c13e"}}}}