Repository: ankitpokhrel/jira-cli
Pull request #139 (2021-09-11 19:14:56)

feat: Support clone cmd for on-premise jira installation


Patch:
diff --git a/api/client.go b/api/client.go
index 2528d67..9bcca8e 100644
--- a/api/client.go
+++ b/api/client.go
@@ -32,3 +32,43 @@ func Client(config jira.Config) *jira.Client {
 
 	return jiraClient
 }
+
+// ProxyCreate uses either a v2 or v3 version of the Jira POST /issue
+// endpoint to create an issue based on configured installation type.
+// Defaults to v3 if installation type is not defined in the config.
+func ProxyCreate(c *jira.Client, cr *jira.CreateRequest) (*jira.CreateResponse, error) {
+	var (
+		resp *jira.CreateResponse
+		err  error
+	)
+
+	it := viper.GetString("installation")
+
+	if it == jira.InstallationTypeLocal {
+		resp, err = c.CreateV2(cr)
+	} else {
+		resp, err = c.Create(cr)
+	}
+
+	return resp, err
+}
+
+// ProxyGetIssue uses either a v2 or v3 version of the Jira GET /issue/{key}
+// endpoint to fetch the issue details based on configured installation type.
+// Defaults to v3 if installation type is not defined in the config.
+func ProxyGetIssue(c *jira.Client, key string) (*jira.Issue, error) {
+	var (
+		issue *jira.Issue
+		err   error
+	)
+
+	it := viper.GetString("installation")
+
+	if it == jira.InstallationTypeLocal {
+		issue, err = c.GetIssueV2(key)
+	} else {
+		issue, err = c.GetIssue(key)
+	}
+
+	return issue, err
+}
diff --git a/internal/cmd/issue/clone/clone.go b/internal/cmd/issue/clone/clone.go
index 4c9abb5..0e04f16 100644
--- a/internal/cmd/issue/clone/clone.go
+++ b/internal/cmd/issue/clone/clone.go
@@ -61,7 +61,7 @@ func clone(cmd *cobra.Command, args []string) {
 		s := cmdutil.Info("Fetching issue details...")
 		defer s.Stop()
 
-		issue, err := api.Client(jira.Config{Debug: cc.params.debug}).GetIssue(key)
+		issue, err := api.ProxyGetIssue(client, key)
 		cmdutil.ExitIfError(err)
 
 		return issue
@@ -83,7 +83,7 @@ func clone(cmd *cobra.Command, args []string) {
 			Components: cp.components,
 		}
 
-		resp, err := client.Create(&cr)
+		resp, err := api.ProxyCreate(client, &cr)
 		cmdutil.ExitIfError(err)
 
 		return resp.Key
@@ -182,7 +182,12 @@ func (cc *cloneCmd) getActualCreateParams(issue *jira.Issue) *createParams {
 		cp.components = cc.params.components
 	}
 
-	body := issue.Fields.Description.(*adf.ADF)
+	var body interface{}
+
+	body, isADF := issue.Fields.Description.(*adf.ADF)
+	if !isADF {
+		body = issue.Fields.Description.(string)
+	}
 
 	if cc.params.replace != "" {
 		pieces := strings.Split(cc.params.replace, ":")
@@ -193,7 +198,12 @@ func (cc *cloneCmd) getActualCreateParams(issue *jira.Issue) *createParams {
 			from, to := pieces[0], pieces[1]
 
 			cp.summary = strings.ReplaceAll(cp.summary, from, to)
-			body.ReplaceAll(from, to)
+
+			if isADF {
+				body.(*adf.ADF).ReplaceAll(from, to)
+			} else {
+				body = strings.ReplaceAll(body.(string), from, to)
+			}
 		}
 	}
 	cp.body = body
diff --git a/internal/config/generator.go b/internal/config/generator.go
index 4fbf889..cd20970 100644
--- a/internal/config/generator.go
+++ b/internal/config/generator.go
@@ -22,11 +22,6 @@ const (
 	FileName = ".config"
 	// FileExt is a jira-cli config file extension.
 	FileExt = "yml"
-
-	// InstallationTypeCloud represents Jira cloud server.
-	InstallationTypeCloud = "Cloud"
-	// InstallationTypeLocal represents on-premise Jira servers.
-	InstallationTypeLocal = "Local"
 )
 
 var (
@@ -148,7 +143,7 @@ func (c *JiraCLIConfig) configureServerAndLoginDetails() error {
 		},
 	}
 
-	if c.value.installation == InstallationTypeCloud {
+	if c.value.installation == jira.InstallationTypeCloud {
 		qs = append(qs, &survey.Question{
 			Name: "login",
 			Prompt: &survey.Input{
@@ -177,7 +172,7 @@ func (c *JiraCLIConfig) configureServerAndLoginDetails() error {
 				return nil
 			},
 		})
-	} else if c.value.installation == InstallationTypeLocal {
+	} else if c.value.installation == jira.InstallationTypeLocal {
 		qs = append(qs, &survey.Question{
 			Name: "login",
 			Prompt: &survey.Input{
@@ -302,9 +297,9 @@ func (c *JiraCLIConfig) configureMetadata() error {
 		}
 		v := value.(map[string]interface{})
 		if v["name"].(string) == "Epic Name" {
-			if c.value.installation == InstallationTypeCloud {
+			if c.value.installation == jira.InstallationTypeCloud {
 				epicKey = v["key"].(string)
-			} else if c.value.installation == InstallationTypeLocal {
+			} else if c.value.installation == jira.InstallationTypeLocal {
 				epicKey = v["fieldId"].(string)
 			}
 			break
diff --git a/pkg/jira/client.go b/pkg/jira/client.go
index 160a569..1f1a0f6 100644
--- a/pkg/jira/client.go
+++ b/pkg/jira/client.go
@@ -16,6 +16,11 @@ const (
 	// RFC3339 is jira datetime format.
 	RFC3339 = "2006-01-02T15:04:05-0700"
 
+	// InstallationTypeCloud represents Jira cloud server.
+	InstallationTypeCloud = "Cloud"
+	// InstallationTypeLocal represents on-premise Jira servers.
+	InstallationTypeLocal = "Local"
+
 	baseURLv3 = "/rest/api/3"
 	baseURLv2 = "/rest/api/2"
 	baseURLv1 = "/rest/agile/1.0"
diff --git a/pkg/jira/issue.go b/pkg/jira/issue.go
index 9c16a90..edd5e15 100644
--- a/pkg/jira/issue.go
+++ b/pkg/jira/issue.go
@@ -162,7 +162,7 @@ func (c *Client) LinkIssue(inwardIssue, outwardIssue, linkType string) error {
 		return err
 	}
 
-	res, err := c.Post(context.Background(), "/issueLink", body, Header{
+	res, err := c.PostV2(context.Background(), "/issueLink", body, Header{
 		"Accept":       "application/json",
 		"Content-Type": "application/json",
 	})


Test patch:
diff --git a/pkg/jira/issue_test.go b/pkg/jira/issue_test.go
index 8721245..09fb662 100644
--- a/pkg/jira/issue_test.go
+++ b/pkg/jira/issue_test.go
@@ -274,7 +274,7 @@ func TestLinkIssue(t *testing.T) {
 	var unexpectedStatusCode bool
 
 	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		assert.Equal(t, "/rest/api/3/issueLink", r.URL.Path)
+		assert.Equal(t, "/rest/api/2/issueLink", r.URL.Path)
 		assert.Equal(t, "application/json", r.Header.Get("Accept"))
 		assert.Equal(t, "application/json", r.Header.Get("Content-Type"))