Repository: ankitpokhrel/jira-cli
Pull request #53 (2021-01-04 18:20:36)

feat: Filter by component


Patch:
diff --git a/internal/cmd/issue/list/list.go b/internal/cmd/issue/list/list.go
index 97165b7..3cb1c05 100644
--- a/internal/cmd/issue/list/list.go
+++ b/internal/cmd/issue/list/list.go
@@ -118,6 +118,7 @@ func SetFlags(cmd *cobra.Command) {
 	cmd.Flags().StringP("priority", "y", "", "Filter issues by priority")
 	cmd.Flags().StringP("reporter", "r", "", "Filter issues by reporter (email or display name)")
 	cmd.Flags().StringP("assignee", "a", "", "Filter issues by assignee (email or display name)")
+	cmd.Flags().StringP("component", "C", "", "Filter issues by component")
 	cmd.Flags().StringArrayP("label", "l", []string{}, "Filter issues by label")
 	cmd.Flags().Bool("history", false, "Issues you accessed recently")
 	cmd.Flags().BoolP("watching", "w", false, "Issues you are watching")
diff --git a/internal/query/issue.go b/internal/query/issue.go
index 8a1f75c..95479c0 100644
--- a/internal/query/issue.go
+++ b/internal/query/issue.go
@@ -44,7 +44,8 @@ func (i *Issue) Get() string {
 			FilterBy("status", i.params.status).
 			FilterBy("priority", i.params.priority).
 			FilterBy("reporter", i.params.reporter).
-			FilterBy("assignee", i.params.assignee)
+			FilterBy("assignee", i.params.assignee).
+			FilterBy("component", i.params.component)
 
 		i.setCreatedFilters(q)
 		i.setUpdatedFilters(q)
@@ -139,6 +140,7 @@ type issueParams struct {
 	priority      string
 	reporter      string
 	assignee      string
+	component     string
 	created       string
 	updated       string
 	createdAfter  string
@@ -155,9 +157,8 @@ func (ip *issueParams) init(flags FlagParser) error {
 
 	boolParams := []string{"history", "watching", "reverse", "debug"}
 	stringParams := []string{
-		"resolution", "type", "status", "priority", "reporter", "assignee",
-		"created", "created-after", "created-before",
-		"updated", "updated-after", "updated-before",
+		"resolution", "type", "status", "priority", "reporter", "assignee", "component",
+		"created", "created-after", "created-before", "updated", "updated-after", "updated-before",
 	}
 
 	boolParamsMap := make(map[string]bool)
@@ -216,6 +217,8 @@ func (ip *issueParams) setStringParams(paramsMap map[string]string) {
 			ip.reporter = v
 		case "assignee":
 			ip.assignee = v
+		case "component":
+			ip.component = v
 		case "created":
 			ip.created = v
 		case "created-after":
diff --git a/pkg/adf/adf.go b/pkg/adf/adf.go
index 3d60c50..98b1fb6 100644
--- a/pkg/adf/adf.go
+++ b/pkg/adf/adf.go
@@ -31,12 +31,11 @@ const (
 	InlineNodeMention   = "mention"
 	InlineNodeHardBreak = "hardBreak"
 
-	MarkEm        = "em"
-	MarkLink      = "link"
-	MarkCode      = "code"
-	MarkStrike    = "strike"
-	MarkStrong    = "strong"
-	MarkUnderline = "underline"
+	MarkEm     = "em"
+	MarkLink   = "link"
+	MarkCode   = "code"
+	MarkStrike = "strike"
+	MarkStrong = "strong"
 )
 
 // TagOpener is a tag opener.
diff --git a/pkg/adf/markdown.go b/pkg/adf/markdown.go
index c97a94e..0ccffc1 100644
--- a/pkg/adf/markdown.go
+++ b/pkg/adf/markdown.go
@@ -77,8 +77,6 @@ func (tr *MarkdownTranslator) Open(n Connector, d int) string {
 		tag.WriteString(" **")
 	case MarkEm:
 		tag.WriteString(" _")
-	case MarkUnderline:
-		tag.WriteString(" +")
 	case MarkCode:
 		tag.WriteString(" `")
 	case MarkStrike:
@@ -140,8 +138,6 @@ func (tr *MarkdownTranslator) Close(n Connector) string {
 		tag.WriteString("** ")
 	case MarkEm:
 		tag.WriteString("_ ")
-	case MarkUnderline:
-		tag.WriteString("+ ")
 	case MarkCode:
 		tag.WriteString("` ")
 	case MarkStrike:


Test patch:
diff --git a/internal/query/issue_test.go b/internal/query/issue_test.go
index f46dda3..eb784ec 100644
--- a/internal/query/issue_test.go
+++ b/internal/query/issue_test.go
@@ -118,8 +118,8 @@ func TestIssueGet(t *testing.T) {
 				return i
 			},
 			expected: `project="TEST" AND issue IN issueHistory() AND issue IN watchedIssues() AND ` +
-				`type="test" AND resolution="test" AND status="test" AND priority="test" AND reporter="test" AND assignee="test" ` +
-				`ORDER BY lastViewed ASC`,
+				`type="test" AND resolution="test" AND status="test" AND priority="test" AND reporter="test" ` +
+				`AND assignee="test" AND component="test" ORDER BY lastViewed ASC`,
 		},
 		{
 			name: "query without issue history parameter",
@@ -129,8 +129,8 @@ func TestIssueGet(t *testing.T) {
 				return i
 			},
 			expected: `project="TEST" AND issue IN watchedIssues() AND ` +
-				`type="test" AND resolution="test" AND status="test" AND priority="test" AND reporter="test" AND assignee="test" ` +
-				`ORDER BY created ASC`,
+				`type="test" AND resolution="test" AND status="test" AND priority="test" AND reporter="test" ` +
+				`AND assignee="test" AND component="test" ORDER BY created ASC`,
 		},
 		{
 			name: "query only with fields filter",
@@ -140,8 +140,8 @@ func TestIssueGet(t *testing.T) {
 				return i
 			},
 			expected: `project="TEST" AND ` +
-				`type="test" AND resolution="test" AND status="test" AND priority="test" AND reporter="test" AND assignee="test" ` +
-				`ORDER BY created ASC`,
+				`type="test" AND resolution="test" AND status="test" AND priority="test" AND reporter="test" ` +
+				`AND assignee="test" AND component="test" ORDER BY created ASC`,
 		},
 		{
 			name: "query with error when fetching history flag",
@@ -207,7 +207,7 @@ func TestIssueGet(t *testing.T) {
 			},
 			expected: `project="TEST" AND issue IN issueHistory() AND issue IN watchedIssues() AND ` +
 				`resolution="test" AND status="test" AND priority="test" AND reporter="test" AND assignee="test" ` +
-				`ORDER BY lastViewed ASC`,
+				`AND component="test" ORDER BY lastViewed ASC`,
 		},
 		{
 			name: "query with reverse set to true",
@@ -217,8 +217,8 @@ func TestIssueGet(t *testing.T) {
 				return i
 			},
 			expected: `project="TEST" AND issue IN issueHistory() AND issue IN watchedIssues() AND ` +
-				`type="test" AND resolution="test" AND status="test" AND priority="test" AND reporter="test" AND assignee="test" ` +
-				`ORDER BY lastViewed DESC`,
+				`type="test" AND resolution="test" AND status="test" AND priority="test" AND reporter="test" ` +
+				`AND assignee="test" AND component="test" ORDER BY lastViewed DESC`,
 		},
 		{
 			name: "query with labels",
@@ -229,7 +229,7 @@ func TestIssueGet(t *testing.T) {
 			},
 			expected: `project="TEST" AND issue IN issueHistory() AND issue IN watchedIssues() AND ` +
 				`type="test" AND resolution="test" AND status="test" AND priority="test" AND reporter="test" AND assignee="test" ` +
-				`AND labels IN ("first", "second", "third") ORDER BY lastViewed ASC`,
+				`AND component="test" AND labels IN ("first", "second", "third") ORDER BY lastViewed ASC`,
 		},
 		{
 			name: "query with created and updated today filter",
@@ -240,7 +240,7 @@ func TestIssueGet(t *testing.T) {
 			},
 			expected: `project="TEST" AND issue IN issueHistory() AND issue IN watchedIssues() AND ` +
 				`type="test" AND resolution="test" AND status="test" AND priority="test" AND reporter="test" AND assignee="test" ` +
-				`AND createdDate>=startOfDay() AND updatedDate>=startOfDay() ORDER BY lastViewed ASC`,
+				`AND component="test" AND createdDate>=startOfDay() AND updatedDate>=startOfDay() ORDER BY lastViewed ASC`,
 		},
 		{
 			name: "query with created and updated week filter",
@@ -251,7 +251,7 @@ func TestIssueGet(t *testing.T) {
 			},
 			expected: `project="TEST" AND issue IN issueHistory() AND issue IN watchedIssues() AND ` +
 				`type="test" AND resolution="test" AND status="test" AND priority="test" AND reporter="test" AND assignee="test" ` +
-				`AND createdDate>=startOfWeek() AND updatedDate>=startOfWeek() ORDER BY lastViewed ASC`,
+				`AND component="test" AND createdDate>=startOfWeek() AND updatedDate>=startOfWeek() ORDER BY lastViewed ASC`,
 		},
 		{
 			name: "query with created and updated month filter",
@@ -262,7 +262,7 @@ func TestIssueGet(t *testing.T) {
 			},
 			expected: `project="TEST" AND issue IN issueHistory() AND issue IN watchedIssues() AND ` +
 				`type="test" AND resolution="test" AND status="test" AND priority="test" AND reporter="test" AND assignee="test" ` +
-				`AND createdDate>=startOfMonth() AND updatedDate>=startOfMonth() ORDER BY lastViewed ASC`,
+				`AND component="test" AND createdDate>=startOfMonth() AND updatedDate>=startOfMonth() ORDER BY lastViewed ASC`,
 		},
 		{
 			name: "query with created and updated year filter",
@@ -273,7 +273,7 @@ func TestIssueGet(t *testing.T) {
 			},
 			expected: `project="TEST" AND issue IN issueHistory() AND issue IN watchedIssues() AND ` +
 				`type="test" AND resolution="test" AND status="test" AND priority="test" AND reporter="test" AND assignee="test" ` +
-				`AND createdDate>=startOfYear() AND updatedDate>=startOfYear() ORDER BY lastViewed ASC`,
+				`AND component="test" AND createdDate>=startOfYear() AND updatedDate>=startOfYear() ORDER BY lastViewed ASC`,
 		},
 		{
 			name: "query with created and updated filter",
@@ -283,7 +283,7 @@ func TestIssueGet(t *testing.T) {
 				return i
 			},
 			expected: `project="TEST" AND issue IN issueHistory() AND issue IN watchedIssues() AND ` +
-				`type="test" AND resolution="test" AND status="test" AND priority="test" AND reporter="test" AND assignee="test" ` +
+				`type="test" AND resolution="test" AND status="test" AND priority="test" AND reporter="test" AND assignee="test" AND component="test" ` +
 				`AND createdDate>="2020-12-31" AND createdDate<"2021-01-01" AND updatedDate>="2020-12-31" AND updatedDate<"2021-01-01" ` +
 				`ORDER BY lastViewed ASC`,
 		},
@@ -296,7 +296,7 @@ func TestIssueGet(t *testing.T) {
 			},
 			expected: `project="TEST" AND issue IN issueHistory() AND issue IN watchedIssues() AND ` +
 				`type="test" AND resolution="test" AND status="test" AND priority="test" AND reporter="test" AND assignee="test" ` +
-				`AND createdDate>="2020-15-31" AND updatedDate>="2020-12-31 10:30:30" ORDER BY lastViewed ASC`,
+				`AND component="test" AND createdDate>="2020-15-31" AND updatedDate>="2020-12-31 10:30:30" ORDER BY lastViewed ASC`,
 		},
 		{
 			name: "query with created-after and created-before filter",
@@ -307,7 +307,7 @@ func TestIssueGet(t *testing.T) {
 			},
 			expected: `project="TEST" AND issue IN issueHistory() AND issue IN watchedIssues() AND ` +
 				`type="test" AND resolution="test" AND status="test" AND priority="test" AND reporter="test" AND assignee="test" ` +
-				`AND createdDate>"2020-12-01" AND createdDate<"2020-12-31" ORDER BY lastViewed ASC`,
+				`AND component="test" AND createdDate>"2020-12-01" AND createdDate<"2020-12-31" ORDER BY lastViewed ASC`,
 		},
 		{
 			name: "query with updated-after and updated-before filter",
@@ -318,7 +318,7 @@ func TestIssueGet(t *testing.T) {
 			},
 			expected: `project="TEST" AND issue IN issueHistory() AND issue IN watchedIssues() AND ` +
 				`type="test" AND resolution="test" AND status="test" AND priority="test" AND reporter="test" AND assignee="test" ` +
-				`AND updatedDate>"2020-12-01" AND updatedDate<"2020-12-31" ORDER BY lastViewed ASC`,
+				`AND component="test" AND updatedDate>"2020-12-01" AND updatedDate<"2020-12-31" ORDER BY lastViewed ASC`,
 		},
 		{
 			name: "created and updated flags gets precedence",
@@ -336,7 +336,7 @@ func TestIssueGet(t *testing.T) {
 			},
 			expected: `project="TEST" AND issue IN issueHistory() AND issue IN watchedIssues() AND ` +
 				`type="test" AND resolution="test" AND status="test" AND priority="test" AND reporter="test" AND assignee="test" ` +
-				`AND createdDate>="2020-11-01" AND createdDate<"2020-11-02" AND updatedDate>="-10d" ` +
+				`AND component="test" AND createdDate>="2020-11-01" AND createdDate<"2020-11-02" AND updatedDate>="-10d" ` +
 				`ORDER BY lastViewed ASC`,
 		},
 	}
diff --git a/pkg/adf/adf_test.go b/pkg/adf/adf_test.go
index 4e1e34c..2ec1de4 100644
--- a/pkg/adf/adf_test.go
+++ b/pkg/adf/adf_test.go
@@ -18,6 +18,6 @@ func TestADF(t *testing.T) {
 
 	tr := NewTranslator(&adf, &MarkdownTranslator{})
 
-	expected := "# H1\n## H2\n1. Some text\n\n2. Some more text\n\n\n\n> Blockquote text\n\n\nInline Node 📍 https://antiklabs.atlassian.net/wiki/spaces/ANK/pages/124234/hello-world \n\nImplement epic browser\n\n---\nPanel paragraph\n\n---\n @Person A \n\n---\n **Strong** Paragraph 1\n\nParagraph 2\n\n---\n **Bold Text** \n\n _Italic Text_ \n\n +Underlined Text+ \n\n `Inline Code Block` \n\n ~Strikethrough text~ \n\n [Link](https://ankit.pl) \n\n- Unordered list item 1\n\n\t- Next\n\n\t\t- Another\n\n\t\t\t- New level\n\n- Unordered list item 2\n\n- Unordered list item 3\n\n1. Ordered list item 1\n\n2. Ordered list item 2\n\n3. Ordered list item 3\n\n\t4. nested\n\n\t\t5. second level\n\n\t\t\t6. third level\n\n\t\t\t\t7. fourth level\n\n\n **Table Header 1**  |  **Table Header 2**  |  **Table Header 3** \n--- | --- | ---\nTable row 1 column 1 | Table row 1 column 2 | Table row 1 column 3\nTable row 2 column 1 | Table row 2 column 2 | Table row 2 column 3\n```go\npackage main\n\nimport (\n\t\"fmt\"\n)\n\nfunc main() {\n\tfmt.Println(\"Hello, World!\")\n}\n```\n\n **Table Header 1**  |  **Table Header 2**  |  **Table Header 3**  |  **Table Header 4**  |  **Table Header 5** \n--- | --- | --- | --- | ---\nTable row 1 column 1 | Table row 2 column 1 | Table row 3 column 1 | Table row 4 column 1 | Table row 5 column 1\nTable row 1 column 2 | Table row 2 column 2 | Table row 3 column 2 | Table row 4 column 2 | Table row 5 column 2\nTable row 1 column 2 | Table row 2 column 3 | Table row 3 column 3 | Table row 4 column 3 | Table row 5 column 3\n"
+	expected := "# H1\n## H2\n1. Some text\n\n2. Some more text\n\n\n\n> Blockquote text\n\n\nInline Node 📍 https://antiklabs.atlassian.net/wiki/spaces/ANK/pages/124234/hello-world \n\nImplement epic browser\n\n---\nPanel paragraph\n\n---\n @Person A \n\n---\n **Strong** Paragraph 1\n\nParagraph 2\n\n---\n **Bold Text** \n\n _Italic Text_ \n\nUnderlined Text\n\n `Inline Code Block` \n\n ~Strikethrough text~ \n\n [Link](https://ankit.pl) \n\n- Unordered list item 1\n\n\t- Next\n\n\t\t- Another\n\n\t\t\t- New level\n\n- Unordered list item 2\n\n- Unordered list item 3\n\n1. Ordered list item 1\n\n2. Ordered list item 2\n\n3. Ordered list item 3\n\n\t4. nested\n\n\t\t5. second level\n\n\t\t\t6. third level\n\n\t\t\t\t7. fourth level\n\n\n **Table Header 1**  |  **Table Header 2**  |  **Table Header 3** \n--- | --- | ---\nTable row 1 column 1 | Table row 1 column 2 | Table row 1 column 3\nTable row 2 column 1 | Table row 2 column 2 | Table row 2 column 3\n```go\npackage main\n\nimport (\n\t\"fmt\"\n)\n\nfunc main() {\n\tfmt.Println(\"Hello, World!\")\n}\n```\n\n **Table Header 1**  |  **Table Header 2**  |  **Table Header 3**  |  **Table Header 4**  |  **Table Header 5** \n--- | --- | --- | --- | ---\nTable row 1 column 1 | Table row 2 column 1 | Table row 3 column 1 | Table row 4 column 1 | Table row 5 column 1\nTable row 1 column 2 | Table row 2 column 2 | Table row 3 column 2 | Table row 4 column 2 | Table row 5 column 2\nTable row 1 column 2 | Table row 2 column 3 | Table row 3 column 3 | Table row 4 column 3 | Table row 5 column 3\n"
 	assert.Equal(t, expected, tr.Translate())
 }