forked from nerdishbynature/octokit.swift
-
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.
Merge pull request nerdishbynature#80 from robmathers/label-endpoints
Add methods to get and create labels
- Loading branch information
Showing
6 changed files
with
348 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
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 |
---|---|---|
@@ -1,7 +1,134 @@ | ||
import Foundation | ||
import RequestKit | ||
|
||
open class Label: Codable { | ||
open var url: URL? | ||
open var name: String? | ||
open var color: String? | ||
} | ||
|
||
// MARK: request | ||
|
||
public extension Octokit { | ||
/** | ||
Fetches a single label in a repository | ||
- parameter session: RequestKitURLSession, defaults to URLSession.sharedSession() | ||
- parameter owner: The user or organization that owns the repository. | ||
- parameter repository: The name of the repository. | ||
- parameter name: The name of the label. | ||
- parameter completion: Callback for the outcome of the fetch. | ||
*/ | ||
@discardableResult | ||
func label(_ session: RequestKitURLSession = URLSession.shared, owner: String, repository: String, name: String, completion: @escaping (_ response: Response<Label>) -> Void) -> URLSessionDataTaskProtocol? { | ||
let router = LabelRouter.readLabel(configuration, owner, repository, name) | ||
return router.load(session, dateDecodingStrategy: .formatted(Time.rfc3339DateFormatter), expectedResultType: Label.self) { label, error in | ||
if let error = error { | ||
completion(Response.failure(error)) | ||
} else { | ||
if let label = label { | ||
completion(Response.success(label)) | ||
} | ||
} | ||
} | ||
} | ||
|
||
/** | ||
Fetches all labels in a repository | ||
- parameter session: RequestKitURLSession, defaults to URLSession.sharedSession() | ||
- parameter owner: The user or organization that owns the repository. | ||
- parameter repository: The name of the repository. | ||
- parameter page: Current page for label pagination. `1` by default. | ||
- parameter perPage: Number of labels per page. `100` by default. | ||
- parameter completion: Callback for the outcome of the fetch. | ||
*/ | ||
@discardableResult | ||
func labels(_ session: RequestKitURLSession = URLSession.shared, owner: String, repository: String, page: String = "1", perPage: String = "100", completion: @escaping (_ response: Response<[Label]>) -> Void) -> URLSessionDataTaskProtocol? { | ||
let router = LabelRouter.readLabels(configuration, owner, repository, page, perPage) | ||
return router.load(session, dateDecodingStrategy: .formatted(Time.rfc3339DateFormatter), expectedResultType: [Label].self) { labels, error in | ||
if let error = error { | ||
completion(Response.failure(error)) | ||
} else { | ||
if let labels = labels { | ||
completion(Response.success(labels)) | ||
} | ||
} | ||
} | ||
} | ||
|
||
/** | ||
Create a label in a repository | ||
- parameter session: RequestKitURLSession, defaults to URLSession.sharedSession() | ||
- parameter owner: The user or organization that owns the repository. | ||
- parameter repository: The name of the repository. | ||
- parameter name: The name of the label. | ||
- parameter color: The color of the label, in hexadecimal without the leading `#`. | ||
- parameter completion: Callback for the outcome of the request. | ||
*/ | ||
@discardableResult | ||
func postLabel(_ session: RequestKitURLSession = URLSession.shared, owner: String, repository: String, name: String, color: String, completion: @escaping (_ response: Response<Label>) -> Void) -> URLSessionDataTaskProtocol? { | ||
let router = LabelRouter.createLabel(configuration, owner, repository, name, color) | ||
return router.post(session, expectedResultType: Label.self) { label, error in | ||
if let error = error { | ||
completion(Response.failure(error)) | ||
} else { | ||
if let label = label { | ||
completion(Response.success(label)) | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
enum LabelRouter: JSONPostRouter { | ||
case readLabel(Configuration, String, String, String) | ||
case readLabels(Configuration, String, String, String, String) | ||
case createLabel(Configuration, String, String, String, String) | ||
|
||
var method: HTTPMethod { | ||
switch self { | ||
case .createLabel: | ||
return .POST | ||
default: | ||
return .GET | ||
} | ||
} | ||
|
||
var encoding: HTTPEncoding { | ||
switch self { | ||
case .createLabel: | ||
return .json | ||
default: | ||
return .url | ||
} | ||
} | ||
|
||
var configuration: Configuration { | ||
switch self { | ||
case .readLabel(let config, _, _, _): return config | ||
case .readLabels(let config, _, _, _, _): return config | ||
case .createLabel(let config, _, _, _, _): return config | ||
} | ||
} | ||
|
||
var params: [String : Any] { | ||
switch self { | ||
case .readLabel: return [:] | ||
case .readLabels(_, _, _, let page, let perPage): | ||
return ["per_page": perPage, "page": page] | ||
case .createLabel(_, _, _, let name, let color): | ||
return ["name": name, "color": color] | ||
} | ||
} | ||
|
||
var path: String { | ||
switch self { | ||
case .readLabel(_, let owner, let repository, let name): | ||
let name = name.stringByAddingPercentEncodingForRFC3986() ?? name | ||
return "/repos/\(owner)/\(repository)/labels/\(name)" | ||
case .readLabels(_, let owner, let repository, _, _): | ||
return "/repos/\(owner)/\(repository)/labels" | ||
case .createLabel(_, let owner, let repository, _, _): | ||
return "/repos/\(owner)/\(repository)/labels" | ||
} | ||
} | ||
} |
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,14 @@ | ||
import Foundation | ||
|
||
extension String { | ||
/// Percent-encodes a string to be URL-safe | ||
/// | ||
/// See https://useyourloaf.com/blog/how-to-percent-encode-a-url-string/ for more info | ||
/// - returns: An optional string, with percent encoding to match RFC3986 | ||
func stringByAddingPercentEncodingForRFC3986() -> String? { | ||
let unreserved = "-._~/?" | ||
var allowed = CharacterSet.alphanumerics | ||
allowed.insert(charactersIn: unreserved) | ||
return addingPercentEncoding(withAllowedCharacters: allowed) | ||
} | ||
} |
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,8 @@ | ||
{ | ||
"id": 107942188, | ||
"node_id": "MDU6TGFiZWwxMDc5NDIxODg=", | ||
"url": "https://api.github.com/repos/octocat/hello-worId/labels/bug", | ||
"name": "bug", | ||
"color": "fc2929", | ||
"default": true | ||
} |
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,58 @@ | ||
[ | ||
{ | ||
"id": 107942188, | ||
"node_id": "MDU6TGFiZWwxMDc5NDIxODg=", | ||
"url": "https://api.github.com/repos/octocat/hello-worId/labels/bug", | ||
"name": "bug", | ||
"color": "fc2929", | ||
"default": true | ||
}, | ||
{ | ||
"id": 107942189, | ||
"node_id": "MDU6TGFiZWwxMDc5NDIxODk=", | ||
"url": "https://api.github.com/repos/octocat/hello-worId/labels/duplicate", | ||
"name": "duplicate", | ||
"color": "cccccc", | ||
"default": true | ||
}, | ||
{ | ||
"id": 107942190, | ||
"node_id": "MDU6TGFiZWwxMDc5NDIxOTA=", | ||
"url": "https://api.github.com/repos/octocat/hello-worId/labels/enhancement", | ||
"name": "enhancement", | ||
"color": "84b6eb", | ||
"default": true | ||
}, | ||
{ | ||
"id": 107942191, | ||
"node_id": "MDU6TGFiZWwxMDc5NDIxOTE=", | ||
"url": "https://api.github.com/repos/octocat/hello-worId/labels/help%20wanted", | ||
"name": "help wanted", | ||
"color": "159818", | ||
"default": true | ||
}, | ||
{ | ||
"id": 107942192, | ||
"node_id": "MDU6TGFiZWwxMDc5NDIxOTI=", | ||
"url": "https://api.github.com/repos/octocat/hello-worId/labels/invalid", | ||
"name": "invalid", | ||
"color": "e6e6e6", | ||
"default": true | ||
}, | ||
{ | ||
"id": 107942193, | ||
"node_id": "MDU6TGFiZWwxMDc5NDIxOTM=", | ||
"url": "https://api.github.com/repos/octocat/hello-worId/labels/question", | ||
"name": "question", | ||
"color": "cc317c", | ||
"default": true | ||
}, | ||
{ | ||
"id": 107942194, | ||
"node_id": "MDU6TGFiZWwxMDc5NDIxOTQ=", | ||
"url": "https://api.github.com/repos/octocat/hello-worId/labels/wontfix", | ||
"name": "wontfix", | ||
"color": "ffffff", | ||
"default": true | ||
} | ||
] |
Oops, something went wrong.