2012-09-18 17:51:53 +01:00
headline : Tutorial
body :
- text : |
2012-09-19 00:08:02 +01:00
2015-08-11 22:02:53 -07:00
GitHub has a JSON API, so let's play with that. This URL gets us the last
5 commits from the jq repo.
2013-09-04 11:42:40 +02:00
- command : "curl 'https://api.github.com/repos/stedolan/jq/commits?per_page=5'"
2012-09-18 17:51:53 +01:00
result : |
2013-09-04 11:42:40 +02:00
[
{
"sha": "d25341478381063d1c76e81b3a52e0592a7c997f" ,
"commit": {
"author": {
"name": "Stephen Dolan" ,
"email": "mu@netsoc.tcd.ie" ,
"date": "2013-06-22T16:30:59Z"
},
"committer": {
"name": "Stephen Dolan" ,
"email": "mu@netsoc.tcd.ie" ,
"date": "2013-06-22T16:30:59Z"
},
"message": "Merge pull request #162 from stedolan/utf8-fixes\n\nUtf8 fixes. Closes #161" ,
"tree": {
"sha": "6ab697a8dfb5a96e124666bf6d6213822599fb40" ,
"url": "https://api.github.com/repos/stedolan/jq/git/trees/6ab697a8dfb5a96e124666bf6d6213822599fb40"
},
"url": "https://api.github.com/repos/stedolan/jq/git/commits/d25341478381063d1c76e81b3a52e0592a7c997f" ,
"comment_count": 0
},
"url": "https://api.github.com/repos/stedolan/jq/commits/d25341478381063d1c76e81b3a52e0592a7c997f" ,
"html_url": "https://github.com/stedolan/jq/commit/d25341478381063d1c76e81b3a52e0592a7c997f" ,
"comments_url": "https://api.github.com/repos/stedolan/jq/commits/d25341478381063d1c76e81b3a52e0592a7c997f/comments" ,
"author": {
"login": "stedolan" ,
2015-08-11 22:02:53 -07:00
...
2012-09-18 17:51:53 +01:00
- text : |
2015-08-11 22:02:53 -07:00
GitHub returns nicely formatted JSON. For servers that don't, it can be
helpful to pipe the response through jq to pretty-print it. The simplest
jq program is the expression `.`, which takes the input and produces it
unchanged as output.
2012-09-18 17:51:53 +01:00
2013-09-04 11:42:40 +02:00
- command : "curl 'https://api.github.com/repos/stedolan/jq/commits?per_page=5' | jq '.'"
2012-09-18 17:51:53 +01:00
result : |
2013-09-04 11:42:40 +02:00
[
{
2015-08-11 22:02:53 -07:00
"sha": "d25341478381063d1c76e81b3a52e0592a7c997f" ,
"commit": {
"author": {
"name": "Stephen Dolan" ,
"email": "mu@netsoc.tcd.ie" ,
"date": "2013-06-22T16:30:59Z"
2013-09-04 11:42:40 +02:00
},
2015-08-11 22:02:53 -07:00
"committer": {
"name": "Stephen Dolan" ,
"email": "mu@netsoc.tcd.ie" ,
"date": "2013-06-22T16:30:59Z"
},
"message": "Merge pull request #162 from stedolan/utf8-fixes\n\nUtf8 fixes. Closes #161" ,
"tree": {
"sha": "6ab697a8dfb5a96e124666bf6d6213822599fb40" ,
"url": "https://api.github.com/repos/stedolan/jq/git/trees/6ab697a8dfb5a96e124666bf6d6213822599fb40"
},
"url": "https://api.github.com/repos/stedolan/jq/git/commits/d25341478381063d1c76e81b3a52e0592a7c997f" ,
"comment_count": 0
},
"url": "https://api.github.com/repos/stedolan/jq/commits/d25341478381063d1c76e81b3a52e0592a7c997f" ,
"html_url": "https://github.com/stedolan/jq/commit/d25341478381063d1c76e81b3a52e0592a7c997f" ,
"comments_url": "https://api.github.com/repos/stedolan/jq/commits/d25341478381063d1c76e81b3a52e0592a7c997f/comments" ,
"author": {
"login": "stedolan" ,
2013-09-04 11:42:40 +02:00
...
- text : |
2012-09-18 17:51:53 +01:00
2015-08-11 22:02:53 -07:00
We can use jq to extract just the first commit.
2013-09-04 11:42:40 +02:00
- command : "curl 'https://api.github.com/repos/stedolan/jq/commits?per_page=5' | jq '.[0]'"
result : |
2012-09-18 17:51:53 +01:00
{
2015-08-11 22:02:53 -07:00
"sha": "d25341478381063d1c76e81b3a52e0592a7c997f" ,
"commit": {
"author": {
"name": "Stephen Dolan" ,
"email": "mu@netsoc.tcd.ie" ,
"date": "2013-06-22T16:30:59Z"
2012-09-18 17:51:53 +01:00
},
2015-08-11 22:02:53 -07:00
"committer": {
"name": "Stephen Dolan" ,
"email": "mu@netsoc.tcd.ie" ,
"date": "2013-06-22T16:30:59Z"
},
"message": "Merge pull request #162 from stedolan/utf8-fixes\n\nUtf8 fixes. Closes #161" ,
"tree": {
"sha": "6ab697a8dfb5a96e124666bf6d6213822599fb40" ,
"url": "https://api.github.com/repos/stedolan/jq/git/trees/6ab697a8dfb5a96e124666bf6d6213822599fb40"
},
"url": "https://api.github.com/repos/stedolan/jq/git/commits/d25341478381063d1c76e81b3a52e0592a7c997f" ,
"comment_count": 0
},
"url": "https://api.github.com/repos/stedolan/jq/commits/d25341478381063d1c76e81b3a52e0592a7c997f" ,
"html_url": "https://github.com/stedolan/jq/commit/d25341478381063d1c76e81b3a52e0592a7c997f" ,
"comments_url": "https://api.github.com/repos/stedolan/jq/commits/d25341478381063d1c76e81b3a52e0592a7c997f/comments" ,
"author": {
2013-09-04 11:42:40 +02:00
"login": "stedolan" ,
"id": 79765 ,
2015-08-11 22:02:53 -07:00
"avatar_url": "https://avatars.githubusercontent.com/u/79765?v=3" ,
"gravatar_id": "" ,
2013-09-04 11:42:40 +02:00
"url": "https://api.github.com/users/stedolan" ,
"html_url": "https://github.com/stedolan" ,
"followers_url": "https://api.github.com/users/stedolan/followers" ,
2015-08-11 22:02:53 -07:00
"following_url": "https://api.github.com/users/stedolan/following{/other_user}" ,
2013-09-04 11:42:40 +02:00
"gists_url": "https://api.github.com/users/stedolan/gists{/gist_id}" ,
2015-08-11 22:02:53 -07:00
"starred_url": "https://api.github.com/users/stedolan/starred{/owner}{/repo}" ,
"subscriptions_url": "https://api.github.com/users/stedolan/subscriptions" ,
"organizations_url": "https://api.github.com/users/stedolan/orgs" ,
"repos_url": "https://api.github.com/users/stedolan/repos" ,
"events_url": "https://api.github.com/users/stedolan/events{/privacy}" ,
"received_events_url": "https://api.github.com/users/stedolan/received_events" ,
"type": "User" ,
"site_admin": false
},
"committer": {
2013-09-04 11:42:40 +02:00
"login": "stedolan" ,
"id": 79765 ,
2015-08-11 22:02:53 -07:00
"avatar_url": "https://avatars.githubusercontent.com/u/79765?v=3" ,
"gravatar_id": "" ,
2013-09-04 11:42:40 +02:00
"url": "https://api.github.com/users/stedolan" ,
"html_url": "https://github.com/stedolan" ,
"followers_url": "https://api.github.com/users/stedolan/followers" ,
2015-08-11 22:02:53 -07:00
"following_url": "https://api.github.com/users/stedolan/following{/other_user}" ,
"gists_url": "https://api.github.com/users/stedolan/gists{/gist_id}" ,
"starred_url": "https://api.github.com/users/stedolan/starred{/owner}{/repo}" ,
"subscriptions_url": "https://api.github.com/users/stedolan/subscriptions" ,
"organizations_url": "https://api.github.com/users/stedolan/orgs" ,
"repos_url": "https://api.github.com/users/stedolan/repos" ,
"events_url": "https://api.github.com/users/stedolan/events{/privacy}" ,
"received_events_url": "https://api.github.com/users/stedolan/received_events" ,
"type": "User" ,
"site_admin": false
2013-09-04 11:42:40 +02:00
},
2015-08-11 22:02:53 -07:00
"parents": [
{
"sha": "54b9c9bdb225af5d886466d72f47eafc51acb4f7" ,
"url": "https://api.github.com/repos/stedolan/jq/commits/54b9c9bdb225af5d886466d72f47eafc51acb4f7" ,
"html_url": "https://github.com/stedolan/jq/commit/54b9c9bdb225af5d886466d72f47eafc51acb4f7"
2013-09-04 11:42:40 +02:00
},
2015-08-11 22:02:53 -07:00
{
"sha": "8b1b503609c161fea4b003a7179b3fbb2dd4345a" ,
"url": "https://api.github.com/repos/stedolan/jq/commits/8b1b503609c161fea4b003a7179b3fbb2dd4345a" ,
"html_url": "https://github.com/stedolan/jq/commit/8b1b503609c161fea4b003a7179b3fbb2dd4345a"
2013-09-04 11:42:40 +02:00
}
2015-08-11 22:02:53 -07:00
]
2012-09-18 17:51:53 +01:00
}
- text : |
2015-08-11 22:02:53 -07:00
For the rest of the examples, I'll leave out the `curl` command - it's not
going to change.
2012-09-18 17:51:53 +01:00
2015-08-11 22:02:53 -07:00
There's a lot of info we don't care about there, so we'll restrict it down
to the most interesting fields.
2013-09-04 11:42:40 +02:00
- command : "jq '.[0] | {message: .commit.message, name: .commit.committer.name}'"
2012-09-18 17:51:53 +01:00
result : |
{
2015-08-11 22:02:53 -07:00
"message": "Merge pull request #162 from stedolan/utf8-fixes\n\nUtf8 fixes. Closes #161" ,
"name": "Stephen Dolan"
2012-09-18 17:51:53 +01:00
}
2013-09-04 11:42:40 +02:00
2012-09-18 17:51:53 +01:00
- text : |
2013-09-04 11:42:40 +02:00
2015-08-11 22:02:53 -07:00
The `|` operator in jq feeds the output of one filter (`.[0]` which gets
the first element of the array in the response) into the input of another
(`{...}` which builds an object out of those fields). You can access
nested attributes, such as `.commit.message`.
2013-09-04 11:42:40 +02:00
2015-08-11 22:02:53 -07:00
Now let's get the rest of the commits.
2013-09-04 11:42:40 +02:00
- command : "jq '.[] | {message: .commit.message, name: .commit.committer.name}'"
2012-09-18 17:51:53 +01:00
result : |
{
2015-08-11 22:02:53 -07:00
"message": "Merge pull request #162 from stedolan/utf8-fixes\n\nUtf8 fixes. Closes #161" ,
"name": "Stephen Dolan"
2012-09-18 17:51:53 +01:00
}
{
2015-08-11 22:02:53 -07:00
"message": "Reject all overlong UTF8 sequences." ,
"name": "Stephen Dolan"
2012-09-18 17:51:53 +01:00
}
{
2015-08-11 22:02:53 -07:00
"message": "Fix various UTF8 parsing bugs.\n\nIn particular, parse bad UTF8 by replacing the broken bits with U+FFFD\nand resychronise correctly after broken sequences." ,
"name": "Stephen Dolan"
2012-09-18 17:51:53 +01:00
}
{
2015-08-11 22:02:53 -07:00
"message": "Fix example in manual for `floor`. See #155." ,
"name": "Stephen Dolan"
2012-09-18 17:51:53 +01:00
}
{
2015-08-11 22:02:53 -07:00
"message": "Document floor" ,
"name": "Nicolas Williams"
2012-09-18 17:51:53 +01:00
}
2013-09-04 11:42:40 +02:00
2012-09-18 17:51:53 +01:00
- text : |
2013-09-04 11:42:40 +02:00
2015-08-11 22:02:53 -07:00
`.[]` returns each element of the array returned in the response, one at a
time, which are all fed into
`{message: .commit.message, name: .commit.committer.name}`.
2012-09-18 17:51:53 +01:00
2015-07-23 21:26:18 -07:00
Data in jq is represented as streams of JSON values - every jq
2012-09-18 17:51:53 +01:00
expression runs for each value in its input stream, and can
produce any number of values to its output stream.
Streams are serialised by just separating JSON values with
2015-07-23 21:26:18 -07:00
whitespace. This is a `cat`-friendly format - you can just join
2012-09-18 17:51:53 +01:00
two JSON streams together and get a valid JSON stream.
2013-09-04 11:42:40 +02:00
2012-09-18 17:51:53 +01:00
If you want to get the output as a single array, you can tell jq to
"collect" all of the answers by wrapping the filter in square
brackets :
2013-09-04 11:42:40 +02:00
- command : "jq '[.[] | {message: .commit.message, name: .commit.committer.name}]'"
2012-09-18 17:51:53 +01:00
result : |
[
{
2015-08-11 22:02:53 -07:00
"message": "Merge pull request #163 from stedolan/utf8-fixes\n\nUtf8 fixes. Closes #161" ,
"name": "Stephen Dolan"
2012-09-18 17:51:53 +01:00
},
{
2015-08-11 22:02:53 -07:00
"message": "Reject all overlong UTF8 sequences." ,
"name": "Stephen Dolan"
2012-09-18 17:51:53 +01:00
},
{
2015-08-11 22:02:53 -07:00
"message": "Fix various UTF8 parsing bugs.\n\nIn particular, parse bad UTF8 by replacing the broken bits with U+FFFD\nand resychronise correctly after broken sequences." ,
"name": "Stephen Dolan"
2012-09-18 17:51:53 +01:00
},
{
2015-08-11 22:02:53 -07:00
"message": "Fix example in manual for `floor`. See #155." ,
"name": "Stephen Dolan"
2012-09-18 17:51:53 +01:00
},
{
2015-08-11 22:02:53 -07:00
"message": "Document floor" ,
"name": "Nicolas Williams"
2012-09-18 17:51:53 +01:00
}
]
2015-08-11 22:02:53 -07:00
2012-09-18 17:51:53 +01:00
- text : |
- - -
2014-11-05 10:47:37 +00:00
Next, let's try getting the URLs of the parent commits out of the
2013-09-04 11:42:40 +02:00
API results as well. In each commit, the GitHub API includes information
about "parent" commits. There can be one or many.
"parents": [
{
2015-08-11 22:02:53 -07:00
"sha": "54b9c9bdb225af5d886466d72f47eafc51acb4f7" ,
2013-09-04 11:42:40 +02:00
"url": "https://api.github.com/repos/stedolan/jq/commits/54b9c9bdb225af5d886466d72f47eafc51acb4f7" ,
2015-08-11 22:02:53 -07:00
"html_url": "https://github.com/stedolan/jq/commit/54b9c9bdb225af5d886466d72f47eafc51acb4f7"
2013-09-04 11:42:40 +02:00
},
{
2015-08-11 22:02:53 -07:00
"sha": "8b1b503609c161fea4b003a7179b3fbb2dd4345a" ,
2013-09-04 11:42:40 +02:00
"url": "https://api.github.com/repos/stedolan/jq/commits/8b1b503609c161fea4b003a7179b3fbb2dd4345a" ,
2015-08-11 22:02:53 -07:00
"html_url": "https://github.com/stedolan/jq/commit/8b1b503609c161fea4b003a7179b3fbb2dd4345a"
2013-09-04 11:42:40 +02:00
}
]
We want to pull out all of the "html_url" fields inside that array of parent
commits and make a simple list of strings to go along with the
"message" and "author" fields we already have.
- command : "jq '[.[] | {message: .commit.message, name: .commit.committer.name, parents: [.parents[].html_url]}]'"
2012-09-18 17:51:53 +01:00
result : |
2013-09-04 11:42:40 +02:00
[
{
2015-08-11 22:02:53 -07:00
"message": "Merge pull request #162 from stedolan/utf8-fixes\n\nUtf8 fixes. Closes #161" ,
"name": "Stephen Dolan" ,
2013-09-04 11:42:40 +02:00
"parents": [
"https://github.com/stedolan/jq/commit/54b9c9bdb225af5d886466d72f47eafc51acb4f7" ,
"https://github.com/stedolan/jq/commit/8b1b503609c161fea4b003a7179b3fbb2dd4345a"
2015-08-11 22:02:53 -07:00
]
2013-09-04 11:42:40 +02:00
},
{
2015-08-11 22:02:53 -07:00
"message": "Reject all overlong UTF8 sequences." ,
"name": "Stephen Dolan" ,
2013-09-04 11:42:40 +02:00
"parents": [
"https://github.com/stedolan/jq/commit/ff48bd6ec538b01d1057be8e93b94eef6914e9ef"
2015-08-11 22:02:53 -07:00
]
2013-09-04 11:42:40 +02:00
},
{
2015-08-11 22:02:53 -07:00
"message": "Fix various UTF8 parsing bugs.\n\nIn particular, parse bad UTF8 by replacing the broken bits with U+FFFD\nand resychronise correctly after broken sequences." ,
"name": "Stephen Dolan" ,
2013-09-04 11:42:40 +02:00
"parents": [
"https://github.com/stedolan/jq/commit/54b9c9bdb225af5d886466d72f47eafc51acb4f7"
2015-08-11 22:02:53 -07:00
]
2013-09-04 11:42:40 +02:00
},
{
2015-08-11 22:02:53 -07:00
"message": "Fix example in manual for `floor`. See #155." ,
"name": "Stephen Dolan" ,
2013-09-04 11:42:40 +02:00
"parents": [
"https://github.com/stedolan/jq/commit/3dcdc582ea993afea3f5503a78a77675967ecdfa"
2015-08-11 22:02:53 -07:00
]
2013-09-04 11:42:40 +02:00
},
{
2015-08-11 22:02:53 -07:00
"message": "Document floor" ,
"name": "Nicolas Williams" ,
2013-09-04 11:42:40 +02:00
"parents": [
"https://github.com/stedolan/jq/commit/7c4171d414f647ab08bcd20c76a4d8ed68d9c602"
2015-08-11 22:02:53 -07:00
]
2013-09-04 11:42:40 +02:00
}
]
2012-09-18 17:51:53 +01:00
- text : |
2013-09-04 11:42:40 +02:00
Here we're making an object as before, but this time the `parents`
2015-08-11 22:02:53 -07:00
field is being set to `[.parents[].html_url]`, which collects
2014-11-05 10:47:37 +00:00
all of the parent commit URLs defined in the parents object.
2012-09-18 17:51:53 +01:00
- text : |
- - -
2015-08-11 22:02:53 -07:00
Here endeth the tutorial! There's lots more to play with. Go
2013-05-06 15:03:14 +01:00
read [the manual](../manual/) if you're interested, and [download
2013-09-04 11:42:40 +02:00
jq](../download/) if you haven't already.