From 8cea03e45d97e0018f379ad946238daeea00fb97 Mon Sep 17 00:00:00 2001 From: Jonas Bechstein Date: Wed, 30 Oct 2019 23:19:38 +0100 Subject: [PATCH] add feature to fork existing repositories --- bitbucket/resource_repository.go | 96 +++++++++++++++++++++----- docusaurus/docs/resource_repository.md | 13 +++- go.mod | 2 + 3 files changed, 92 insertions(+), 19 deletions(-) diff --git a/bitbucket/resource_repository.go b/bitbucket/resource_repository.go index 6ccf522..3a7af79 100644 --- a/bitbucket/resource_repository.go +++ b/bitbucket/resource_repository.go @@ -26,6 +26,18 @@ type Repository struct { } `json:"links,omitempty"` } +type ForkRepositoryRequestBody struct { + Name string `json:"name,omitempty"` + Slug string `json:"slug,omitempty"` + Description string `json:"description,omitempty"` + Forkable bool `json:"forkable,omitempty"` + Public bool `json:"public,omitempty"` + Links struct { + Clone []CloneUrl `json:"clone,omitempty"` + } `json:"links,omitempty"` + Project Project `json:"project,omitempty"` +} + func resourceRepository() *schema.Resource { return &schema.Resource{ Create: resourceRepositoryCreate, @@ -67,6 +79,11 @@ func resourceRepository() *schema.Resource { Optional: true, Default: false, }, + "origin_slug_to_fork": { + Type: schema.TypeString, + Optional: true, + Default: false, + }, "enable_git_lfs": { Type: schema.TypeBool, Optional: true, @@ -84,7 +101,7 @@ func resourceRepository() *schema.Resource { } } -func newRepositoryFromResource(d *schema.ResourceData) (Repo *Repository, Project string) { +func newRepositoryFromResource(d *schema.ResourceData) (Repo *Repository) { repo := &Repository{ Name: d.Get("name").(string), Slug: d.Get("slug").(string), @@ -93,12 +110,26 @@ func newRepositoryFromResource(d *schema.ResourceData) (Repo *Repository, Projec Public: d.Get("public").(bool), } - return repo, d.Get("project").(string) + return repo +} + +func newForkedRepositoryFromResource(d *schema.ResourceData) (Repo *ForkRepositoryRequestBody) { + req := &ForkRepositoryRequestBody{ + Name: d.Get("name").(string), + Slug: d.Get("slug").(string), + Description: d.Get("description").(string), + Forkable: d.Get("forkable").(bool), + Public: d.Get("public").(bool), + Project: Project{Key: d.Get("project").(string)}, + } + + return req } func resourceRepositoryUpdate(d *schema.ResourceData, m interface{}) error { client := m.(*BitbucketServerProvider).BitbucketClient - repo, project := newRepositoryFromResource(d) + project := d.Get("project").(string) + repo := newRepositoryFromResource(d) bytedata, err := json.Marshal(repo) @@ -127,26 +158,27 @@ func resourceRepositoryUpdate(d *schema.ResourceData, m interface{}) error { func resourceRepositoryCreate(d *schema.ResourceData, m interface{}) error { client := m.(*BitbucketServerProvider).BitbucketClient - repo, project := newRepositoryFromResource(d) + + project := d.Get("project").(string) repoSlug := determineSlug(d) + name := d.Get("name").(string) - bytedata, err := json.Marshal(repo) - - if err != nil { - return err + forkSlug := d.Get("fork_slug").(string) + if forkSlug != "" { + err := createForkRepository(client, d, project, forkSlug) + if err != nil { + return err + } + } else { + err := createNewRepository(client, d, project) + if err != nil { + return err + } } - _, err = client.Post(fmt.Sprintf("/rest/api/1.0/projects/%s/repos", - project, - ), bytes.NewBuffer(bytedata)) + d.SetId(string(fmt.Sprintf("%s/%s", project, name))) - if err != nil { - return err - } - - d.SetId(string(fmt.Sprintf("%s/%s", project, repo.Name))) - - err = handleRepositoryGitLFSChanges(client, project, repoSlug, d) + err := handleRepositoryGitLFSChanges(client, project, repoSlug, d) if err != nil { return err } @@ -154,6 +186,34 @@ func resourceRepositoryCreate(d *schema.ResourceData, m interface{}) error { return resourceRepositoryRead(d, m) } +func createNewRepository(client *BitbucketClient, d *schema.ResourceData, project string) error { + repo := newRepositoryFromResource(d) + bytedata, err := json.Marshal(repo) + if err != nil { + return err + } + _, err = client.Post(fmt.Sprintf("/rest/api/1.0/projects/%s/repos", + project, + ), bytes.NewBuffer(bytedata)) + if err != nil { + return err + } + return nil +} + +func createForkRepository(client *BitbucketClient, d *schema.ResourceData, project string, forkSlug string) error { + requestBody := newForkedRepositoryFromResource(d) + bytedata, err := json.Marshal(requestBody) + if err != nil { + return err + } + _, err = client.Post(fmt.Sprintf("/rest/api/1.0/projects/%s/repos/%s", project, forkSlug), bytes.NewBuffer(bytedata)) + if err != nil { + return err + } + return nil +} + func handleRepositoryGitLFSChanges(client *BitbucketClient, project string, repoSlug string, d *schema.ResourceData) error { enableGitLFS := d.Get("enable_git_lfs").(bool) if (d.IsNewResource() && enableGitLFS) || d.HasChange("enable_git_lfs") { diff --git a/docusaurus/docs/resource_repository.md b/docusaurus/docs/resource_repository.md index cd43a04..cc07a04 100644 --- a/docusaurus/docs/resource_repository.md +++ b/docusaurus/docs/resource_repository.md @@ -15,6 +15,17 @@ resource "bitbucketserver_repository" "test" { } ``` +###### if you want to fork an existing repository in the same project + +```hcl +resource "bitbucketserver_repository" "test" { + project = "MYPROJ" + name = "test-01" + description = "Test repository" + origin_slug_to_fork = "MYOLDPROJ" +} +``` + ## Argument Reference * `project` - Required. Name of the project to create the repository in. @@ -24,7 +35,7 @@ resource "bitbucketserver_repository" "test" { * `forkable` - Optional. Enable/disable forks of this repository. Default `true` * `public` - Optional. Determine if this repository is public. Default `false` * `enable_git_lfs` - Optional. Enable git-lfs for this repository. Default `false` - +* `origin_slug_to_fork` - Optional. Use this to fork an expisting repository in the same project. Default `false` ## Attribute Reference Additional to the above, the following attributes are emitted: diff --git a/go.mod b/go.mod index 3785c54..d1c259b 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,5 @@ module github.com/gavinbunney/terraform-provider-bitbucketserver require github.com/hashicorp/terraform v0.12.2 + +go 1.13