impelement a delete of a repository

This commit is contained in:
Ulrich Schreiner 2015-02-04 14:42:24 +01:00
parent 22fa37c3f1
commit 0ed7ae7e3f
10 changed files with 171 additions and 3 deletions

30
cli/delete.go Normal file
View file

@ -0,0 +1,30 @@
package main
import (
"github.com/codegangsta/cli"
"github.com/drone/drone/client"
)
// NewDeleteCommand returns the CLI command for "delete".
func NewDeleteCommand() cli.Command {
return cli.Command{
Name: "delete",
Usage: "delete a repository",
Flags: []cli.Flag{},
Action: func(c *cli.Context) {
handle(c, deleteCommandFunc)
},
}
}
// deleteCommandFunc executes the "delete" command.
func deleteCommandFunc(c *cli.Context, client *client.Client) error {
var host, owner, name string
var args = c.Args()
if len(args) != 0 {
host, owner, name = parseRepo(args[0])
}
return client.Repos.Delete(host, owner, name)
}

View file

@ -1,8 +1,9 @@
package main package main
import ( import (
"github.com/codegangsta/cli"
"os" "os"
"github.com/codegangsta/cli"
) )
var ( var (
@ -40,6 +41,7 @@ func main() {
NewRestartCommand(), NewRestartCommand(),
NewWhoamiCommand(), NewWhoamiCommand(),
NewSetKeyCommand(), NewSetKeyCommand(),
NewDeleteCommand(),
} }
app.Run(os.Args) app.Run(os.Args)

View file

@ -38,6 +38,12 @@ func (s *RepoService) Disable(host, owner, name string) error {
return s.run("DELETE", path, nil, nil) return s.run("DELETE", path, nil, nil)
} }
// DELETE /api/repos/{host}/{owner}/{name}?remove=true
func (s *RepoService) Delete(host, owner, name string) error {
var path = fmt.Sprintf("/api/repos/%s/%s/%s?remove=true", host, owner, name)
return s.run("DELETE", path, nil, nil)
}
// PUT /api/repos/{host}/{owner}/{name} // PUT /api/repos/{host}/{owner}/{name}
func (s *RepoService) SetKey(host, owner, name, pub, priv string) error { func (s *RepoService) SetKey(host, owner, name, pub, priv string) error {
var path = fmt.Sprintf("/api/repos/%s/%s/%s", host, owner, name) var path = fmt.Sprintf("/api/repos/%s/%s/%s", host, owner, name)

View file

@ -241,6 +241,12 @@ func (r *Bitbucket) Activate(user *model.User, repo *model.Repo, link string) er
return err return err
} }
// Deactivate removes a repository by removing all the post-commit hooks
// which are equal to link and removing the SSH deploy key.
func (r *Bitbucket) Deactivate(user *model.User, repo *model.Repo, link string) error {
return fmt.Errorf("Remove %#v in bitbucket not implemented", *repo)
}
// ParseHook parses the post-commit hook from the Request body // ParseHook parses the post-commit hook from the Request body
// and returns the required data in a standard format. // and returns the required data in a standard format.
func (r *Bitbucket) ParseHook(req *http.Request) (*model.Hook, error) { func (r *Bitbucket) ParseHook(req *http.Request) (*model.Hook, error) {

View file

@ -193,6 +193,23 @@ func (r *GitHub) GetScript(user *model.User, repo *model.Repo, hook *model.Hook)
return GetFile(client, repo.Owner, repo.Name, ".drone.yml", hook.Sha) return GetFile(client, repo.Owner, repo.Name, ".drone.yml", hook.Sha)
} }
// Deactivate removes a repository by removing all the post-commit hooks
// which are equal to link and removing the SSH deploy key.
func (r *GitHub) Deactivate(user *model.User, repo *model.Repo, link string) error {
var client = NewClient(r.API, user.Access, r.SkipVerify)
var title, err = GetKeyTitle(link)
if err != nil {
return err
}
// remove the deploy-key if it is installed remote.
if err := DeleteKey(client, repo.Owner, repo.Name, title, repo.PublicKey); err != nil {
return err
}
return DeleteHook(client, repo.Owner, repo.Name, link)
}
// Activate activates a repository by adding a Post-commit hook and // Activate activates a repository by adding a Post-commit hook and
// a Public Deploy key, if applicable. // a Public Deploy key, if applicable.
func (r *GitHub) Activate(user *model.User, repo *model.Repo, link string) error { func (r *GitHub) Activate(user *model.User, repo *model.Repo, link string) error {

View file

@ -173,6 +173,16 @@ func GetHook(client *github.Client, owner, name, url string) (*github.Hook, erro
return nil, nil return nil, nil
} }
func DeleteHook(client *github.Client, owner, name, url string) error {
hook, err := GetHook(client, owner, name, url)
if err != nil {
return err
}
_, err = client.Repositories.DeleteHook(owner, name, *hook.ID)
return err
}
// CreateHook is a heper function that creates a post-commit hook // CreateHook is a heper function that creates a post-commit hook
// for the specified repository. // for the specified repository.
func CreateHook(client *github.Client, owner, name, url string) (*github.Hook, error) { func CreateHook(client *github.Client, owner, name, url string) (*github.Hook, error) {
@ -230,7 +240,26 @@ func GetKeyTitle(rawurl string) (string, error) {
return fmt.Sprintf("drone@%s", uri.Host), nil return fmt.Sprintf("drone@%s", uri.Host), nil
} }
// CreateKey is a heper function that creates a deploy key // DeleteKey is a helper function that deletes a deploy key
// for the specified repository.
func DeleteKey(client *github.Client, owner, name, title, key string) error {
var k = new(github.Key)
k.Title = github.String(title)
k.Key = github.String(key)
keys, _, err := client.Repositories.ListKeys(owner, name, nil)
if err != nil {
return err
}
for _, rk := range keys {
if rk.Key != nil && rk.Key == k.Key {
_, err = client.Repositories.DeleteKey(owner, name, *rk.ID)
return err
}
}
return fmt.Errorf("%s not found in the list of keys", title)
}
// CreateKey is a helper function that creates a deploy key
// for the specified repository. // for the specified repository.
func CreateKey(client *github.Client, owner, name, title, key string) (*github.Key, error) { func CreateKey(client *github.Client, owner, name, title, key string) (*github.Key, error) {
var k = new(github.Key) var k = new(github.Key)
@ -240,7 +269,7 @@ func CreateKey(client *github.Client, owner, name, title, key string) (*github.K
return created, err return created, err
} }
// CreateUpdateKey is a heper function that creates a deployment key // CreateUpdateKey is a helper function that creates a deployment key
// for the specified repository if it does not already exist, otherwise // for the specified repository if it does not already exist, otherwise
// it updates the existing key // it updates the existing key
func CreateUpdateKey(client *github.Client, owner, name, title, key string) (*github.Key, error) { func CreateUpdateKey(client *github.Client, owner, name, title, key string) (*github.Key, error) {

View file

@ -6,6 +6,7 @@ import (
"net/http" "net/http"
"net/url" "net/url"
"strconv" "strconv"
"strings"
"time" "time"
"code.google.com/p/goauth2/oauth" "code.google.com/p/goauth2/oauth"
@ -179,6 +180,42 @@ func (r *Gitlab) Activate(user *model.User, repo *model.Repo, link string) error
return client.AddProjectHook(path, link, true, false, true) return client.AddProjectHook(path, link, true, false, true)
} }
// Deactivate removes a repository by removing all the post-commit hooks
// which are equal to link and removing the SSH deploy key.
func (r *Gitlab) Deactivate(user *model.User, repo *model.Repo, link string) error {
var client = NewClient(r.url, user.Access, r.SkipVerify)
var path = ns(repo.Owner, repo.Name)
keys, err := client.ProjectDeployKeys(path)
if err != nil {
return err
}
var pubkey = strings.TrimSpace(repo.PublicKey)
for _, k := range keys {
if pubkey == strings.TrimSpace(k.Key) {
fmt.Printf("remove deploy key: %+v\n", k)
if err := client.RemoveProjectDeployKey(path, strconv.Itoa(k.Id)); err != nil {
return err
}
break
}
}
hooks, err := client.ProjectHooks(path)
if err != nil {
return err
}
link += "?owner=" + repo.Owner + "&name=" + repo.Name
for _, h := range hooks {
if link == h.Url {
if err := client.RemoveProjectHook(path, strconv.Itoa(h.Id)); err != nil {
return err
}
break
}
}
return nil
}
// ParseHook parses the post-commit hook from the Request body // ParseHook parses the post-commit hook from the Request body
// and returns the required data in a standard format. // and returns the required data in a standard format.
func (r *Gitlab) ParseHook(req *http.Request) (*model.Hook, error) { func (r *Gitlab) ParseHook(req *http.Request) (*model.Hook, error) {

View file

@ -153,6 +153,12 @@ func (r *Gogs) Activate(user *model.User, repo *model.Repo, link string) error {
return err return err
} }
// Deactivate removes a repository by removing all the post-commit hooks
// which are equal to link and removing the SSH deploy key.
func (r *Gogs) Deactivate(user *model.User, repo *model.Repo, link string) error {
return fmt.Errorf("Remove %#v in gots not implemented", *repo)
}
// ParseHook parses the post-commit hook from the Request body // ParseHook parses the post-commit hook from the Request body
// and returns the required data in a standard format. // and returns the required data in a standard format.
func (r *Gogs) ParseHook(req *http.Request) (*model.Hook, error) { func (r *Gogs) ParseHook(req *http.Request) (*model.Hook, error) {

View file

@ -29,6 +29,10 @@ type Remote interface {
// adding the SSH deploy key, if applicable. // adding the SSH deploy key, if applicable.
Activate(user *model.User, repo *model.Repo, link string) error Activate(user *model.User, repo *model.Repo, link string) error
// Deactivate removes a repository by removing all the post-commit hooks
// which are equal to link and removing the SSH deploy key.
Deactivate(user *model.User, repo *model.Repo, link string) error
// ParseHook parses the post-commit hook from the Request body // ParseHook parses the post-commit hook from the Request body
// and returns the required data in a standard format. // and returns the required data in a standard format.
ParseHook(r *http.Request) (*model.Hook, error) ParseHook(r *http.Request) (*model.Hook, error)

View file

@ -52,6 +52,37 @@ func DelRepo(c web.C, w http.ResponseWriter, r *http.Request) {
var ctx = context.FromC(c) var ctx = context.FromC(c)
var repo = ToRepo(c) var repo = ToRepo(c)
var rm = r.FormValue("remove") // using ?remove=true
// completely remove the repository from the database
if len(rm) != 0 {
var user = ToUser(c)
var remote = remote.Lookup(repo.Host)
if remote == nil {
w.WriteHeader(http.StatusNotFound)
return
}
// Request a new token and update
user_token, err := remote.GetToken(user)
if user_token != nil {
user.Access = user_token.AccessToken
user.Secret = user_token.RefreshToken
datastore.PutUser(ctx, user)
} else if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
// setup the post-commit hook with the remote system and
// if necessary, register the public key
var hook = fmt.Sprintf("%s/api/hook/%s/%s", httputil.GetURL(r), repo.Remote, repo.Token)
if err := remote.Deactivate(user, repo, hook); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
// disable everything // disable everything
repo.Active = false repo.Active = false
repo.PullRequest = false repo.PullRequest = false