SlideShare a Scribd company logo
Abusing text/template
Arnaud Porterie - @icecrime - dotGo 2015
How can I get visibility into
my open source projects?
Collect
Store
Draw
Profit?
Filter
Rename
Enrich
Transform
1 {
2 "url": "https://api.github.com/repos/docker/docker/pulls/16603",
3 "id": 46083503,
4 "html_url": "https://github.com/docker/docker/pull/16603",
5 "diff_url": "https://github.com/docker/docker/pull/16603.diff",
6 "patch_url": "https://github.com/docker/docker/pull/16603.patch",
7 "issue_url": "https://api.github.com/repos/docker/docker/issues/16603",
8 "number": 16603,
9 "state": "closed",
10 "locked": false,
11 "title": "Add @vdemeester to MAINTAINERS",
12 "user": {
13 "login": "icecrime",
14 "id": 1564054,
15 "avatar_url": "https://avatars.githubusercontent.com/u/1564054?v=3",
16 "gravatar_id": "",
17 "url": "https://api.github.com/users/icecrime",
18 "html_url": "https://github.com/icecrime",
19 "followers_url": "https://api.github.com/users/icecrime/followers",
20 "following_url": "https://api.github.com/users/icecrime/following{/other_user}",
21 "gists_url": "https://api.github.com/users/icecrime/gists{/gist_id}",
22 "starred_url": "https://api.github.com/users/icecrime/starred{/owner}{/repo}",
23 "subscriptions_url": "https://api.github.com/users/icecrime/subscriptions",
24 "organizations_url": "https://api.github.com/users/icecrime/orgs",
25 "repos_url": "https://api.github.com/users/icecrime/repos",
26 "events_url": "https://api.github.com/users/icecrime/events{/privacy}",
27 "received_events_url": "https://api.github.com/users/icecrime/received_events",
28 "type": "User",
29 "site_admin": false
30 },
31 "body": ":tada:",
32 "created_at": "2015-09-26T15:16:23Z",
33 "updated_at": "2015-09-27T21:02:55Z",
34 "closed_at": "2015-09-27T19:14:39Z",
35 "merged_at": "2015-09-27T19:14:39Z",
36 "merge_commit_sha": "7fae194c5b4c694dc45a385866207df6bea57e61",
~~ ...
320 }
1 {
2 "url": "https://api.github.com/repos/docker/docker/pulls/16603",
3 "id": 46083503,
4 "html_url": "https://github.com/docker/docker/pull/16603",
5 "diff_url": "https://github.com/docker/docker/pull/16603.diff",
6 "patch_url": "https://github.com/docker/docker/pull/16603.patch",
7 "issue_url": "https://api.github.com/repos/docker/docker/issues/16603",
8 "number": 16603,
9 "state": "closed",
10 "locked": false,
11 "title": "Add @vdemeester to MAINTAINERS",
12 "user": {
13 "login": "icecrime",
14 "id": 1564054,
15 "avatar_url": "https://avatars.githubusercontent.com/u/1564054?v=3",
16 "gravatar_id": "",
17 "url": "https://api.github.com/users/icecrime",
18 "html_url": "https://github.com/icecrime",
19 "followers_url": "https://api.github.com/users/icecrime/followers",
20 "following_url": "https://api.github.com/users/icecrime/following{/other_user}",
21 "gists_url": "https://api.github.com/users/icecrime/gists{/gist_id}",
22 "starred_url": "https://api.github.com/users/icecrime/starred{/owner}{/repo}",
23 "subscriptions_url": "https://api.github.com/users/icecrime/subscriptions",
24 "organizations_url": "https://api.github.com/users/icecrime/orgs",
25 "repos_url": "https://api.github.com/users/icecrime/repos",
26 "events_url": "https://api.github.com/users/icecrime/events{/privacy}",
27 "received_events_url": "https://api.github.com/users/icecrime/received_events",
28 "type": "User",
29 "site_admin": false
30 },
31 "body": ":tada:",
32 "created_at": "2015-09-26T15:16:23Z",
33 "updated_at": "2015-09-27T21:02:55Z",
34 "closed_at": "2015-09-27T19:14:39Z",
35 "merged_at": "2015-09-27T19:14:39Z",
36 "merge_commit_sha": "7fae194c5b4c694dc45a385866207df6bea57e61",
~~ ...
320 }
{
"author": {
"login": "icecrime",
"company": "Docker",
"is_maintainer": true
},
"body": ":tada:",
"closed_at": "2015-09-27T19:14:39Z",
"created_at": "2015-09-26T15:16:23Z",
"labels": ["status/4-merge"],
"merged": true,
"ms": "1.9.0",
"number": 16603,
"state": "closed",
"title": "Add @vdemeester...",
}
"Hello dotGo!"
package main
import (
"os"
"text/template"
)
type Foo struct {
Bar string
}
type Something struct {
Foo Foo
}
const text = "Hello {{ .Foo.Bar }}!"
func main() {
obj := Something{
Foo{
Bar: "dotGo",
},
}
t, _ := template.New("").Parse(text)
t.Execute(os.Stdout, obj)
}
What if we...
● Fork text/template
● Substitute fmt.Fprint for a return
● Use the template syntax as a DSL for data transformation
● Describe the model in a TOML configuration file
{
"author": {
"login": "icecrime",
"company": "Docker",
"is_maintainer": true
},
"body": ":tada:",
"closed_at": "2015-09-27T19:14:39Z",
"created_at": "2015-09-26T15:16:23Z",
"labels": ["status/4-merge"],
"merged": true,
"ms": "1.9.0",
"number": 16603,
"state": "closed",
"title": "Add @vdemeester...",
}
[transformations.pull_request]
author = "{{ user_data .user.login }}"
body = "{{ .body }}"
closed_at = "{{ .closed_at }}"
created_at = "{{ .created_at }}"
labels = "{{ range .labels }}{{ .name }}{{ end }}"
merged = "{{ .merged }}"
ms = "{{ if $m := .milestone }}{{ $m.title }}{{ end }}"
number = "{{ .number }}"
state = "{{ .state }}"
title = "{{ .title }}"
[transformations.pull_request]
author = "{{ user_data .user.login }}"
body = "{{ .body }}"
closed_at = "{{ .closed_at }}"
created_at = "{{ .created_at }}"
labels = "{{ range .labels }}{{ .name }}{{ end }}"
merged = "{{ .merged }}"
ms = "{{ if $m := .milestone }}{{ $m.title }}{{ end }}"
number = "{{ .number }}"
state = "{{ .state }}"
title = "{{ .title }}"
{
"author": {
"login": "icecrime",
"company": "Docker",
"is_maintainer": true
},
"body": ":tada:",
"closed_at": "2015-09-27T19:14:39Z",
"created_at": "2015-09-26T15:16:23Z",
"labels": ["status/4-merge"],
"merged": true,
"ms": "1.9.0",
"number": 16603,
"state": "closed",
"title": "Add @vdemeester...",
}
Simple mapping
[transformations.pull_request]
author = "{{ user_data .user.login }}"
body = "{{ .body }}"
closed_at = "{{ .closed_at }}"
created_at = "{{ .created_at }}"
labels = "{{ range .labels }}{{ .name }}{{ end }}"
merged = "{{ .merged }}"
ms = "{{ if $m := .milestone }}{{ $m.title }}{{ end }}"
number = "{{ .number }}"
state = "{{ .state }}"
title = "{{ .title }}"
{
"author": {
"login": "icecrime",
"company": "Docker",
"is_maintainer": true
},
"body": ":tada:",
"closed_at": "2015-09-27T19:14:39Z",
"created_at": "2015-09-26T15:16:23Z",
"labels": ["status/4-merge"],
"merged": true,
"ms": "1.9.0",
"number": 16603,
"state": "closed",
"title": "Add @vdemeester...",
}
Tests
[transformations.pull_request]
author = "{{ user_data .user.login }}"
body = "{{ .body }}"
closed_at = "{{ .closed_at }}"
created_at = "{{ .created_at }}"
labels = "{{ range .labels }}{{ .name }}{{ end }}"
merged = "{{ .merged }}"
ms = "{{ if $m := .milestone }}{{ $m.title }}{{ end }}"
number = "{{ .number }}"
state = "{{ .state }}"
title = "{{ .title }}"
{
"author": {
"login": "icecrime",
"company": "Docker",
"is_maintainer": true
},
"body": ":tada:",
"closed_at": "2015-09-27T19:14:39Z",
"created_at": "2015-09-26T15:16:23Z",
"labels": ["status/4-merge"],
"merged": true,
"ms": "1.9.0",
"number": 16603,
"state": "closed",
"title": "Add @vdemeester...",
}
Loops
[transformations.pull_request]
author = "{{ user_data .user.login }}"
body = "{{ .body }}"
closed_at = "{{ .closed_at }}"
created_at = "{{ .created_at }}"
labels = "{{ range .labels }}{{ .name }}{{ end }}"
merged = "{{ .merged }}"
ms = "{{ if $m := .milestone }}{{ $m.title }}{{ end }}"
number = "{{ .number }}"
state = "{{ .state }}"
title = "{{ .title }}"
{
"author": {
"login": "icecrime",
"company": "Docker",
"is_maintainer": true
},
"body": ":tada:",
"closed_at": "2015-09-27T19:14:39Z",
"created_at": "2015-09-26T15:16:23Z",
"labels": ["status/4-merge"],
"merged": true,
"ms": "1.9.0",
"number": 16603,
"state": "closed",
"title": "Add @vdemeester...",
}
User defined functions
TOML
JSON
Profit!
Thank you
Arnaud Porterie - @icecrime
/icecrime/vossibility-collector

More Related Content

What's hot

Binomial heap
Binomial heapBinomial heap
Binomial heap
Kalpana Vijayaraghavan
 
Go for the would be network programmer
Go for the would be network programmerGo for the would be network programmer
Go for the would be network programmer
Eleanor McHugh
 
How to stand on the shoulders of giants
How to stand on the shoulders of giantsHow to stand on the shoulders of giants
How to stand on the shoulders of giants
Ian Barber
 
The Browser Environment - A Systems Programmer's Perspective
The Browser Environment - A Systems Programmer's PerspectiveThe Browser Environment - A Systems Programmer's Perspective
The Browser Environment - A Systems Programmer's Perspective
Eleanor McHugh
 
Arp
ArpArp
Python postgre sql a wonderful wedding
Python postgre sql   a wonderful weddingPython postgre sql   a wonderful wedding
Python postgre sql a wonderful wedding
Stéphane Wirtel
 
Distributed Data Structures
Distributed Data StructuresDistributed Data Structures
Distributed Data Structures
PDX Web & Design
 
Assignment no39
Assignment no39Assignment no39
Assignment no39
Jay Patel
 
QA Fest 2019. Saar Rachamim. Developing Tools, While Testing
QA Fest 2019. Saar Rachamim. Developing Tools, While TestingQA Fest 2019. Saar Rachamim. Developing Tools, While Testing
QA Fest 2019. Saar Rachamim. Developing Tools, While Testing
QAFest
 
Usp
UspUsp
Playing 44CON CTF for fun and profit
Playing 44CON CTF for fun and profitPlaying 44CON CTF for fun and profit
Playing 44CON CTF for fun and profit
44CON
 
Implementing virtual machines in go & c 2018 redux
Implementing virtual machines in go & c 2018 reduxImplementing virtual machines in go & c 2018 redux
Implementing virtual machines in go & c 2018 redux
Eleanor McHugh
 
Introduzione a C#
Introduzione a C#Introduzione a C#
Introduzione a C#
Lorenz Cuno Klopfenstein
 
C++ Lambda and concurrency
C++ Lambda and concurrencyC++ Lambda and concurrency
C++ Lambda and concurrency
명신 김
 
Mozilla とブラウザゲーム
Mozilla とブラウザゲームMozilla とブラウザゲーム
Mozilla とブラウザゲーム
Noritada Shimizu
 
Introduction to ES6 with Tommy Cresine
Introduction to ES6 with Tommy CresineIntroduction to ES6 with Tommy Cresine
Introduction to ES6 with Tommy Cresine
Movel
 
C++ TUTORIAL 7
C++ TUTORIAL 7C++ TUTORIAL 7
C++ TUTORIAL 7
Farhan Ab Rahman
 
part2
part2part2
Study of aloha protocol using ns2 network java proram
Study of aloha protocol using ns2 network java proramStudy of aloha protocol using ns2 network java proram
Study of aloha protocol using ns2 network java proram
Meenakshi Devi
 
Go vs C++ - CppRussia 2019 Piter BoF
Go vs C++ - CppRussia 2019 Piter BoFGo vs C++ - CppRussia 2019 Piter BoF
Go vs C++ - CppRussia 2019 Piter BoF
Timur Safin
 

What's hot (20)

Binomial heap
Binomial heapBinomial heap
Binomial heap
 
Go for the would be network programmer
Go for the would be network programmerGo for the would be network programmer
Go for the would be network programmer
 
How to stand on the shoulders of giants
How to stand on the shoulders of giantsHow to stand on the shoulders of giants
How to stand on the shoulders of giants
 
The Browser Environment - A Systems Programmer's Perspective
The Browser Environment - A Systems Programmer's PerspectiveThe Browser Environment - A Systems Programmer's Perspective
The Browser Environment - A Systems Programmer's Perspective
 
Arp
ArpArp
Arp
 
Python postgre sql a wonderful wedding
Python postgre sql   a wonderful weddingPython postgre sql   a wonderful wedding
Python postgre sql a wonderful wedding
 
Distributed Data Structures
Distributed Data StructuresDistributed Data Structures
Distributed Data Structures
 
Assignment no39
Assignment no39Assignment no39
Assignment no39
 
QA Fest 2019. Saar Rachamim. Developing Tools, While Testing
QA Fest 2019. Saar Rachamim. Developing Tools, While TestingQA Fest 2019. Saar Rachamim. Developing Tools, While Testing
QA Fest 2019. Saar Rachamim. Developing Tools, While Testing
 
Usp
UspUsp
Usp
 
Playing 44CON CTF for fun and profit
Playing 44CON CTF for fun and profitPlaying 44CON CTF for fun and profit
Playing 44CON CTF for fun and profit
 
Implementing virtual machines in go & c 2018 redux
Implementing virtual machines in go & c 2018 reduxImplementing virtual machines in go & c 2018 redux
Implementing virtual machines in go & c 2018 redux
 
Introduzione a C#
Introduzione a C#Introduzione a C#
Introduzione a C#
 
C++ Lambda and concurrency
C++ Lambda and concurrencyC++ Lambda and concurrency
C++ Lambda and concurrency
 
Mozilla とブラウザゲーム
Mozilla とブラウザゲームMozilla とブラウザゲーム
Mozilla とブラウザゲーム
 
Introduction to ES6 with Tommy Cresine
Introduction to ES6 with Tommy CresineIntroduction to ES6 with Tommy Cresine
Introduction to ES6 with Tommy Cresine
 
C++ TUTORIAL 7
C++ TUTORIAL 7C++ TUTORIAL 7
C++ TUTORIAL 7
 
part2
part2part2
part2
 
Study of aloha protocol using ns2 network java proram
Study of aloha protocol using ns2 network java proramStudy of aloha protocol using ns2 network java proram
Study of aloha protocol using ns2 network java proram
 
Go vs C++ - CppRussia 2019 Piter BoF
Go vs C++ - CppRussia 2019 Piter BoFGo vs C++ - CppRussia 2019 Piter BoF
Go vs C++ - CppRussia 2019 Piter BoF
 

Similar to Abusing text/template for data transformation

Scala & sling
Scala & slingScala & sling
Scala & sling
michid
 
Making your elastic cluster perform - Jettro Coenradie - Codemotion Amsterdam...
Making your elastic cluster perform - Jettro Coenradie - Codemotion Amsterdam...Making your elastic cluster perform - Jettro Coenradie - Codemotion Amsterdam...
Making your elastic cluster perform - Jettro Coenradie - Codemotion Amsterdam...
Codemotion
 
Python Code Camp for Professionals 3/4
Python Code Camp for Professionals 3/4Python Code Camp for Professionals 3/4
Python Code Camp for Professionals 3/4
DEVCON
 
Back to Basics Webinar 2 - Your First MongoDB Application
Back to  Basics Webinar 2 - Your First MongoDB ApplicationBack to  Basics Webinar 2 - Your First MongoDB Application
Back to Basics Webinar 2 - Your First MongoDB Application
Joe Drumgoole
 
Back to Basics Webinar 2: Your First MongoDB Application
Back to Basics Webinar 2: Your First MongoDB ApplicationBack to Basics Webinar 2: Your First MongoDB Application
Back to Basics Webinar 2: Your First MongoDB Application
MongoDB
 
Real-time search in Drupal with Elasticsearch @Moldcamp
Real-time search in Drupal with Elasticsearch @MoldcampReal-time search in Drupal with Elasticsearch @Moldcamp
Real-time search in Drupal with Elasticsearch @Moldcamp
Alexei Gorobets
 
Avro, la puissance du binaire, la souplesse du JSON
Avro, la puissance du binaire, la souplesse du JSONAvro, la puissance du binaire, la souplesse du JSON
Avro, la puissance du binaire, la souplesse du JSON
Alexandre Victoor
 
Conceptos básicos. Seminario web 2: Su primera aplicación MongoDB
 Conceptos básicos. Seminario web 2: Su primera aplicación MongoDB Conceptos básicos. Seminario web 2: Su primera aplicación MongoDB
Conceptos básicos. Seminario web 2: Su primera aplicación MongoDB
MongoDB
 
Webinaire 2 de la série « Retour aux fondamentaux » : Votre première applicat...
Webinaire 2 de la série « Retour aux fondamentaux » : Votre première applicat...Webinaire 2 de la série « Retour aux fondamentaux » : Votre première applicat...
Webinaire 2 de la série « Retour aux fondamentaux » : Votre première applicat...
MongoDB
 
Introduction to Azure DocumentDB
Introduction to Azure DocumentDBIntroduction to Azure DocumentDB
Introduction to Azure DocumentDB
Alex Zyl
 
GraphQL Los Angeles Meetup Slides
GraphQL Los Angeles Meetup SlidesGraphQL Los Angeles Meetup Slides
GraphQL Los Angeles Meetup Slides
Grant Miller
 
Fun Teaching MongoDB New Tricks
Fun Teaching MongoDB New TricksFun Teaching MongoDB New Tricks
Fun Teaching MongoDB New Tricks
MongoDB
 
Scaling Drupal in AWS Using AutoScaling, Cloudformation, RDS and more
Scaling Drupal in AWS Using AutoScaling, Cloudformation, RDS and moreScaling Drupal in AWS Using AutoScaling, Cloudformation, RDS and more
Scaling Drupal in AWS Using AutoScaling, Cloudformation, RDS and more
Dropsolid
 
REST with Eve and Python
REST with Eve and PythonREST with Eve and Python
REST with Eve and Python
PiXeL16
 
Zero to Sixty: AWS CloudFormation (DMG201) | AWS re:Invent 2013
Zero to Sixty: AWS CloudFormation (DMG201) | AWS re:Invent 2013Zero to Sixty: AWS CloudFormation (DMG201) | AWS re:Invent 2013
Zero to Sixty: AWS CloudFormation (DMG201) | AWS re:Invent 2013
Amazon Web Services
 
Cassandra 3.0 - JSON at scale - StampedeCon 2015
Cassandra 3.0 - JSON at scale - StampedeCon 2015Cassandra 3.0 - JSON at scale - StampedeCon 2015
Cassandra 3.0 - JSON at scale - StampedeCon 2015
StampedeCon
 
ELK Stack - Turn boring logfiles into sexy dashboard
ELK Stack - Turn boring logfiles into sexy dashboardELK Stack - Turn boring logfiles into sexy dashboard
ELK Stack - Turn boring logfiles into sexy dashboard
Georg Sorst
 
Elasticsearch in 15 Minutes
Elasticsearch in 15 MinutesElasticsearch in 15 Minutes
Elasticsearch in 15 Minutes
Karel Minarik
 
Introduction to ReasonML
Introduction to ReasonMLIntroduction to ReasonML
Introduction to ReasonML
Riza Fahmi
 
ZH爱丽丝梦游仙境
ZH爱丽丝梦游仙境ZH爱丽丝梦游仙境
ZH爱丽丝梦游仙境
Tatyana Remayeva
 

Similar to Abusing text/template for data transformation (20)

Scala & sling
Scala & slingScala & sling
Scala & sling
 
Making your elastic cluster perform - Jettro Coenradie - Codemotion Amsterdam...
Making your elastic cluster perform - Jettro Coenradie - Codemotion Amsterdam...Making your elastic cluster perform - Jettro Coenradie - Codemotion Amsterdam...
Making your elastic cluster perform - Jettro Coenradie - Codemotion Amsterdam...
 
Python Code Camp for Professionals 3/4
Python Code Camp for Professionals 3/4Python Code Camp for Professionals 3/4
Python Code Camp for Professionals 3/4
 
Back to Basics Webinar 2 - Your First MongoDB Application
Back to  Basics Webinar 2 - Your First MongoDB ApplicationBack to  Basics Webinar 2 - Your First MongoDB Application
Back to Basics Webinar 2 - Your First MongoDB Application
 
Back to Basics Webinar 2: Your First MongoDB Application
Back to Basics Webinar 2: Your First MongoDB ApplicationBack to Basics Webinar 2: Your First MongoDB Application
Back to Basics Webinar 2: Your First MongoDB Application
 
Real-time search in Drupal with Elasticsearch @Moldcamp
Real-time search in Drupal with Elasticsearch @MoldcampReal-time search in Drupal with Elasticsearch @Moldcamp
Real-time search in Drupal with Elasticsearch @Moldcamp
 
Avro, la puissance du binaire, la souplesse du JSON
Avro, la puissance du binaire, la souplesse du JSONAvro, la puissance du binaire, la souplesse du JSON
Avro, la puissance du binaire, la souplesse du JSON
 
Conceptos básicos. Seminario web 2: Su primera aplicación MongoDB
 Conceptos básicos. Seminario web 2: Su primera aplicación MongoDB Conceptos básicos. Seminario web 2: Su primera aplicación MongoDB
Conceptos básicos. Seminario web 2: Su primera aplicación MongoDB
 
Webinaire 2 de la série « Retour aux fondamentaux » : Votre première applicat...
Webinaire 2 de la série « Retour aux fondamentaux » : Votre première applicat...Webinaire 2 de la série « Retour aux fondamentaux » : Votre première applicat...
Webinaire 2 de la série « Retour aux fondamentaux » : Votre première applicat...
 
Introduction to Azure DocumentDB
Introduction to Azure DocumentDBIntroduction to Azure DocumentDB
Introduction to Azure DocumentDB
 
GraphQL Los Angeles Meetup Slides
GraphQL Los Angeles Meetup SlidesGraphQL Los Angeles Meetup Slides
GraphQL Los Angeles Meetup Slides
 
Fun Teaching MongoDB New Tricks
Fun Teaching MongoDB New TricksFun Teaching MongoDB New Tricks
Fun Teaching MongoDB New Tricks
 
Scaling Drupal in AWS Using AutoScaling, Cloudformation, RDS and more
Scaling Drupal in AWS Using AutoScaling, Cloudformation, RDS and moreScaling Drupal in AWS Using AutoScaling, Cloudformation, RDS and more
Scaling Drupal in AWS Using AutoScaling, Cloudformation, RDS and more
 
REST with Eve and Python
REST with Eve and PythonREST with Eve and Python
REST with Eve and Python
 
Zero to Sixty: AWS CloudFormation (DMG201) | AWS re:Invent 2013
Zero to Sixty: AWS CloudFormation (DMG201) | AWS re:Invent 2013Zero to Sixty: AWS CloudFormation (DMG201) | AWS re:Invent 2013
Zero to Sixty: AWS CloudFormation (DMG201) | AWS re:Invent 2013
 
Cassandra 3.0 - JSON at scale - StampedeCon 2015
Cassandra 3.0 - JSON at scale - StampedeCon 2015Cassandra 3.0 - JSON at scale - StampedeCon 2015
Cassandra 3.0 - JSON at scale - StampedeCon 2015
 
ELK Stack - Turn boring logfiles into sexy dashboard
ELK Stack - Turn boring logfiles into sexy dashboardELK Stack - Turn boring logfiles into sexy dashboard
ELK Stack - Turn boring logfiles into sexy dashboard
 
Elasticsearch in 15 Minutes
Elasticsearch in 15 MinutesElasticsearch in 15 Minutes
Elasticsearch in 15 Minutes
 
Introduction to ReasonML
Introduction to ReasonMLIntroduction to ReasonML
Introduction to ReasonML
 
ZH爱丽丝梦游仙境
ZH爱丽丝梦游仙境ZH爱丽丝梦游仙境
ZH爱丽丝梦游仙境
 

More from Arnaud Porterie

Docker Barcelona Meetup - An Introduction to BuildKit
Docker Barcelona Meetup - An Introduction to BuildKitDocker Barcelona Meetup - An Introduction to BuildKit
Docker Barcelona Meetup - An Introduction to BuildKit
Arnaud Porterie
 
Building software: the lessons from open source
Building software: the lessons from open sourceBuilding software: the lessons from open source
Building software: the lessons from open source
Arnaud Porterie
 
DockerCon US 2016 - Extending Docker With APIs, Drivers, and Plugins
DockerCon US 2016 - Extending Docker With APIs, Drivers, and PluginsDockerCon US 2016 - Extending Docker With APIs, Drivers, and Plugins
DockerCon US 2016 - Extending Docker With APIs, Drivers, and Plugins
Arnaud Porterie
 
DockerCon US 2016 - Scaling Open Source operations
DockerCon US 2016 - Scaling Open Source operationsDockerCon US 2016 - Scaling Open Source operations
DockerCon US 2016 - Scaling Open Source operations
Arnaud Porterie
 
The rise of Docker, and the future of computing
The rise of Docker, and the future of computingThe rise of Docker, and the future of computing
The rise of Docker, and the future of computing
Arnaud Porterie
 
DockerCon EU 2015 - Windows Server Containers
DockerCon EU 2015 - Windows Server ContainersDockerCon EU 2015 - Windows Server Containers
DockerCon EU 2015 - Windows Server Containers
Arnaud Porterie
 
DockerCon US 2015 - Engine Breakout Session
DockerCon US 2015 - Engine Breakout SessionDockerCon US 2015 - Engine Breakout Session
DockerCon US 2015 - Engine Breakout Session
Arnaud Porterie
 
DockerCon EU 2015 - The Latest on Docker Engine
DockerCon EU 2015 - The Latest on Docker EngineDockerCon EU 2015 - The Latest on Docker Engine
DockerCon EU 2015 - The Latest on Docker Engine
Arnaud Porterie
 
Arnaud Porterie - Using Machine & Docker to develop & build Docker
Arnaud Porterie - Using Machine & Docker to develop & build DockerArnaud Porterie - Using Machine & Docker to develop & build Docker
Arnaud Porterie - Using Machine & Docker to develop & build Docker
Arnaud Porterie
 
Arnaud Porterie - The Truth About C++
Arnaud Porterie - The Truth About C++Arnaud Porterie - The Truth About C++
Arnaud Porterie - The Truth About C++
Arnaud Porterie
 

More from Arnaud Porterie (10)

Docker Barcelona Meetup - An Introduction to BuildKit
Docker Barcelona Meetup - An Introduction to BuildKitDocker Barcelona Meetup - An Introduction to BuildKit
Docker Barcelona Meetup - An Introduction to BuildKit
 
Building software: the lessons from open source
Building software: the lessons from open sourceBuilding software: the lessons from open source
Building software: the lessons from open source
 
DockerCon US 2016 - Extending Docker With APIs, Drivers, and Plugins
DockerCon US 2016 - Extending Docker With APIs, Drivers, and PluginsDockerCon US 2016 - Extending Docker With APIs, Drivers, and Plugins
DockerCon US 2016 - Extending Docker With APIs, Drivers, and Plugins
 
DockerCon US 2016 - Scaling Open Source operations
DockerCon US 2016 - Scaling Open Source operationsDockerCon US 2016 - Scaling Open Source operations
DockerCon US 2016 - Scaling Open Source operations
 
The rise of Docker, and the future of computing
The rise of Docker, and the future of computingThe rise of Docker, and the future of computing
The rise of Docker, and the future of computing
 
DockerCon EU 2015 - Windows Server Containers
DockerCon EU 2015 - Windows Server ContainersDockerCon EU 2015 - Windows Server Containers
DockerCon EU 2015 - Windows Server Containers
 
DockerCon US 2015 - Engine Breakout Session
DockerCon US 2015 - Engine Breakout SessionDockerCon US 2015 - Engine Breakout Session
DockerCon US 2015 - Engine Breakout Session
 
DockerCon EU 2015 - The Latest on Docker Engine
DockerCon EU 2015 - The Latest on Docker EngineDockerCon EU 2015 - The Latest on Docker Engine
DockerCon EU 2015 - The Latest on Docker Engine
 
Arnaud Porterie - Using Machine & Docker to develop & build Docker
Arnaud Porterie - Using Machine & Docker to develop & build DockerArnaud Porterie - Using Machine & Docker to develop & build Docker
Arnaud Porterie - Using Machine & Docker to develop & build Docker
 
Arnaud Porterie - The Truth About C++
Arnaud Porterie - The Truth About C++Arnaud Porterie - The Truth About C++
Arnaud Porterie - The Truth About C++
 

Recently uploaded

Harnessing the Power of NLP and Knowledge Graphs for Opioid Research
Harnessing the Power of NLP and Knowledge Graphs for Opioid ResearchHarnessing the Power of NLP and Knowledge Graphs for Opioid Research
Harnessing the Power of NLP and Knowledge Graphs for Opioid Research
Neo4j
 
From Natural Language to Structured Solr Queries using LLMs
From Natural Language to Structured Solr Queries using LLMsFrom Natural Language to Structured Solr Queries using LLMs
From Natural Language to Structured Solr Queries using LLMs
Sease
 
Christine's Supplier Sourcing Presentaion.pptx
Christine's Supplier Sourcing Presentaion.pptxChristine's Supplier Sourcing Presentaion.pptx
Christine's Supplier Sourcing Presentaion.pptx
christinelarrosa
 
Leveraging the Graph for Clinical Trials and Standards
Leveraging the Graph for Clinical Trials and StandardsLeveraging the Graph for Clinical Trials and Standards
Leveraging the Graph for Clinical Trials and Standards
Neo4j
 
"NATO Hackathon Winner: AI-Powered Drug Search", Taras Kloba
"NATO Hackathon Winner: AI-Powered Drug Search",  Taras Kloba"NATO Hackathon Winner: AI-Powered Drug Search",  Taras Kloba
"NATO Hackathon Winner: AI-Powered Drug Search", Taras Kloba
Fwdays
 
MySQL InnoDB Storage Engine: Deep Dive - Mydbops
MySQL InnoDB Storage Engine: Deep Dive - MydbopsMySQL InnoDB Storage Engine: Deep Dive - Mydbops
MySQL InnoDB Storage Engine: Deep Dive - Mydbops
Mydbops
 
Containers & AI - Beauty and the Beast!?!
Containers & AI - Beauty and the Beast!?!Containers & AI - Beauty and the Beast!?!
Containers & AI - Beauty and the Beast!?!
Tobias Schneck
 
PRODUCT LISTING OPTIMIZATION PRESENTATION.pptx
PRODUCT LISTING OPTIMIZATION PRESENTATION.pptxPRODUCT LISTING OPTIMIZATION PRESENTATION.pptx
PRODUCT LISTING OPTIMIZATION PRESENTATION.pptx
christinelarrosa
 
"$10 thousand per minute of downtime: architecture, queues, streaming and fin...
"$10 thousand per minute of downtime: architecture, queues, streaming and fin..."$10 thousand per minute of downtime: architecture, queues, streaming and fin...
"$10 thousand per minute of downtime: architecture, queues, streaming and fin...
Fwdays
 
Mutation Testing for Task-Oriented Chatbots
Mutation Testing for Task-Oriented ChatbotsMutation Testing for Task-Oriented Chatbots
Mutation Testing for Task-Oriented Chatbots
Pablo Gómez Abajo
 
inQuba Webinar Mastering Customer Journey Management with Dr Graham Hill
inQuba Webinar Mastering Customer Journey Management with Dr Graham HillinQuba Webinar Mastering Customer Journey Management with Dr Graham Hill
inQuba Webinar Mastering Customer Journey Management with Dr Graham Hill
LizaNolte
 
QR Secure: A Hybrid Approach Using Machine Learning and Security Validation F...
QR Secure: A Hybrid Approach Using Machine Learning and Security Validation F...QR Secure: A Hybrid Approach Using Machine Learning and Security Validation F...
QR Secure: A Hybrid Approach Using Machine Learning and Security Validation F...
AlexanderRichford
 
What is an RPA CoE? Session 2 – CoE Roles
What is an RPA CoE?  Session 2 – CoE RolesWhat is an RPA CoE?  Session 2 – CoE Roles
What is an RPA CoE? Session 2 – CoE Roles
DianaGray10
 
Must Know Postgres Extension for DBA and Developer during Migration
Must Know Postgres Extension for DBA and Developer during MigrationMust Know Postgres Extension for DBA and Developer during Migration
Must Know Postgres Extension for DBA and Developer during Migration
Mydbops
 
Y-Combinator seed pitch deck template PP
Y-Combinator seed pitch deck template PPY-Combinator seed pitch deck template PP
Y-Combinator seed pitch deck template PP
c5vrf27qcz
 
Introducing BoxLang : A new JVM language for productivity and modularity!
Introducing BoxLang : A new JVM language for productivity and modularity!Introducing BoxLang : A new JVM language for productivity and modularity!
Introducing BoxLang : A new JVM language for productivity and modularity!
Ortus Solutions, Corp
 
Session 1 - Intro to Robotic Process Automation.pdf
Session 1 - Intro to Robotic Process Automation.pdfSession 1 - Intro to Robotic Process Automation.pdf
Session 1 - Intro to Robotic Process Automation.pdf
UiPathCommunity
 
Northern Engraving | Modern Metal Trim, Nameplates and Appliance Panels
Northern Engraving | Modern Metal Trim, Nameplates and Appliance PanelsNorthern Engraving | Modern Metal Trim, Nameplates and Appliance Panels
Northern Engraving | Modern Metal Trim, Nameplates and Appliance Panels
Northern Engraving
 
"What does it really mean for your system to be available, or how to define w...
"What does it really mean for your system to be available, or how to define w..."What does it really mean for your system to be available, or how to define w...
"What does it really mean for your system to be available, or how to define w...
Fwdays
 
Getting the Most Out of ScyllaDB Monitoring: ShareChat's Tips
Getting the Most Out of ScyllaDB Monitoring: ShareChat's TipsGetting the Most Out of ScyllaDB Monitoring: ShareChat's Tips
Getting the Most Out of ScyllaDB Monitoring: ShareChat's Tips
ScyllaDB
 

Recently uploaded (20)

Harnessing the Power of NLP and Knowledge Graphs for Opioid Research
Harnessing the Power of NLP and Knowledge Graphs for Opioid ResearchHarnessing the Power of NLP and Knowledge Graphs for Opioid Research
Harnessing the Power of NLP and Knowledge Graphs for Opioid Research
 
From Natural Language to Structured Solr Queries using LLMs
From Natural Language to Structured Solr Queries using LLMsFrom Natural Language to Structured Solr Queries using LLMs
From Natural Language to Structured Solr Queries using LLMs
 
Christine's Supplier Sourcing Presentaion.pptx
Christine's Supplier Sourcing Presentaion.pptxChristine's Supplier Sourcing Presentaion.pptx
Christine's Supplier Sourcing Presentaion.pptx
 
Leveraging the Graph for Clinical Trials and Standards
Leveraging the Graph for Clinical Trials and StandardsLeveraging the Graph for Clinical Trials and Standards
Leveraging the Graph for Clinical Trials and Standards
 
"NATO Hackathon Winner: AI-Powered Drug Search", Taras Kloba
"NATO Hackathon Winner: AI-Powered Drug Search",  Taras Kloba"NATO Hackathon Winner: AI-Powered Drug Search",  Taras Kloba
"NATO Hackathon Winner: AI-Powered Drug Search", Taras Kloba
 
MySQL InnoDB Storage Engine: Deep Dive - Mydbops
MySQL InnoDB Storage Engine: Deep Dive - MydbopsMySQL InnoDB Storage Engine: Deep Dive - Mydbops
MySQL InnoDB Storage Engine: Deep Dive - Mydbops
 
Containers & AI - Beauty and the Beast!?!
Containers & AI - Beauty and the Beast!?!Containers & AI - Beauty and the Beast!?!
Containers & AI - Beauty and the Beast!?!
 
PRODUCT LISTING OPTIMIZATION PRESENTATION.pptx
PRODUCT LISTING OPTIMIZATION PRESENTATION.pptxPRODUCT LISTING OPTIMIZATION PRESENTATION.pptx
PRODUCT LISTING OPTIMIZATION PRESENTATION.pptx
 
"$10 thousand per minute of downtime: architecture, queues, streaming and fin...
"$10 thousand per minute of downtime: architecture, queues, streaming and fin..."$10 thousand per minute of downtime: architecture, queues, streaming and fin...
"$10 thousand per minute of downtime: architecture, queues, streaming and fin...
 
Mutation Testing for Task-Oriented Chatbots
Mutation Testing for Task-Oriented ChatbotsMutation Testing for Task-Oriented Chatbots
Mutation Testing for Task-Oriented Chatbots
 
inQuba Webinar Mastering Customer Journey Management with Dr Graham Hill
inQuba Webinar Mastering Customer Journey Management with Dr Graham HillinQuba Webinar Mastering Customer Journey Management with Dr Graham Hill
inQuba Webinar Mastering Customer Journey Management with Dr Graham Hill
 
QR Secure: A Hybrid Approach Using Machine Learning and Security Validation F...
QR Secure: A Hybrid Approach Using Machine Learning and Security Validation F...QR Secure: A Hybrid Approach Using Machine Learning and Security Validation F...
QR Secure: A Hybrid Approach Using Machine Learning and Security Validation F...
 
What is an RPA CoE? Session 2 – CoE Roles
What is an RPA CoE?  Session 2 – CoE RolesWhat is an RPA CoE?  Session 2 – CoE Roles
What is an RPA CoE? Session 2 – CoE Roles
 
Must Know Postgres Extension for DBA and Developer during Migration
Must Know Postgres Extension for DBA and Developer during MigrationMust Know Postgres Extension for DBA and Developer during Migration
Must Know Postgres Extension for DBA and Developer during Migration
 
Y-Combinator seed pitch deck template PP
Y-Combinator seed pitch deck template PPY-Combinator seed pitch deck template PP
Y-Combinator seed pitch deck template PP
 
Introducing BoxLang : A new JVM language for productivity and modularity!
Introducing BoxLang : A new JVM language for productivity and modularity!Introducing BoxLang : A new JVM language for productivity and modularity!
Introducing BoxLang : A new JVM language for productivity and modularity!
 
Session 1 - Intro to Robotic Process Automation.pdf
Session 1 - Intro to Robotic Process Automation.pdfSession 1 - Intro to Robotic Process Automation.pdf
Session 1 - Intro to Robotic Process Automation.pdf
 
Northern Engraving | Modern Metal Trim, Nameplates and Appliance Panels
Northern Engraving | Modern Metal Trim, Nameplates and Appliance PanelsNorthern Engraving | Modern Metal Trim, Nameplates and Appliance Panels
Northern Engraving | Modern Metal Trim, Nameplates and Appliance Panels
 
"What does it really mean for your system to be available, or how to define w...
"What does it really mean for your system to be available, or how to define w..."What does it really mean for your system to be available, or how to define w...
"What does it really mean for your system to be available, or how to define w...
 
Getting the Most Out of ScyllaDB Monitoring: ShareChat's Tips
Getting the Most Out of ScyllaDB Monitoring: ShareChat's TipsGetting the Most Out of ScyllaDB Monitoring: ShareChat's Tips
Getting the Most Out of ScyllaDB Monitoring: ShareChat's Tips
 

Abusing text/template for data transformation

  • 1. Abusing text/template Arnaud Porterie - @icecrime - dotGo 2015
  • 2. How can I get visibility into my open source projects?
  • 4. Filter Rename Enrich Transform 1 { 2 "url": "https://api.github.com/repos/docker/docker/pulls/16603", 3 "id": 46083503, 4 "html_url": "https://github.com/docker/docker/pull/16603", 5 "diff_url": "https://github.com/docker/docker/pull/16603.diff", 6 "patch_url": "https://github.com/docker/docker/pull/16603.patch", 7 "issue_url": "https://api.github.com/repos/docker/docker/issues/16603", 8 "number": 16603, 9 "state": "closed", 10 "locked": false, 11 "title": "Add @vdemeester to MAINTAINERS", 12 "user": { 13 "login": "icecrime", 14 "id": 1564054, 15 "avatar_url": "https://avatars.githubusercontent.com/u/1564054?v=3", 16 "gravatar_id": "", 17 "url": "https://api.github.com/users/icecrime", 18 "html_url": "https://github.com/icecrime", 19 "followers_url": "https://api.github.com/users/icecrime/followers", 20 "following_url": "https://api.github.com/users/icecrime/following{/other_user}", 21 "gists_url": "https://api.github.com/users/icecrime/gists{/gist_id}", 22 "starred_url": "https://api.github.com/users/icecrime/starred{/owner}{/repo}", 23 "subscriptions_url": "https://api.github.com/users/icecrime/subscriptions", 24 "organizations_url": "https://api.github.com/users/icecrime/orgs", 25 "repos_url": "https://api.github.com/users/icecrime/repos", 26 "events_url": "https://api.github.com/users/icecrime/events{/privacy}", 27 "received_events_url": "https://api.github.com/users/icecrime/received_events", 28 "type": "User", 29 "site_admin": false 30 }, 31 "body": ":tada:", 32 "created_at": "2015-09-26T15:16:23Z", 33 "updated_at": "2015-09-27T21:02:55Z", 34 "closed_at": "2015-09-27T19:14:39Z", 35 "merged_at": "2015-09-27T19:14:39Z", 36 "merge_commit_sha": "7fae194c5b4c694dc45a385866207df6bea57e61", ~~ ... 320 }
  • 5. 1 { 2 "url": "https://api.github.com/repos/docker/docker/pulls/16603", 3 "id": 46083503, 4 "html_url": "https://github.com/docker/docker/pull/16603", 5 "diff_url": "https://github.com/docker/docker/pull/16603.diff", 6 "patch_url": "https://github.com/docker/docker/pull/16603.patch", 7 "issue_url": "https://api.github.com/repos/docker/docker/issues/16603", 8 "number": 16603, 9 "state": "closed", 10 "locked": false, 11 "title": "Add @vdemeester to MAINTAINERS", 12 "user": { 13 "login": "icecrime", 14 "id": 1564054, 15 "avatar_url": "https://avatars.githubusercontent.com/u/1564054?v=3", 16 "gravatar_id": "", 17 "url": "https://api.github.com/users/icecrime", 18 "html_url": "https://github.com/icecrime", 19 "followers_url": "https://api.github.com/users/icecrime/followers", 20 "following_url": "https://api.github.com/users/icecrime/following{/other_user}", 21 "gists_url": "https://api.github.com/users/icecrime/gists{/gist_id}", 22 "starred_url": "https://api.github.com/users/icecrime/starred{/owner}{/repo}", 23 "subscriptions_url": "https://api.github.com/users/icecrime/subscriptions", 24 "organizations_url": "https://api.github.com/users/icecrime/orgs", 25 "repos_url": "https://api.github.com/users/icecrime/repos", 26 "events_url": "https://api.github.com/users/icecrime/events{/privacy}", 27 "received_events_url": "https://api.github.com/users/icecrime/received_events", 28 "type": "User", 29 "site_admin": false 30 }, 31 "body": ":tada:", 32 "created_at": "2015-09-26T15:16:23Z", 33 "updated_at": "2015-09-27T21:02:55Z", 34 "closed_at": "2015-09-27T19:14:39Z", 35 "merged_at": "2015-09-27T19:14:39Z", 36 "merge_commit_sha": "7fae194c5b4c694dc45a385866207df6bea57e61", ~~ ... 320 } { "author": { "login": "icecrime", "company": "Docker", "is_maintainer": true }, "body": ":tada:", "closed_at": "2015-09-27T19:14:39Z", "created_at": "2015-09-26T15:16:23Z", "labels": ["status/4-merge"], "merged": true, "ms": "1.9.0", "number": 16603, "state": "closed", "title": "Add @vdemeester...", }
  • 6. "Hello dotGo!" package main import ( "os" "text/template" ) type Foo struct { Bar string } type Something struct { Foo Foo } const text = "Hello {{ .Foo.Bar }}!" func main() { obj := Something{ Foo{ Bar: "dotGo", }, } t, _ := template.New("").Parse(text) t.Execute(os.Stdout, obj) }
  • 7. What if we... ● Fork text/template ● Substitute fmt.Fprint for a return ● Use the template syntax as a DSL for data transformation ● Describe the model in a TOML configuration file
  • 8. { "author": { "login": "icecrime", "company": "Docker", "is_maintainer": true }, "body": ":tada:", "closed_at": "2015-09-27T19:14:39Z", "created_at": "2015-09-26T15:16:23Z", "labels": ["status/4-merge"], "merged": true, "ms": "1.9.0", "number": 16603, "state": "closed", "title": "Add @vdemeester...", } [transformations.pull_request] author = "{{ user_data .user.login }}" body = "{{ .body }}" closed_at = "{{ .closed_at }}" created_at = "{{ .created_at }}" labels = "{{ range .labels }}{{ .name }}{{ end }}" merged = "{{ .merged }}" ms = "{{ if $m := .milestone }}{{ $m.title }}{{ end }}" number = "{{ .number }}" state = "{{ .state }}" title = "{{ .title }}"
  • 9. [transformations.pull_request] author = "{{ user_data .user.login }}" body = "{{ .body }}" closed_at = "{{ .closed_at }}" created_at = "{{ .created_at }}" labels = "{{ range .labels }}{{ .name }}{{ end }}" merged = "{{ .merged }}" ms = "{{ if $m := .milestone }}{{ $m.title }}{{ end }}" number = "{{ .number }}" state = "{{ .state }}" title = "{{ .title }}" { "author": { "login": "icecrime", "company": "Docker", "is_maintainer": true }, "body": ":tada:", "closed_at": "2015-09-27T19:14:39Z", "created_at": "2015-09-26T15:16:23Z", "labels": ["status/4-merge"], "merged": true, "ms": "1.9.0", "number": 16603, "state": "closed", "title": "Add @vdemeester...", } Simple mapping
  • 10. [transformations.pull_request] author = "{{ user_data .user.login }}" body = "{{ .body }}" closed_at = "{{ .closed_at }}" created_at = "{{ .created_at }}" labels = "{{ range .labels }}{{ .name }}{{ end }}" merged = "{{ .merged }}" ms = "{{ if $m := .milestone }}{{ $m.title }}{{ end }}" number = "{{ .number }}" state = "{{ .state }}" title = "{{ .title }}" { "author": { "login": "icecrime", "company": "Docker", "is_maintainer": true }, "body": ":tada:", "closed_at": "2015-09-27T19:14:39Z", "created_at": "2015-09-26T15:16:23Z", "labels": ["status/4-merge"], "merged": true, "ms": "1.9.0", "number": 16603, "state": "closed", "title": "Add @vdemeester...", } Tests
  • 11. [transformations.pull_request] author = "{{ user_data .user.login }}" body = "{{ .body }}" closed_at = "{{ .closed_at }}" created_at = "{{ .created_at }}" labels = "{{ range .labels }}{{ .name }}{{ end }}" merged = "{{ .merged }}" ms = "{{ if $m := .milestone }}{{ $m.title }}{{ end }}" number = "{{ .number }}" state = "{{ .state }}" title = "{{ .title }}" { "author": { "login": "icecrime", "company": "Docker", "is_maintainer": true }, "body": ":tada:", "closed_at": "2015-09-27T19:14:39Z", "created_at": "2015-09-26T15:16:23Z", "labels": ["status/4-merge"], "merged": true, "ms": "1.9.0", "number": 16603, "state": "closed", "title": "Add @vdemeester...", } Loops
  • 12. [transformations.pull_request] author = "{{ user_data .user.login }}" body = "{{ .body }}" closed_at = "{{ .closed_at }}" created_at = "{{ .created_at }}" labels = "{{ range .labels }}{{ .name }}{{ end }}" merged = "{{ .merged }}" ms = "{{ if $m := .milestone }}{{ $m.title }}{{ end }}" number = "{{ .number }}" state = "{{ .state }}" title = "{{ .title }}" { "author": { "login": "icecrime", "company": "Docker", "is_maintainer": true }, "body": ":tada:", "closed_at": "2015-09-27T19:14:39Z", "created_at": "2015-09-26T15:16:23Z", "labels": ["status/4-merge"], "merged": true, "ms": "1.9.0", "number": 16603, "state": "closed", "title": "Add @vdemeester...", } User defined functions
  • 14.
  • 15. Profit! Thank you Arnaud Porterie - @icecrime /icecrime/vossibility-collector