Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for editing Gists #484

Merged
merged 9 commits into from
Oct 11, 2019
21 changes: 20 additions & 1 deletion src/main/java/org/kohsuke/github/GHGist.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.kohsuke.github;

import com.fasterxml.jackson.annotation.JsonProperty;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.net.URL;
Expand Down Expand Up @@ -115,8 +116,13 @@ private void wrapUp() {
e.getValue().fileName = e.getKey();
}
}

String getApiTailUrl(String tail) {
return "/gists/" + id + '/' + tail;
String result = "/gists/" + id;
if (!StringUtils.isBlank(tail)) {
result += StringUtils.prependIfMissing(tail, "/");
}
return result;
}

public void star() throws IOException {
Expand Down Expand Up @@ -159,6 +165,13 @@ public void delete() throws IOException {
new Requester(root).method("DELETE").to("/gists/" + id);
}

/**
* Updates this gist via a builder.
*/
public GHGistUpdater update() throws IOException {
return new GHGistUpdater(this);
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
Expand All @@ -172,4 +185,10 @@ public boolean equals(Object o) {
public int hashCode() {
return id.hashCode();
}

GHGist wrap(GHUser owner) {
this.owner = owner;
this.root = owner.root;
return this;
}
}
60 changes: 60 additions & 0 deletions src/main/java/org/kohsuke/github/GHGistUpdater.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package org.kohsuke.github;

import java.io.IOException;
import java.util.Collections;
import java.util.LinkedHashMap;

/**
* Builder pattern for updating a Gist.
*
* @author Martin van Zijl
*/
public class GHGistUpdater {
private final GHGist base;
private final Requester builder;
LinkedHashMap<String,Object> files;

GHGistUpdater(GHGist base) {
this.base = base;
this.builder = new Requester(base.root);

files = new LinkedHashMap<>();
}

public GHGistUpdater addFile(String fileName, String content) throws IOException {
updateFile(fileName, content);
return this;
}

// // This method does not work.
// public GHGistUpdater deleteFile(String fileName) throws IOException {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@martinvanzijl
This probably has to do with the way that values are passed via maps.
I suspect passing null results in the key not being set or at least not set to GitHub.

// files.put(fileName, Collections.singletonMap("filename", null));
// return this;
// }

public GHGistUpdater renameFile(String fileName, String newFileName) throws IOException
{
files.put(fileName, Collections.singletonMap("filename", newFileName));
return this;
}

public GHGistUpdater updateFile(String fileName, String content) throws IOException {
files.put(fileName, Collections.singletonMap("content", content));
return this;
}

public GHGistUpdater description(String desc) {
builder.with("description",desc);
return this;
}

/**
* Updates the Gist based on the parameters specified thus far.
*/
public GHGist update() throws IOException {
builder._with("files", files);
return builder
.method("PATCH")
.to(base.getApiTailUrl(""), GHGist.class).wrap(base.owner);
}
}
73 changes: 73 additions & 0 deletions src/test/java/org/kohsuke/github/GHGistUpdaterTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package org.kohsuke.github;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.util.Map;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

/**
* @author Martin van Zijl
*/
public class GHGistUpdaterTest extends AbstractGitHubWireMockTest {

private GHGist gist;

@Before
public void setUp() throws IOException {
GHGistBuilder builder = new GHGistBuilder(gitHub);
gist = builder.description("Test for the API")
.file("unmodified.txt", "Should be unmodified")
//.file("delete-me.txt", "To be deleted")
.file("rename-me.py", "print 'hello'")
.file("update-me.txt", "To be updated")
.public_(true)
.create();
}

@After
public void cleanUp() throws Exception {
// Cleanup is only needed when proxying
if (!mockGitHub.isUseProxy()) {
return;
}

gist.delete();
}

@Test
public void testGitUpdater() throws Exception {
GHGistUpdater updater = gist.update();
GHGist updatedGist = updater.description("Description updated by API")
.addFile("new-file.txt", "Added by updater")
//.deleteFile("delete-me.txt")
.renameFile("rename-me.py", "renamed.py")
.updateFile("update-me.txt", "Content updated by API")
.update();

assertEquals("Description updated by API", updatedGist.getDescription());

Map<String,GHGistFile> files = updatedGist.getFiles();

// Check that the unmodified file stays intact.
assertTrue(files.containsKey("unmodified.txt"));
assertEquals("Should be unmodified", files.get("unmodified.txt").getContent());

// Check that the files are updated as expected.
//assertFalse("File was not deleted.", files.containsKey("delete-me.txt"));

assertTrue(files.containsKey("new-file.txt"));
assertEquals("Added by updater", files.get("new-file.txt").getContent());

assertFalse(files.containsKey("rename-me.py"));
assertTrue(files.containsKey("renamed.py"));
assertEquals("print 'hello'", files.get("renamed.py").getContent());

assertEquals("Content updated by API", files.get("update-me.txt").getContent());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
{
"url": "https://api.github.com/gists/209fef72c25fe4b3f673437603ab6d5d",
"forks_url": "https://api.github.com/gists/209fef72c25fe4b3f673437603ab6d5d/forks",
"commits_url": "https://api.github.com/gists/209fef72c25fe4b3f673437603ab6d5d/commits",
"id": "209fef72c25fe4b3f673437603ab6d5d",
"node_id": "MDQ6R2lzdDIwOWZlZjcyYzI1ZmU0YjNmNjczNDM3NjAzYWI2ZDVk",
"git_pull_url": "https://gist.github.com/209fef72c25fe4b3f673437603ab6d5d.git",
"git_push_url": "https://gist.github.com/209fef72c25fe4b3f673437603ab6d5d.git",
"html_url": "https://gist.github.com/209fef72c25fe4b3f673437603ab6d5d",
"files": {
"rename-me.py": {
"filename": "rename-me.py",
"type": "application/x-python",
"language": "Python",
"raw_url": "https://gist.githubusercontent.com/martinvanzijl/209fef72c25fe4b3f673437603ab6d5d/raw/b609dee383ab7aee026b182aa99086777a97cb77/rename-me.py",
"size": 13,
"truncated": false,
"content": "print 'hello'"
},
"unmodified.txt": {
"filename": "unmodified.txt",
"type": "text/plain",
"language": "Text",
"raw_url": "https://gist.githubusercontent.com/martinvanzijl/209fef72c25fe4b3f673437603ab6d5d/raw/92aaf920c4873e413416e552aaad16cd79d361b7/unmodified.txt",
"size": 20,
"truncated": false,
"content": "Should be unmodified"
},
"update-me.txt": {
"filename": "update-me.txt",
"type": "text/plain",
"language": "Text",
"raw_url": "https://gist.githubusercontent.com/martinvanzijl/209fef72c25fe4b3f673437603ab6d5d/raw/bd835e30ff8e75fb7f435c1868b747f83c3ba243/update-me.txt",
"size": 13,
"truncated": false,
"content": "To be updated"
}
},
"public": true,
"created_at": "2019-10-09T18:06:38Z",
"updated_at": "2019-10-09T18:06:38Z",
"description": "Test for the API",
"comments": 0,
"user": null,
"comments_url": "https://api.github.com/gists/209fef72c25fe4b3f673437603ab6d5d/comments",
"owner": {
"login": "martinvanzijl",
"id": 24422213,
"node_id": "MDQ6VXNlcjI0NDIyMjEz",
"avatar_url": "https://avatars0.githubusercontent.com/u/24422213?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/martinvanzijl",
"html_url": "https://github.com/martinvanzijl",
"followers_url": "https://api.github.com/users/martinvanzijl/followers",
"following_url": "https://api.github.com/users/martinvanzijl/following{/other_user}",
"gists_url": "https://api.github.com/users/martinvanzijl/gists{/gist_id}",
"starred_url": "https://api.github.com/users/martinvanzijl/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/martinvanzijl/subscriptions",
"organizations_url": "https://api.github.com/users/martinvanzijl/orgs",
"repos_url": "https://api.github.com/users/martinvanzijl/repos",
"events_url": "https://api.github.com/users/martinvanzijl/events{/privacy}",
"received_events_url": "https://api.github.com/users/martinvanzijl/received_events",
"type": "User",
"site_admin": false
},
"forks": [],
"history": [
{
"user": {
"login": "martinvanzijl",
"id": 24422213,
"node_id": "MDQ6VXNlcjI0NDIyMjEz",
"avatar_url": "https://avatars0.githubusercontent.com/u/24422213?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/martinvanzijl",
"html_url": "https://github.com/martinvanzijl",
"followers_url": "https://api.github.com/users/martinvanzijl/followers",
"following_url": "https://api.github.com/users/martinvanzijl/following{/other_user}",
"gists_url": "https://api.github.com/users/martinvanzijl/gists{/gist_id}",
"starred_url": "https://api.github.com/users/martinvanzijl/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/martinvanzijl/subscriptions",
"organizations_url": "https://api.github.com/users/martinvanzijl/orgs",
"repos_url": "https://api.github.com/users/martinvanzijl/repos",
"events_url": "https://api.github.com/users/martinvanzijl/events{/privacy}",
"received_events_url": "https://api.github.com/users/martinvanzijl/received_events",
"type": "User",
"site_admin": false
},
"version": "3ef13d1c0c4fc4deef97527c758d1068d2ca4fe3",
"committed_at": "2019-10-09T18:06:37Z",
"change_status": {
"total": 3,
"additions": 3,
"deletions": 0
},
"url": "https://api.github.com/gists/209fef72c25fe4b3f673437603ab6d5d/3ef13d1c0c4fc4deef97527c758d1068d2ca4fe3"
}
],
"truncated": false
}
Loading