From 18b881516668c0f0ad60b5eaf94547555360b99a Mon Sep 17 00:00:00 2001 From: Peter Landoll Date: Sat, 3 Aug 2024 23:12:32 -0400 Subject: [PATCH 1/2] feat: add Bitbucket Cloud and Server import endpoints --- examples/bitbucket_import.go | 50 +++++++++++++++++ import.go | 106 +++++++++++++++++++++++++++++++++++ import_test.go | 99 ++++++++++++++++++++++++++++++++ 3 files changed, 255 insertions(+) create mode 100644 examples/bitbucket_import.go diff --git a/examples/bitbucket_import.go b/examples/bitbucket_import.go new file mode 100644 index 000000000..410ba58be --- /dev/null +++ b/examples/bitbucket_import.go @@ -0,0 +1,50 @@ +package main + +import ( + "log" + + "github.com/xanzy/go-gitlab" +) + +func bitbucketCloudExample() { + git, err := gitlab.NewClient("yourtokengoeshere") + if err != nil { + log.Fatal(err) + } + + cloudOpt := &gitlab.ImportRepositoryFromBitbucketCloudOptions{ + BitbucketUsername: gitlab.Ptr("username"), + BitbucketAppPassword: gitlab.Ptr("password"), + RepoPath: gitlab.Ptr("some/repo"), + TargetNamespace: gitlab.Ptr("some-group"), + NewName: gitlab.Ptr("some-repo"), + } + cloudResp, _, err := git.Import.ImportRepositoryFromBitbucketCloud(cloudOpt) + if err != nil { + log.Fatal(err) + } + log.Print(cloudResp.String()) +} + +func bitbucketServerExample() { + git, err := gitlab.NewClient("yourtokengoeshere") + if err != nil { + log.Fatal(err) + } + + serverOpt := &gitlab.ImportRepositoryFromBitbucketServerOptions{ + BitbucketServerUrl: gitlab.Ptr("https://bitbucket.example.com"), + BitbucketServerUsername: gitlab.Ptr("username"), + PersonalAccessToken: gitlab.Ptr("access-token"), + BitbucketServerProject: gitlab.Ptr("some-project"), + BitbucketServerRepo: gitlab.Ptr("some-repo"), + NewName: gitlab.Ptr("some-other-repo"), + NewNamespace: gitlab.Ptr("some-group"), + TimeoutStrategy: gitlab.Ptr("pessimistic"), + } + serverResp, _, err := git.Import.ImportRepositoryFromBitbucketServer(serverOpt) + if err != nil { + log.Fatal(err) + } + log.Print(serverResp.String()) +} diff --git a/import.go b/import.go index 5178a07d2..0e5731de0 100644 --- a/import.go +++ b/import.go @@ -158,3 +158,109 @@ func (s *ImportService) ImportGitHubGistsIntoGitLabSnippets(opt *ImportGitHubGis return s.client.Do(req, nil) } + +// BitbucketCloudImport represents the response from an import from Bitbucket Cloud. +// This uses the same "ProjectImportEntity" as GitHub, but is copied here to avoid conflicts. +// +// GitLab API docs: +// https://docs.gitlab.com/ee/api/import.html#import-repository-from-bitbucket-cloud +type BitbucketCloudImport struct { + ID int `json:"id"` + Name string `json:"name"` + FullPath string `json:"full_path"` + FullName string `json:"full_name"` + RefsUrl string `json:"refs_url"` + ImportSource string `json:"import_source"` + ImportStatus string `json:"import_status"` + HumanImportStatusName string `json:"human_import_status_name"` + ProviderLink string `json:"provider_link"` + RelationType string `json:"relation_type"` + ImportWarning string `json:"import_warning"` +} + +func (s BitbucketCloudImport) String() string { + return Stringify(s) +} + +// ImportRepositoryFromBitbucketCloudOptions represents the available ImportRepositoryFromBitbucketCloud() options. +// +// GitLab API docs: +// https://docs.gitlab.com/ee/api/import.html#import-repository-from-bitbucket-cloud +type ImportRepositoryFromBitbucketCloudOptions struct { + BitbucketUsername *string `url:"bitbucket_username,omitempty" json:"bitbucket_username,omitempty"` + BitbucketAppPassword *string `url:"bitbucket_app_password,omitempty" json:"bitbucket_app_password,omitempty"` + RepoPath *string `url:"repo_path,omitempty" json:"repo_path,omitempty"` + TargetNamespace *string `url:"target_namespace,omitempty" json:"target_namespace,omitempty"` + NewName *string `url:"new_name,omitempty" json:"new_name,omitempty"` +} + +// Import a repository from Bitbucket Cloud. +// For importing repositories from Bitbucket Server or Data Center, see ImportRepositoryFromBitbucketServer(). +// +// GitLab API docs: +// https://docs.gitlab.com/ee/api/import.html#import-repository-from-bitbucket-cloud +func (s *ImportService) ImportRepositoryFromBitbucketCloud(opt *ImportRepositoryFromBitbucketCloudOptions, options ...RequestOptionFunc) (*BitbucketCloudImport, *Response, error) { + req, err := s.client.NewRequest(http.MethodPost, "import/bitbucket", opt, options) + if err != nil { + return nil, nil, err + } + + bci := new(BitbucketCloudImport) + resp, err := s.client.Do(req, bci) + if err != nil { + return nil, resp, err + } + + return bci, resp, nil +} + +// BitbucketServerImport represents the response from an import from Bitbucket Server. +// +// GitLab API docs: +// https://docs.gitlab.com/ee/api/import.html#import-repository-from-bitbucket-server +type BitbucketServerImport struct { + ID int `json:"id"` + Name string `json:"name"` + FullPath string `json:"full_path"` + FullName string `json:"full_name"` + RefsUrl string `json:"refs_url"` +} + +func (s BitbucketServerImport) String() string { + return Stringify(s) +} + +// ImportRepositoryFromBitbucketServerOptions represents the available ImportRepositoryFromBitbucketServer() options. +// +// GitLab API docs: +// https://docs.gitlab.com/ee/api/import.html#import-repository-from-bitbucket-server +type ImportRepositoryFromBitbucketServerOptions struct { + BitbucketServerUrl *string `url:"bitbucket_server_url,omitempty" json:"bitbucket_server_url,omitempty"` + BitbucketServerUsername *string `url:"bitbucket_server_username,omitempty" json:"bitbucket_server_username,omitempty"` + PersonalAccessToken *string `url:"personal_access_token,omitempty" json:"personal_access_token,omitempty"` + BitbucketServerProject *string `url:"bitbucket_server_project,omitempty" json:"bitbucket_server_project,omitempty"` + BitbucketServerRepo *string `url:"bitbucket_server_repo,omitempty" json:"bitbucket_server_repo,omitempty"` + NewName *string `url:"new_name,omitempty" json:"new_name,omitempty"` + NewNamespace *string `url:"new_namespace,omitempty" json:"new_namespace,omitempty"` + TimeoutStrategy *string `url:"timeout_strategy,omitempty" json:"timeout_strategy,omitempty"` +} + +// Import a repository from Bitbucket Server. +// For importing repositories from Bitbucket Cloud, see ImportRepositoryFromBitbucketCloud(). +// +// GitLab API docs: +// https://docs.gitlab.com/ee/api/import.html#import-repository-from-bitbucket-server +func (s *ImportService) ImportRepositoryFromBitbucketServer(opt *ImportRepositoryFromBitbucketServerOptions, options ...RequestOptionFunc) (*BitbucketServerImport, *Response, error) { + req, err := s.client.NewRequest(http.MethodPost, "import/bitbucket_server", opt, options) + if err != nil { + return nil, nil, err + } + + bsi := new(BitbucketServerImport) + resp, err := s.client.Do(req, bsi) + if err != nil { + return nil, resp, err + } + + return bsi, resp, nil +} diff --git a/import_test.go b/import_test.go index 81808e513..8a7c5c7c7 100644 --- a/import_test.go +++ b/import_test.go @@ -121,3 +121,102 @@ func TestImportService_ImportGitHubGistsIntoGitLabSnippets(t *testing.T) { require.EqualError(t, err, "RequestOptionFunc returns an error") require.Nil(t, resp) } + +func TestImportService_ImportRepositoryFromBitbucketCloud(t *testing.T) { + mux, client := setup(t) + + mux.HandleFunc("/api/v4/import/bitbucket", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, http.MethodPost) + fmt.Fprintf(w, ` + { + "id": 27, + "name": "my-repo", + "full_path": "/root/my-repo", + "full_name": "Administrator / my-repo", + "refs_url": "/root/my-repo/refs", + "import_source": "my-bitbucket/repo", + "import_status": "scheduled", + "human_import_status_name": "scheduled", + "provider_link": "/my-bitbucket/repo", + "relation_type": null, + "import_warning": null + } + `) + }) + + want := &BitbucketCloudImport{ + ID: 27, + Name: "my-repo", + FullPath: "/root/my-repo", + FullName: "Administrator / my-repo", + RefsUrl: "/root/my-repo/refs", + ImportSource: "my-bitbucket/repo", + ImportStatus: "scheduled", + HumanImportStatusName: "scheduled", + ProviderLink: "/my-bitbucket/repo", + } + + opt := &ImportRepositoryFromBitbucketCloudOptions{ + BitbucketUsername: Ptr("username"), + BitbucketAppPassword: Ptr("password"), + RepoPath: Ptr("/root/my-repo"), + TargetNamespace: Ptr("/root/"), + NewName: Ptr("my-repo"), + } + + bci, resp, err := client.Import.ImportRepositoryFromBitbucketCloud(opt) + require.NoError(t, err) + require.NotNil(t, resp) + require.Equal(t, want, bci) + + bci, resp, err = client.Import.ImportRepositoryFromBitbucketCloud(opt, errorOption) + require.EqualError(t, err, "RequestOptionFunc returns an error") + require.Nil(t, resp) + require.Nil(t, bci) +} + +func TestImportService_ImportRepositoryFromBitbucketServer(t *testing.T) { + mux, client := setup(t) + + mux.HandleFunc("/api/v4/import/bitbucket_server", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, http.MethodPost) + fmt.Fprintf(w, ` + { + "id": 27, + "name": "my-repo", + "full_path": "/root/my-repo", + "full_name": "Administrator / my-repo", + "refs_url": "/root/my-repo/refs" + } + `) + }) + + want := &BitbucketServerImport{ + ID: 27, + Name: "my-repo", + FullPath: "/root/my-repo", + FullName: "Administrator / my-repo", + RefsUrl: "/root/my-repo/refs", + } + + opt := &ImportRepositoryFromBitbucketServerOptions{ + BitbucketServerUrl: Ptr("https://bitbucket.example.com"), + BitbucketServerUsername: Ptr("username"), + PersonalAccessToken: Ptr("token"), + BitbucketServerProject: Ptr("root"), + BitbucketServerRepo: Ptr("my-repo"), + NewName: Ptr("my-repo"), + NewNamespace: Ptr("root"), + TimeoutStrategy: Ptr("pessimistic"), + } + + bsi, resp, err := client.Import.ImportRepositoryFromBitbucketServer(opt) + require.NoError(t, err) + require.NotNil(t, resp) + require.Equal(t, want, bsi) + + bsi, resp, err = client.Import.ImportRepositoryFromBitbucketServer(opt, errorOption) + require.EqualError(t, err, "RequestOptionFunc returns an error") + require.Nil(t, resp) + require.Nil(t, bsi) +} From 449f5213dd4f39623b896646394180f7d12dc7f3 Mon Sep 17 00:00:00 2001 From: Sander van Harmelen Date: Thu, 8 Aug 2024 14:36:48 +0200 Subject: [PATCH 2/2] Few minor styling tweaks --- import.go | 110 ++++++++++++++++++++++++------------------------- import_test.go | 92 ++++++++++++++++++++--------------------- 2 files changed, 101 insertions(+), 101 deletions(-) diff --git a/import.go b/import.go index 0e5731de0..a8164a70c 100644 --- a/import.go +++ b/import.go @@ -159,8 +159,59 @@ func (s *ImportService) ImportGitHubGistsIntoGitLabSnippets(opt *ImportGitHubGis return s.client.Do(req, nil) } -// BitbucketCloudImport represents the response from an import from Bitbucket Cloud. -// This uses the same "ProjectImportEntity" as GitHub, but is copied here to avoid conflicts. +// BitbucketServerImport represents the response from an import from Bitbucket +// Server. +// +// GitLab API docs: +// https://docs.gitlab.com/ee/api/import.html#import-repository-from-bitbucket-server +type BitbucketServerImport struct { + ID int `json:"id"` + Name string `json:"name"` + FullPath string `json:"full_path"` + FullName string `json:"full_name"` + RefsUrl string `json:"refs_url"` +} + +func (s BitbucketServerImport) String() string { + return Stringify(s) +} + +// ImportRepositoryFromBitbucketServerOptions represents the available ImportRepositoryFromBitbucketServer() options. +// +// GitLab API docs: +// https://docs.gitlab.com/ee/api/import.html#import-repository-from-bitbucket-server +type ImportRepositoryFromBitbucketServerOptions struct { + BitbucketServerUrl *string `url:"bitbucket_server_url,omitempty" json:"bitbucket_server_url,omitempty"` + BitbucketServerUsername *string `url:"bitbucket_server_username,omitempty" json:"bitbucket_server_username,omitempty"` + PersonalAccessToken *string `url:"personal_access_token,omitempty" json:"personal_access_token,omitempty"` + BitbucketServerProject *string `url:"bitbucket_server_project,omitempty" json:"bitbucket_server_project,omitempty"` + BitbucketServerRepo *string `url:"bitbucket_server_repo,omitempty" json:"bitbucket_server_repo,omitempty"` + NewName *string `url:"new_name,omitempty" json:"new_name,omitempty"` + NewNamespace *string `url:"new_namespace,omitempty" json:"new_namespace,omitempty"` + TimeoutStrategy *string `url:"timeout_strategy,omitempty" json:"timeout_strategy,omitempty"` +} + +// Import a repository from Bitbucket Server. +// +// GitLab API docs: +// https://docs.gitlab.com/ee/api/import.html#import-repository-from-bitbucket-server +func (s *ImportService) ImportRepositoryFromBitbucketServer(opt *ImportRepositoryFromBitbucketServerOptions, options ...RequestOptionFunc) (*BitbucketServerImport, *Response, error) { + req, err := s.client.NewRequest(http.MethodPost, "import/bitbucket_server", opt, options) + if err != nil { + return nil, nil, err + } + + bsi := new(BitbucketServerImport) + resp, err := s.client.Do(req, bsi) + if err != nil { + return nil, resp, err + } + + return bsi, resp, nil +} + +// BitbucketCloudImport represents the response from an import from Bitbucket +// Cloud. // // GitLab API docs: // https://docs.gitlab.com/ee/api/import.html#import-repository-from-bitbucket-cloud @@ -182,7 +233,8 @@ func (s BitbucketCloudImport) String() string { return Stringify(s) } -// ImportRepositoryFromBitbucketCloudOptions represents the available ImportRepositoryFromBitbucketCloud() options. +// ImportRepositoryFromBitbucketCloudOptions represents the available +// ImportRepositoryFromBitbucketCloud() options. // // GitLab API docs: // https://docs.gitlab.com/ee/api/import.html#import-repository-from-bitbucket-cloud @@ -195,7 +247,6 @@ type ImportRepositoryFromBitbucketCloudOptions struct { } // Import a repository from Bitbucket Cloud. -// For importing repositories from Bitbucket Server or Data Center, see ImportRepositoryFromBitbucketServer(). // // GitLab API docs: // https://docs.gitlab.com/ee/api/import.html#import-repository-from-bitbucket-cloud @@ -213,54 +264,3 @@ func (s *ImportService) ImportRepositoryFromBitbucketCloud(opt *ImportRepository return bci, resp, nil } - -// BitbucketServerImport represents the response from an import from Bitbucket Server. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/import.html#import-repository-from-bitbucket-server -type BitbucketServerImport struct { - ID int `json:"id"` - Name string `json:"name"` - FullPath string `json:"full_path"` - FullName string `json:"full_name"` - RefsUrl string `json:"refs_url"` -} - -func (s BitbucketServerImport) String() string { - return Stringify(s) -} - -// ImportRepositoryFromBitbucketServerOptions represents the available ImportRepositoryFromBitbucketServer() options. -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/import.html#import-repository-from-bitbucket-server -type ImportRepositoryFromBitbucketServerOptions struct { - BitbucketServerUrl *string `url:"bitbucket_server_url,omitempty" json:"bitbucket_server_url,omitempty"` - BitbucketServerUsername *string `url:"bitbucket_server_username,omitempty" json:"bitbucket_server_username,omitempty"` - PersonalAccessToken *string `url:"personal_access_token,omitempty" json:"personal_access_token,omitempty"` - BitbucketServerProject *string `url:"bitbucket_server_project,omitempty" json:"bitbucket_server_project,omitempty"` - BitbucketServerRepo *string `url:"bitbucket_server_repo,omitempty" json:"bitbucket_server_repo,omitempty"` - NewName *string `url:"new_name,omitempty" json:"new_name,omitempty"` - NewNamespace *string `url:"new_namespace,omitempty" json:"new_namespace,omitempty"` - TimeoutStrategy *string `url:"timeout_strategy,omitempty" json:"timeout_strategy,omitempty"` -} - -// Import a repository from Bitbucket Server. -// For importing repositories from Bitbucket Cloud, see ImportRepositoryFromBitbucketCloud(). -// -// GitLab API docs: -// https://docs.gitlab.com/ee/api/import.html#import-repository-from-bitbucket-server -func (s *ImportService) ImportRepositoryFromBitbucketServer(opt *ImportRepositoryFromBitbucketServerOptions, options ...RequestOptionFunc) (*BitbucketServerImport, *Response, error) { - req, err := s.client.NewRequest(http.MethodPost, "import/bitbucket_server", opt, options) - if err != nil { - return nil, nil, err - } - - bsi := new(BitbucketServerImport) - resp, err := s.client.Do(req, bsi) - if err != nil { - return nil, resp, err - } - - return bsi, resp, nil -} diff --git a/import_test.go b/import_test.go index 8a7c5c7c7..1dfd9a204 100644 --- a/import_test.go +++ b/import_test.go @@ -122,6 +122,52 @@ func TestImportService_ImportGitHubGistsIntoGitLabSnippets(t *testing.T) { require.Nil(t, resp) } +func TestImportService_ImportRepositoryFromBitbucketServer(t *testing.T) { + mux, client := setup(t) + + mux.HandleFunc("/api/v4/import/bitbucket_server", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, http.MethodPost) + fmt.Fprintf(w, ` + { + "id": 27, + "name": "my-repo", + "full_path": "/root/my-repo", + "full_name": "Administrator / my-repo", + "refs_url": "/root/my-repo/refs" + } + `) + }) + + want := &BitbucketServerImport{ + ID: 27, + Name: "my-repo", + FullPath: "/root/my-repo", + FullName: "Administrator / my-repo", + RefsUrl: "/root/my-repo/refs", + } + + opt := &ImportRepositoryFromBitbucketServerOptions{ + BitbucketServerUrl: Ptr("https://bitbucket.example.com"), + BitbucketServerUsername: Ptr("username"), + PersonalAccessToken: Ptr("token"), + BitbucketServerProject: Ptr("root"), + BitbucketServerRepo: Ptr("my-repo"), + NewName: Ptr("my-repo"), + NewNamespace: Ptr("root"), + TimeoutStrategy: Ptr("pessimistic"), + } + + bsi, resp, err := client.Import.ImportRepositoryFromBitbucketServer(opt) + require.NoError(t, err) + require.NotNil(t, resp) + require.Equal(t, want, bsi) + + bsi, resp, err = client.Import.ImportRepositoryFromBitbucketServer(opt, errorOption) + require.EqualError(t, err, "RequestOptionFunc returns an error") + require.Nil(t, resp) + require.Nil(t, bsi) +} + func TestImportService_ImportRepositoryFromBitbucketCloud(t *testing.T) { mux, client := setup(t) @@ -174,49 +220,3 @@ func TestImportService_ImportRepositoryFromBitbucketCloud(t *testing.T) { require.Nil(t, resp) require.Nil(t, bci) } - -func TestImportService_ImportRepositoryFromBitbucketServer(t *testing.T) { - mux, client := setup(t) - - mux.HandleFunc("/api/v4/import/bitbucket_server", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, http.MethodPost) - fmt.Fprintf(w, ` - { - "id": 27, - "name": "my-repo", - "full_path": "/root/my-repo", - "full_name": "Administrator / my-repo", - "refs_url": "/root/my-repo/refs" - } - `) - }) - - want := &BitbucketServerImport{ - ID: 27, - Name: "my-repo", - FullPath: "/root/my-repo", - FullName: "Administrator / my-repo", - RefsUrl: "/root/my-repo/refs", - } - - opt := &ImportRepositoryFromBitbucketServerOptions{ - BitbucketServerUrl: Ptr("https://bitbucket.example.com"), - BitbucketServerUsername: Ptr("username"), - PersonalAccessToken: Ptr("token"), - BitbucketServerProject: Ptr("root"), - BitbucketServerRepo: Ptr("my-repo"), - NewName: Ptr("my-repo"), - NewNamespace: Ptr("root"), - TimeoutStrategy: Ptr("pessimistic"), - } - - bsi, resp, err := client.Import.ImportRepositoryFromBitbucketServer(opt) - require.NoError(t, err) - require.NotNil(t, resp) - require.Equal(t, want, bsi) - - bsi, resp, err = client.Import.ImportRepositoryFromBitbucketServer(opt, errorOption) - require.EqualError(t, err, "RequestOptionFunc returns an error") - require.Nil(t, resp) - require.Nil(t, bsi) -}