forked from github/platform-samples
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
First version of Scala samples to use GitHub API
- Loading branch information
Philippe Charrière
authored
Nov 11, 2016
1 parent
47154a9
commit 92d34db
Showing
16 changed files
with
683 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
.idea/* | ||
project/* | ||
target/* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
# GitHub API + Scala | ||
|
||
## Setup and Run | ||
|
||
- This is a `sbt` project. See http://www.scala-sbt.org/0.13/docs/Setup.html | ||
- Run `sbt` in a Terminal (at the root of this project: `/platform-samples/API/scala.wit.sbt/octocat-samples`) | ||
- Type `run`, and you'll get this: | ||
```shell | ||
> run | ||
[warn] Multiple main classes detected. Run 'show discoveredMainClasses' to see the list | ||
|
||
Multiple main classes detected, select one to run: | ||
|
||
[1] DemoOrganizations | ||
[2] DemoRepositories | ||
[3] DemoUser | ||
[4] DemoZen | ||
|
||
Enter number: | ||
``` | ||
- Chose the number of the demo to run | ||
eg, if you choose `4` you'll get something like that: | ||
```shell | ||
[info] Running DemoZen | ||
MMM. .MMM | ||
MMMMMMMMMMMMMMMMMMM | ||
MMMMMMMMMMMMMMMMMMM _____________________ | ||
MMMMMMMMMMMMMMMMMMMMM | | | ||
MMMMMMMMMMMMMMMMMMMMMMM | Speak like a human. | | ||
MMMMMMMMMMMMMMMMMMMMMMMM |_ _________________| | ||
MMMM::- -:::::::- -::MMMM |/ | ||
MM~:~ 00~:::::~ 00~:~MM | ||
.. MMMMM::.00:::+:::.00::MMMMM .. | ||
.MM::::: ._. :::::MM. | ||
MMMM;:::::;MMMM | ||
-MM MMMMMMM | ||
^ M+ MMMMMMMMM | ||
MMMMMMM MM MM MM | ||
MM MM MM MM | ||
MM MM MM MM | ||
.~~MM~MM~MM~MM~~. | ||
~~~~MM:~MM~~~MM~:MM~~~~ | ||
~~~~~~==~==~~~==~==~~~~~~ | ||
~~~~~~==~==~==~==~~~~~~ | ||
:~==~==~==~==~~ | ||
[success] Total time: 112 s, completed Nov 1, 2016 11:31:15 AM | ||
``` | ||
## Use `src/main/scala/Client.scala` | ||
This source code can work with :octocat:.com and :octocat: Enterprise | ||
### Create a GitHub client | ||
- First, go to your GitHub profile settings and define a **Personal access token** (https://github.com/settings/tokens) | ||
- Then, add the token to the environment variables (eg: `export TOKEN_GITHUB_DOT_COM=token_string`) | ||
- Now you can get the token like that: `sys.env("TOKEN_GITHUB_DOT_COM")` | ||
```scala | ||
val githubCliEnterprise = new github.Client( | ||
"http://github.at.home/api/v3", | ||
sys.env("TOKEN_GITHUB_ENTERPRISE") | ||
) | ||
val githubCliDotCom = new github.Client( | ||
"https://api.github.com", | ||
sys.env("TOKEN_GITHUB_DOT_COM") | ||
) | ||
``` | ||
- if you use GitHub Enterprise, `baseUri` has to be set with `http(s)://your_domain_name/api/v3` | ||
- if you use GitHub.com, `baseUri` has to be set with `https://api.github.com` | ||
### Use the GitHub client | ||
For example, you want to get the information about a user: | ||
(see https://developer.github.com/v3/users/#get-a-single-user) | ||
#### Adding features | ||
You can add "features" to `GitHubClient` using Scala traits: | ||
```scala | ||
val gitHubCli = new github.Client( | ||
"https://api.github.com", | ||
sys.env("TOKEN_GITHUB_DOT_COM") | ||
) with Users | ||
gitHubCli.fetchUser("k33g").fold( | ||
{errorMessage => println(errorMessage)}, | ||
{userInformation:Option[Any] => | ||
println( | ||
userInformation | ||
.map(user => user.asInstanceOf[Map[String, Any]]) | ||
.getOrElse("Huston? We've got a problem!") | ||
) | ||
} | ||
) | ||
``` | ||
You can add more than one feature: | ||
```scala | ||
val gitHubCli = new github.Client( | ||
"http://github.at.home/api/v3", | ||
sys.env("TOKEN_GITHUB_ENTERPRISE") | ||
) with Organizations | ||
with Repositories | ||
``` | ||
## Add features to the GitHub Client | ||
- It's simple: just add a trait to the `github.features` package. | ||
- The trait must extend `RESTMethods` from `github.features` | ||
```scala | ||
trait KillerFeatures extends RESTMethods { | ||
def feature1():Either[String, String] = { | ||
// foo | ||
} | ||
def feature2():Either[String, String] = { | ||
// foo | ||
} | ||
} | ||
``` | ||
See the `github.features` package for more samples | ||
## About Models | ||
There is no GitHub Model, data are provided inside `Map[String, Any]` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
name := "octocat-samples" | ||
version := "1.0" | ||
scalaVersion := "2.12.0" | ||
libraryDependencies += "org.scala-lang.modules" %% "scala-parser-combinators" % "1.0.4" |
47 changes: 47 additions & 0 deletions
47
api/scala.with.sbt/octocat-samples/src/main/scala/DemoOrganizations.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import github.features.{Organizations, Repositories} | ||
|
||
/** | ||
* Create an organization and then a repository | ||
*/ | ||
object DemoOrganizations extends App { | ||
|
||
val gitHubCli = new github.Client( | ||
"http://github.at.home/api/v3", | ||
sys.env("TOKEN_GITHUB_ENTERPRISE") | ||
) with Organizations | ||
with Repositories | ||
|
||
gitHubCli.createOrganization( | ||
login = "PlanetEarth", | ||
admin = "k33g", | ||
profile_name = "PlanetEarth Organization" | ||
).fold( | ||
{errorMessage => println(s"Organization Error: $errorMessage")}, | ||
{ | ||
case Some(organizationData) => | ||
val organization = organizationData.asInstanceOf[Map[String, Any]] | ||
println(organization) | ||
println(organization.getOrElse("login","???")) | ||
|
||
gitHubCli.createOrganizationRepository( | ||
name = "my-little-tools", | ||
description = "foo...", | ||
organization = organization.getOrElse("login","???").toString, | ||
isPrivate = false, | ||
hasIssues = true | ||
).fold( | ||
{errorMessage => println(s"Repository Error: $errorMessage")}, | ||
{repositoryInformation:Option[Any] => | ||
println( | ||
repositoryInformation | ||
.map(repo => repo.asInstanceOf[Map[String, Any]]) | ||
.getOrElse("Huston? We've got a problem!") | ||
) | ||
} | ||
) | ||
case None => | ||
println("Huston? We've got a problem!") | ||
} | ||
|
||
) | ||
} |
28 changes: 28 additions & 0 deletions
28
api/scala.with.sbt/octocat-samples/src/main/scala/DemoRepositories.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import github.features.Repositories | ||
|
||
/** | ||
* Create a repository | ||
*/ | ||
object DemoRepositories extends App { | ||
|
||
val gitHubCli = new github.Client( | ||
"https://api.github.com", | ||
sys.env("TOKEN_GITHUB_DOT_COM") | ||
) with Repositories | ||
|
||
gitHubCli.createRepository( | ||
name = "hello_earth_africa", | ||
description = "Hello world :heart:", | ||
isPrivate = false, | ||
hasIssues = true | ||
).fold( | ||
{errorMessage => println(s"Error: $errorMessage")}, | ||
{repositoryInformation:Option[Any] => | ||
println( | ||
repositoryInformation | ||
.map(repo => repo.asInstanceOf[Map[String, Any]]) | ||
.getOrElse("ouch!") | ||
) | ||
} | ||
) | ||
} |
25 changes: 25 additions & 0 deletions
25
api/scala.with.sbt/octocat-samples/src/main/scala/DemoUser.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import github.features.Users | ||
|
||
/** | ||
* Display user informations on GitHub | ||
*/ | ||
object DemoUser extends App { | ||
|
||
val gitHubCli = new github.Client( | ||
"https://api.github.com", | ||
sys.env("TOKEN_GITHUB_DOT_COM") | ||
) with Users | ||
|
||
|
||
gitHubCli.fetchUser("k33g").fold( | ||
{errorMessage => println(errorMessage)}, | ||
{userInformation:Option[Any] => | ||
println( | ||
userInformation | ||
.map(user => user.asInstanceOf[Map[String, Any]]) | ||
.getOrElse("Huston? We've got a problem!") | ||
) | ||
} | ||
) | ||
|
||
} |
17 changes: 17 additions & 0 deletions
17
api/scala.with.sbt/octocat-samples/src/main/scala/DemoZen.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import github.features.Zen | ||
|
||
object DemoZen extends App { | ||
/** | ||
* Display Zen of GitHub | ||
*/ | ||
val gitHubCli = new github.Client( | ||
"https://api.github.com" | ||
, sys.env("TOKEN_GITHUB_DOT_COM") | ||
) with Zen | ||
|
||
gitHubCli.octocatMessage().fold( | ||
{errorMessage => println(s"Error: $errorMessage")}, | ||
{data => println(data)} | ||
) | ||
|
||
} |
19 changes: 19 additions & 0 deletions
19
api/scala.with.sbt/octocat-samples/src/main/scala/github/Client.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package github | ||
|
||
import github.features.RESTMethods | ||
|
||
/** =Simple GitHub client= | ||
* | ||
* ==Setup== | ||
* {{{ | ||
* val gitHubCli = new github.Client( | ||
* "https://api.github.com", | ||
* sys.env("TOKEN_GITHUB_DOT_COM") | ||
* ) with trait1 with trait2 | ||
* // trait1, trait2 are features provided in the `features` package | ||
* }}} | ||
*/ | ||
class Client(gitHubUrl:String, gitHubToken:String) extends RESTMethods { | ||
override var baseUri: String = gitHubUrl | ||
override var token: String = gitHubToken | ||
} |
68 changes: 68 additions & 0 deletions
68
api/scala.with.sbt/octocat-samples/src/main/scala/github/features/Organizations.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package github.features | ||
|
||
import http.Response | ||
|
||
import scala.util.{Failure, Success} | ||
import scala.util.parsing.json.JSON | ||
|
||
/** =Organizations features= | ||
* | ||
* ==Setup== | ||
* | ||
* instantiate the `github.Client` with `Organizations` trait: | ||
* | ||
* {{{ | ||
* val gitHubCli = new github.Client( | ||
* "http://github.at.home/api/v3", | ||
* sys.env("TOKEN_GITHUB_ENTERPRISE") | ||
* ) with Organizations | ||
* | ||
* }}} | ||
*/ | ||
trait Organizations extends RESTMethods { | ||
|
||
/** this methods creates an organization (only for GitHub Enterprise) | ||
* see: https://developer.github.com/v3/enterprise/orgs/#create-an-organization | ||
* | ||
* @param login The organization's username. | ||
* @param admin The login of the user who will manage this organization. | ||
* @param profile_name The organization's display name. | ||
* @return a Map with organization details inside an Either | ||
*/ | ||
def createOrganization(login:String, admin:String, profile_name:String):Either[String, Option[Any]] = { | ||
postData( | ||
"/admin/organizations", | ||
generateHeaders.::(new http.Header("Content-Type", "application/json")), | ||
Map( | ||
"login" -> login, | ||
"admin" -> admin, | ||
"profile_name" -> profile_name | ||
) | ||
) match { | ||
case Success(resp:Response) => | ||
if (http.isOk(resp.code)) Right(JSON.parseFull(resp.data)) else Left(resp.message) | ||
case Failure(err) => Left(err.getMessage) | ||
} | ||
} | ||
|
||
/** `addOrganizationMembership` adds a role for a user of an organization | ||
* | ||
* @param org organization name(login) | ||
* @param userName name of the concerned user | ||
* @param role role of membership | ||
* @return membership information | ||
*/ | ||
def addOrganizationMembership(org:String, userName:String, role:String):Either[String, Option[Any]] = { | ||
putData( | ||
s"/orgs/$org/memberships/$userName", | ||
generateHeaders.::(new http.Header("Content-Type", "application/json")), | ||
Map( | ||
"role" -> role // member, maintener | ||
) | ||
) match { | ||
case Success(resp:Response) => | ||
if (http.isOk(resp.code)) Right(JSON.parseFull(resp.data)) else Left(resp.message) | ||
case Failure(err) => Left(err.getMessage) | ||
} | ||
} | ||
} |
Oops, something went wrong.