feat: switch cli indexing to code-first identifiers
This commit is contained in:
@@ -13,7 +13,6 @@ import (
|
|||||||
type essentialResponse struct {
|
type essentialResponse struct {
|
||||||
ID int `json:"id"`
|
ID int `json:"id"`
|
||||||
EssentialCode string `json:"essential_code"`
|
EssentialCode string `json:"essential_code"`
|
||||||
ProposalID int `json:"proposal_id"`
|
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
Description *string `json:"description"`
|
Description *string `json:"description"`
|
||||||
@@ -49,8 +48,7 @@ func RunEssentialList(args []string, tokenFlag string) {
|
|||||||
output.Errorf("config error: %v", err)
|
output.Errorf("config error: %v", err)
|
||||||
}
|
}
|
||||||
c := client.New(cfg.BaseURL, token)
|
c := client.New(cfg.BaseURL, token)
|
||||||
project := resolveProposalProject(c, proposalCode)
|
data, err := c.Get(proposalPath(c, proposalCode) + "/essentials")
|
||||||
data, err := c.Get("/projects/" + project + "/proposals/" + proposalCode + "/essentials")
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
output.Errorf("failed to list essentials: %v", err)
|
output.Errorf("failed to list essentials: %v", err)
|
||||||
}
|
}
|
||||||
@@ -147,8 +145,7 @@ func RunEssentialCreate(args []string, tokenFlag string) {
|
|||||||
output.Errorf("config error: %v", err)
|
output.Errorf("config error: %v", err)
|
||||||
}
|
}
|
||||||
c := client.New(cfg.BaseURL, token)
|
c := client.New(cfg.BaseURL, token)
|
||||||
project := resolveProposalProject(c, proposalCode)
|
data, err := c.Post(proposalPath(c, proposalCode)+"/essentials", bytes.NewReader(body))
|
||||||
data, err := c.Post("/projects/"+project+"/proposals/"+proposalCode+"/essentials", bytes.NewReader(body))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
output.Errorf("failed to create essential: %v", err)
|
output.Errorf("failed to create essential: %v", err)
|
||||||
}
|
}
|
||||||
@@ -231,8 +228,7 @@ func RunEssentialUpdate(essentialCode string, args []string, tokenFlag string) {
|
|||||||
output.Errorf("config error: %v", err)
|
output.Errorf("config error: %v", err)
|
||||||
}
|
}
|
||||||
c := client.New(cfg.BaseURL, token)
|
c := client.New(cfg.BaseURL, token)
|
||||||
project := resolveProposalProject(c, proposalCode)
|
_, err = c.Patch(proposalPath(c, proposalCode)+"/essentials/"+essentialCode, bytes.NewReader(body))
|
||||||
_, err = c.Patch("/projects/"+project+"/proposals/"+proposalCode+"/essentials/"+essentialCode, bytes.NewReader(body))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
output.Errorf("failed to update essential: %v", err)
|
output.Errorf("failed to update essential: %v", err)
|
||||||
}
|
}
|
||||||
@@ -269,8 +265,7 @@ func RunEssentialDeleteFull(essentialCode string, args []string, tokenFlag strin
|
|||||||
output.Errorf("config error: %v", err)
|
output.Errorf("config error: %v", err)
|
||||||
}
|
}
|
||||||
c := client.New(cfg.BaseURL, token)
|
c := client.New(cfg.BaseURL, token)
|
||||||
project := resolveProposalProject(c, proposalCode)
|
_, err = c.Delete(proposalPath(c, proposalCode) + "/essentials/" + essentialCode)
|
||||||
_, err = c.Delete("/projects/" + project + "/proposals/" + proposalCode + "/essentials/" + essentialCode)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
output.Errorf("failed to delete essential: %v", err)
|
output.Errorf("failed to delete essential: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ func RunMeetingList(args []string, tokenFlag string) {
|
|||||||
output.Error("--project requires a value")
|
output.Error("--project requires a value")
|
||||||
}
|
}
|
||||||
i++
|
i++
|
||||||
query = appendQuery(query, "project", args[i])
|
query = appendQuery(query, "project_code", args[i])
|
||||||
case "--status":
|
case "--status":
|
||||||
if i+1 >= len(args) {
|
if i+1 >= len(args) {
|
||||||
output.Error("--status requires a value")
|
output.Error("--status requires a value")
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ func RunMilestoneList(args []string, tokenFlag string) {
|
|||||||
output.Error("--project requires a value")
|
output.Error("--project requires a value")
|
||||||
}
|
}
|
||||||
i++
|
i++
|
||||||
query = appendQuery(query, "project", args[i])
|
query = appendQuery(query, "project_code", args[i])
|
||||||
case "--status":
|
case "--status":
|
||||||
if i+1 >= len(args) {
|
if i+1 >= len(args) {
|
||||||
output.Error("--status requires a value")
|
output.Error("--status requires a value")
|
||||||
|
|||||||
@@ -170,20 +170,29 @@ func TestEssentialDelete_MissingProposal(t *testing.T) {
|
|||||||
|
|
||||||
func TestEssentialList_JSONOutput(t *testing.T) {
|
func TestEssentialList_JSONOutput(t *testing.T) {
|
||||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
if r.Method != "GET" || r.URL.Path != "/proposes/PRJ-001/essentials" {
|
switch {
|
||||||
|
case r.Method == "GET" && r.URL.Path == "/projects":
|
||||||
|
w.WriteHeader(200)
|
||||||
|
json.NewEncoder(w).Encode([]interface{}{map[string]interface{}{"id": 1, "project_code": "PROJ-001"}})
|
||||||
|
case r.Method == "GET" && r.URL.Path == "/projects/PROJ-001/proposals/PRJ-001":
|
||||||
|
w.WriteHeader(200)
|
||||||
|
json.NewEncoder(w).Encode(map[string]interface{}{"code": "PRJ-001", "project_code": "PROJ-001"})
|
||||||
|
case r.Method == "GET" && r.URL.Path == "/projects/PROJ-001/proposals/PRJ-001/essentials":
|
||||||
|
w.WriteHeader(200)
|
||||||
|
json.NewEncoder(w).Encode([]interface{}{
|
||||||
|
map[string]interface{}{
|
||||||
|
"id": 1,
|
||||||
|
"essential_code": "ESS-001",
|
||||||
|
"proposal_id": 1,
|
||||||
|
"type": "feature",
|
||||||
|
"title": "Add login",
|
||||||
|
"created_at": "2026-03-01",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
default:
|
||||||
t.Errorf("unexpected request: %s %s", r.Method, r.URL.Path)
|
t.Errorf("unexpected request: %s %s", r.Method, r.URL.Path)
|
||||||
|
w.WriteHeader(404)
|
||||||
}
|
}
|
||||||
w.WriteHeader(200)
|
|
||||||
json.NewEncoder(w).Encode([]interface{}{
|
|
||||||
map[string]interface{}{
|
|
||||||
"id": 1,
|
|
||||||
"essential_code": "ESS-001",
|
|
||||||
"proposal_id": 1,
|
|
||||||
"type": "feature",
|
|
||||||
"title": "Add login",
|
|
||||||
"created_at": "2026-03-01",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}))
|
}))
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
@@ -204,16 +213,25 @@ func TestEssentialList_JSONOutput(t *testing.T) {
|
|||||||
|
|
||||||
func TestEssentialCreate_Success(t *testing.T) {
|
func TestEssentialCreate_Success(t *testing.T) {
|
||||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
if r.Method != "POST" {
|
switch {
|
||||||
t.Errorf("expected POST; got: %s", r.Method)
|
case r.Method == "GET" && r.URL.Path == "/projects":
|
||||||
|
w.WriteHeader(200)
|
||||||
|
json.NewEncoder(w).Encode([]interface{}{map[string]interface{}{"id": 1, "project_code": "PROJ-001"}})
|
||||||
|
case r.Method == "GET" && r.URL.Path == "/projects/PROJ-001/proposals/PRJ-001":
|
||||||
|
w.WriteHeader(200)
|
||||||
|
json.NewEncoder(w).Encode(map[string]interface{}{"code": "PRJ-001", "project_code": "PROJ-001"})
|
||||||
|
case r.Method == "POST" && r.URL.Path == "/projects/PROJ-001/proposals/PRJ-001/essentials":
|
||||||
|
w.WriteHeader(200)
|
||||||
|
json.NewEncoder(w).Encode(map[string]interface{}{
|
||||||
|
"id": 1,
|
||||||
|
"essential_code": "ESS-001",
|
||||||
|
"title": "Add login",
|
||||||
|
"type": "feature",
|
||||||
|
})
|
||||||
|
default:
|
||||||
|
t.Errorf("unexpected request: %s %s", r.Method, r.URL.Path)
|
||||||
|
w.WriteHeader(404)
|
||||||
}
|
}
|
||||||
w.WriteHeader(200)
|
|
||||||
json.NewEncoder(w).Encode(map[string]interface{}{
|
|
||||||
"id": 1,
|
|
||||||
"essential_code": "ESS-001",
|
|
||||||
"title": "Add login",
|
|
||||||
"type": "feature",
|
|
||||||
})
|
|
||||||
}))
|
}))
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
@@ -234,11 +252,20 @@ func TestEssentialCreate_Success(t *testing.T) {
|
|||||||
|
|
||||||
func TestEssentialUpdate_Success(t *testing.T) {
|
func TestEssentialUpdate_Success(t *testing.T) {
|
||||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
if r.Method != "PATCH" {
|
switch {
|
||||||
t.Errorf("expected PATCH; got: %s", r.Method)
|
case r.Method == "GET" && r.URL.Path == "/projects":
|
||||||
|
w.WriteHeader(200)
|
||||||
|
json.NewEncoder(w).Encode([]interface{}{map[string]interface{}{"id": 1, "project_code": "PROJ-001"}})
|
||||||
|
case r.Method == "GET" && r.URL.Path == "/projects/PROJ-001/proposals/PRJ-001":
|
||||||
|
w.WriteHeader(200)
|
||||||
|
json.NewEncoder(w).Encode(map[string]interface{}{"code": "PRJ-001", "project_code": "PROJ-001"})
|
||||||
|
case r.Method == "PATCH" && r.URL.Path == "/projects/PROJ-001/proposals/PRJ-001/essentials/ESS-001":
|
||||||
|
w.WriteHeader(200)
|
||||||
|
w.Write([]byte(`{}`))
|
||||||
|
default:
|
||||||
|
t.Errorf("unexpected request: %s %s", r.Method, r.URL.Path)
|
||||||
|
w.WriteHeader(404)
|
||||||
}
|
}
|
||||||
w.WriteHeader(200)
|
|
||||||
w.Write([]byte(`{}`))
|
|
||||||
}))
|
}))
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
@@ -259,11 +286,20 @@ func TestEssentialUpdate_Success(t *testing.T) {
|
|||||||
|
|
||||||
func TestEssentialDelete_Success(t *testing.T) {
|
func TestEssentialDelete_Success(t *testing.T) {
|
||||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
if r.Method != "DELETE" {
|
switch {
|
||||||
t.Errorf("expected DELETE; got: %s", r.Method)
|
case r.Method == "GET" && r.URL.Path == "/projects":
|
||||||
|
w.WriteHeader(200)
|
||||||
|
json.NewEncoder(w).Encode([]interface{}{map[string]interface{}{"id": 1, "project_code": "PROJ-001"}})
|
||||||
|
case r.Method == "GET" && r.URL.Path == "/projects/PROJ-001/proposals/PRJ-001":
|
||||||
|
w.WriteHeader(200)
|
||||||
|
json.NewEncoder(w).Encode(map[string]interface{}{"code": "PRJ-001", "project_code": "PROJ-001"})
|
||||||
|
case r.Method == "DELETE" && r.URL.Path == "/projects/PROJ-001/proposals/PRJ-001/essentials/ESS-001":
|
||||||
|
w.WriteHeader(200)
|
||||||
|
w.Write([]byte(`{}`))
|
||||||
|
default:
|
||||||
|
t.Errorf("unexpected request: %s %s", r.Method, r.URL.Path)
|
||||||
|
w.WriteHeader(404)
|
||||||
}
|
}
|
||||||
w.WriteHeader(200)
|
|
||||||
w.Write([]byte(`{}`))
|
|
||||||
}))
|
}))
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
@@ -306,20 +342,29 @@ func TestProposalAccept_MissingMilestone(t *testing.T) {
|
|||||||
|
|
||||||
func TestProposalAccept_Success(t *testing.T) {
|
func TestProposalAccept_Success(t *testing.T) {
|
||||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
if r.Method != "POST" || r.URL.Path != "/proposes/PRJ-001/accept" {
|
switch {
|
||||||
|
case r.Method == "GET" && r.URL.Path == "/projects":
|
||||||
|
w.WriteHeader(200)
|
||||||
|
json.NewEncoder(w).Encode([]interface{}{map[string]interface{}{"id": 1, "project_code": "PROJ-001"}})
|
||||||
|
case r.Method == "GET" && r.URL.Path == "/projects/PROJ-001/proposals/PRJ-001":
|
||||||
|
w.WriteHeader(200)
|
||||||
|
json.NewEncoder(w).Encode(map[string]interface{}{"code": "PRJ-001", "project_code": "PROJ-001"})
|
||||||
|
case r.Method == "POST" && r.URL.Path == "/projects/PROJ-001/proposals/PRJ-001/accept":
|
||||||
|
var body map[string]interface{}
|
||||||
|
json.NewDecoder(r.Body).Decode(&body)
|
||||||
|
if body["milestone_code"] != "MS-001" {
|
||||||
|
t.Errorf("expected milestone_code=MS-001; got: %v", body["milestone_code"])
|
||||||
|
}
|
||||||
|
w.WriteHeader(200)
|
||||||
|
json.NewEncoder(w).Encode(map[string]interface{}{
|
||||||
|
"code": "PRJ-001",
|
||||||
|
"status": "Accepted",
|
||||||
|
"tasks": []interface{}{},
|
||||||
|
})
|
||||||
|
default:
|
||||||
t.Errorf("unexpected request: %s %s", r.Method, r.URL.Path)
|
t.Errorf("unexpected request: %s %s", r.Method, r.URL.Path)
|
||||||
|
w.WriteHeader(404)
|
||||||
}
|
}
|
||||||
var body map[string]interface{}
|
|
||||||
json.NewDecoder(r.Body).Decode(&body)
|
|
||||||
if body["milestone_code"] != "MS-001" {
|
|
||||||
t.Errorf("expected milestone_code=MS-001; got: %v", body["milestone_code"])
|
|
||||||
}
|
|
||||||
w.WriteHeader(200)
|
|
||||||
json.NewEncoder(w).Encode(map[string]interface{}{
|
|
||||||
"code": "PRJ-001",
|
|
||||||
"status": "Accepted",
|
|
||||||
"tasks": []interface{}{},
|
|
||||||
})
|
|
||||||
}))
|
}))
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
@@ -421,7 +466,7 @@ func TestTaskCreate_StoryTypeOnlyRestricted(t *testing.T) {
|
|||||||
|
|
||||||
func TestProposalList_Success(t *testing.T) {
|
func TestProposalList_Success(t *testing.T) {
|
||||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
if r.Method != "GET" || r.URL.Path != "/proposes" {
|
if r.Method != "GET" || r.URL.Path != "/projects/PROJ-001/proposals" {
|
||||||
t.Errorf("unexpected request: %s %s", r.Method, r.URL.Path)
|
t.Errorf("unexpected request: %s %s", r.Method, r.URL.Path)
|
||||||
}
|
}
|
||||||
w.WriteHeader(200)
|
w.WriteHeader(200)
|
||||||
@@ -444,7 +489,7 @@ func TestProposalList_Success(t *testing.T) {
|
|||||||
cliPath := filepath.Join(tmpDir, "hf")
|
cliPath := filepath.Join(tmpDir, "hf")
|
||||||
buildCLI(t, cliPath)
|
buildCLI(t, cliPath)
|
||||||
|
|
||||||
out, err := runCLIProposal(t, tmpDir, cliPath, "proposal", "list", "--token", "fake")
|
out, err := runCLIProposal(t, tmpDir, cliPath, "proposal", "list", "--token", "fake", "--project", "PROJ-001")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error: %v; out=%s", err, out)
|
t.Fatalf("unexpected error: %v; out=%s", err, out)
|
||||||
}
|
}
|
||||||
@@ -455,6 +500,9 @@ func TestProposalList_Success(t *testing.T) {
|
|||||||
|
|
||||||
func TestProposalList_JSONOutput(t *testing.T) {
|
func TestProposalList_JSONOutput(t *testing.T) {
|
||||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if r.Method != "GET" || r.URL.Path != "/projects/PROJ-001/proposals" {
|
||||||
|
t.Errorf("unexpected request: %s %s", r.Method, r.URL.Path)
|
||||||
|
}
|
||||||
w.WriteHeader(200)
|
w.WriteHeader(200)
|
||||||
json.NewEncoder(w).Encode([]interface{}{
|
json.NewEncoder(w).Encode([]interface{}{
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
@@ -472,7 +520,7 @@ func TestProposalList_JSONOutput(t *testing.T) {
|
|||||||
cliPath := filepath.Join(tmpDir, "hf")
|
cliPath := filepath.Join(tmpDir, "hf")
|
||||||
buildCLI(t, cliPath)
|
buildCLI(t, cliPath)
|
||||||
|
|
||||||
out, err := runCLIProposal(t, tmpDir, cliPath, "--json", "proposal", "list", "--token", "fake")
|
out, err := runCLIProposal(t, tmpDir, cliPath, "--json", "proposal", "list", "--token", "fake", "--project", "PROJ-001")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error: %v; out=%s", err, out)
|
t.Fatalf("unexpected error: %v; out=%s", err, out)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,21 +32,30 @@ type projectLookup struct {
|
|||||||
func resolveProposalProject(c *client.Client, proposalCode string) string {
|
func resolveProposalProject(c *client.Client, proposalCode string) string {
|
||||||
data, err := c.Get("/projects")
|
data, err := c.Get("/projects")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
output.Errorf("failed to list projects for proposal lookup: %v", err)
|
return ""
|
||||||
}
|
}
|
||||||
var projects []projectLookup
|
var projects []projectLookup
|
||||||
if err := json.Unmarshal(data, &projects); err != nil {
|
if err := json.Unmarshal(data, &projects); err != nil {
|
||||||
output.Errorf("cannot parse project list for proposal lookup: %v", err)
|
return ""
|
||||||
}
|
}
|
||||||
for _, p := range projects {
|
for _, p := range projects {
|
||||||
|
if p.ProjectCode == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
if _, err := c.Get("/projects/" + p.ProjectCode + "/proposals/" + proposalCode); err == nil {
|
if _, err := c.Get("/projects/" + p.ProjectCode + "/proposals/" + proposalCode); err == nil {
|
||||||
return p.ProjectCode
|
return p.ProjectCode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
output.Errorf("proposal not found: %s", proposalCode)
|
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func proposalPath(c *client.Client, proposalCode string) string {
|
||||||
|
if project := resolveProposalProject(c, proposalCode); project != "" {
|
||||||
|
return "/projects/" + project + "/proposals/" + proposalCode
|
||||||
|
}
|
||||||
|
return "/proposes/" + proposalCode
|
||||||
|
}
|
||||||
|
|
||||||
// RunProposeList implements `hf propose list --project <project-code>`.
|
// RunProposeList implements `hf propose list --project <project-code>`.
|
||||||
func RunProposeList(args []string, tokenFlag string) {
|
func RunProposeList(args []string, tokenFlag string) {
|
||||||
token := ResolveToken(tokenFlag)
|
token := ResolveToken(tokenFlag)
|
||||||
@@ -77,8 +86,9 @@ func RunProposeList(args []string, tokenFlag string) {
|
|||||||
output.Errorf("unknown flag: %s", args[i])
|
output.Errorf("unknown flag: %s", args[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
legacyPath := false
|
||||||
if project == "" {
|
if project == "" {
|
||||||
output.Error("usage: hf propose list --project <project-code> [--status <status>] [--order-by <field>]")
|
legacyPath = true
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg, err := config.Load()
|
cfg, err := config.Load()
|
||||||
@@ -87,6 +97,9 @@ func RunProposeList(args []string, tokenFlag string) {
|
|||||||
}
|
}
|
||||||
c := client.New(cfg.BaseURL, token)
|
c := client.New(cfg.BaseURL, token)
|
||||||
path := "/projects/" + project + "/proposals"
|
path := "/projects/" + project + "/proposals"
|
||||||
|
if legacyPath {
|
||||||
|
path = "/proposes"
|
||||||
|
}
|
||||||
if encoded := query.Encode(); encoded != "" {
|
if encoded := query.Encode(); encoded != "" {
|
||||||
path += "?" + encoded
|
path += "?" + encoded
|
||||||
}
|
}
|
||||||
@@ -133,8 +146,7 @@ func RunProposeGet(proposeCode, tokenFlag string) {
|
|||||||
output.Errorf("config error: %v", err)
|
output.Errorf("config error: %v", err)
|
||||||
}
|
}
|
||||||
c := client.New(cfg.BaseURL, token)
|
c := client.New(cfg.BaseURL, token)
|
||||||
project := resolveProposalProject(c, proposeCode)
|
data, err := c.Get(proposalPath(c, proposeCode))
|
||||||
data, err := c.Get("/projects/" + project + "/proposals/" + proposeCode)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
output.Errorf("failed to get proposal: %v", err)
|
output.Errorf("failed to get proposal: %v", err)
|
||||||
}
|
}
|
||||||
@@ -281,8 +293,7 @@ func RunProposeUpdate(proposeCode string, args []string, tokenFlag string) {
|
|||||||
output.Errorf("config error: %v", err)
|
output.Errorf("config error: %v", err)
|
||||||
}
|
}
|
||||||
c := client.New(cfg.BaseURL, token)
|
c := client.New(cfg.BaseURL, token)
|
||||||
project := resolveProposalProject(c, proposeCode)
|
_, err = c.Patch(proposalPath(c, proposeCode), bytes.NewReader(body))
|
||||||
_, err = c.Patch("/projects/"+project+"/proposals/"+proposeCode, bytes.NewReader(body))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
output.Errorf("failed to update proposal: %v", err)
|
output.Errorf("failed to update proposal: %v", err)
|
||||||
}
|
}
|
||||||
@@ -340,8 +351,7 @@ func RunProposeAccept(proposeCode string, args []string, tokenFlag string) {
|
|||||||
output.Errorf("config error: %v", err)
|
output.Errorf("config error: %v", err)
|
||||||
}
|
}
|
||||||
c := client.New(cfg.BaseURL, token)
|
c := client.New(cfg.BaseURL, token)
|
||||||
project := resolveProposalProject(c, proposeCode)
|
data, err := c.Post(proposalPath(c, proposeCode)+"/accept", bytes.NewReader(body))
|
||||||
data, err := c.Post("/projects/"+project+"/proposals/"+proposeCode+"/accept", bytes.NewReader(body))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
output.Errorf("failed to accept proposal: %v", err)
|
output.Errorf("failed to accept proposal: %v", err)
|
||||||
}
|
}
|
||||||
@@ -362,7 +372,7 @@ func RunProposeAccept(proposeCode string, args []string, tokenFlag string) {
|
|||||||
if err := json.Unmarshal(data, &resp); err == nil && len(resp.GeneratedTasks) > 0 {
|
if err := json.Unmarshal(data, &resp); err == nil && len(resp.GeneratedTasks) > 0 {
|
||||||
fmt.Printf("\nGenerated %d story task(s):\n", len(resp.GeneratedTasks))
|
fmt.Printf("\nGenerated %d story task(s):\n", len(resp.GeneratedTasks))
|
||||||
for _, gt := range resp.GeneratedTasks {
|
for _, gt := range resp.GeneratedTasks {
|
||||||
code := ""
|
code := "(no task_code)"
|
||||||
if gt.TaskCode != nil {
|
if gt.TaskCode != nil {
|
||||||
code = *gt.TaskCode
|
code = *gt.TaskCode
|
||||||
}
|
}
|
||||||
@@ -410,8 +420,7 @@ func RunProposeReject(proposeCode string, args []string, tokenFlag string) {
|
|||||||
output.Errorf("config error: %v", err)
|
output.Errorf("config error: %v", err)
|
||||||
}
|
}
|
||||||
c := client.New(cfg.BaseURL, token)
|
c := client.New(cfg.BaseURL, token)
|
||||||
project := resolveProposalProject(c, proposeCode)
|
_, err = c.Post(proposalPath(c, proposeCode)+"/reject", body)
|
||||||
_, err = c.Post("/projects/"+project+"/proposals/"+proposeCode+"/reject", body)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
output.Errorf("failed to reject proposal: %v", err)
|
output.Errorf("failed to reject proposal: %v", err)
|
||||||
}
|
}
|
||||||
@@ -428,8 +437,7 @@ func RunProposeReopen(proposeCode, tokenFlag string) {
|
|||||||
output.Errorf("config error: %v", err)
|
output.Errorf("config error: %v", err)
|
||||||
}
|
}
|
||||||
c := client.New(cfg.BaseURL, token)
|
c := client.New(cfg.BaseURL, token)
|
||||||
project := resolveProposalProject(c, proposeCode)
|
_, err = c.Post(proposalPath(c, proposeCode)+"/reopen", nil)
|
||||||
_, err = c.Post("/projects/"+project+"/proposals/"+proposeCode+"/reopen", nil)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
output.Errorf("failed to reopen proposal: %v", err)
|
output.Errorf("failed to reopen proposal: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,13 +38,13 @@ func RunTaskList(args []string, tokenFlag string) {
|
|||||||
output.Error("--project requires a value")
|
output.Error("--project requires a value")
|
||||||
}
|
}
|
||||||
i++
|
i++
|
||||||
query = appendQuery(query, "project", args[i])
|
query = appendQuery(query, "project_code", args[i])
|
||||||
case "--milestone":
|
case "--milestone":
|
||||||
if i+1 >= len(args) {
|
if i+1 >= len(args) {
|
||||||
output.Error("--milestone requires a value")
|
output.Error("--milestone requires a value")
|
||||||
}
|
}
|
||||||
i++
|
i++
|
||||||
query = appendQuery(query, "milestone", args[i])
|
query = appendQuery(query, "milestone_code", args[i])
|
||||||
case "--status":
|
case "--status":
|
||||||
if i+1 >= len(args) {
|
if i+1 >= len(args) {
|
||||||
output.Error("--status requires a value")
|
output.Error("--status requires a value")
|
||||||
@@ -426,7 +426,7 @@ func RunTaskSearch(args []string, tokenFlag string) {
|
|||||||
output.Error("--project requires a value")
|
output.Error("--project requires a value")
|
||||||
}
|
}
|
||||||
i++
|
i++
|
||||||
query = appendQuery(query, "project", args[i])
|
query = appendQuery(query, "project_code", args[i])
|
||||||
case "--status":
|
case "--status":
|
||||||
if i+1 >= len(args) {
|
if i+1 >= len(args) {
|
||||||
output.Error("--status requires a value")
|
output.Error("--status requires a value")
|
||||||
|
|||||||
Reference in New Issue
Block a user