Skip to content

Instantly share code, notes, and snippets.

@aslakknutsen
Created January 10, 2017 10:46
Show Gist options
  • Select an option

  • Save aslakknutsen/92adef2a61e6a931d1757eef37d1dbb6 to your computer and use it in GitHub Desktop.

Select an option

Save aslakknutsen/92adef2a61e6a931d1757eef37d1dbb6 to your computer and use it in GitHub Desktop.
PDD import
package main
import (
"fmt"
"io/ioutil"
"net/http"
"testing"
"encoding/json"
"io"
"strings"
"github.com/almighty/almighty-core/client"
"github.com/almighty/almighty-core/workitem"
goaclient "github.com/goadesign/goa/client"
"golang.org/x/net/context"
)
var TypeMap = map[string]string{
"Experience": workitem.SystemExperience,
"Value Proposition": workitem.SystemValueProposition,
"Fundamental": workitem.SystemFundamental,
"Scenario": workitem.SystemScenario,
}
var key = "xxxx"
type Entry struct {
ID string
Type string
Title *string
Priority *string
Description string
Supporting []string
WorkItemID string
}
func TestParseData(t *testing.T) {
entries := []Entry{}
data, err := ioutil.ReadFile("../JSONParsing-PDD/pdd.json")
if err != nil {
t.Fatal("Could not read pdd.json", err.Error())
}
json.Unmarshal(data, &entries)
fmt.Println("Original Number of entries", len(entries))
entryMap := cleanEntries(entries)
fmt.Println("Mapped Number of entries", len(entryMap))
c := createClient(key)
c.Host = "localhost:8080"
ctx := context.Background()
for _, val := range entryMap {
fmt.Println("Attempting to create", val)
title := ""
if val.Title != nil {
title = strings.Replace(strings.Replace(*val.Title, "\u201c", "", -1), "\u201d", "", -1)
} else {
if len(val.Description) > 100 {
title = val.Description[:100]
title = title[:strings.LastIndex(title, " ")] + "..."
} else {
title = val.Description
}
}
title = title + " ( " + val.ID
if val.Priority != nil {
title = title + " " + *val.Priority
}
title = title + " )"
resp, err := c.CreateWorkitem(ctx, client.CreateWorkitemPath(), &client.CreateWorkitemPayload{
Data: &client.WorkItem2{
Type: "workitems",
Attributes: map[string]interface{}{
workitem.SystemState: workitem.SystemStateNew,
workitem.SystemDescription: val.Description,
workitem.SystemTitle: title,
},
Relationships: &client.WorkItemRelationships{
BaseType: &client.RelationBaseType{
Data: &client.BaseTypeData{
ID: TypeMap[val.Type],
Type: "workitemtypes",
},
},
},
},
})
if err != nil {
fmt.Println("Failed to create entry", val, err)
} else if resp.StatusCode != http.StatusCreated {
fmt.Println("Not created", toString(resp.Body))
} else {
s := &client.WorkItem2Single{}
err = json.NewDecoder(resp.Body).Decode(s)
if err != nil {
fmt.Println("Failed to decode response")
} else {
fmt.Println("Created workitem", s)
val.WorkItemID = *s.Data.ID
}
}
}
for _, source := range entryMap {
for i := 0; i < len(source.Supporting); i++ {
target := entryMap[source.Supporting[i]]
if target == nil {
continue
}
resp, err := c.CreateWorkItemLink(ctx, client.CreateWorkItemLinkPath(), &client.CreateWorkItemLinkPayload{
Data: &client.WorkItemLinkData{
Type: "workitemlinks",
Relationships: &client.WorkItemLinkRelationships{
LinkType: &client.RelationWorkItemLinkType{
Data: &client.RelationWorkItemLinkTypeData{
Type: "workitemlinktypes",
ID: "a4df0ec9-21df-433d-ac92-f6ef64b41c8b",
},
},
Source: &client.RelationWorkItem{
Data: &client.RelationWorkItemData{
Type: "workitems",
ID: source.WorkItemID,
},
},
Target: &client.RelationWorkItem{
Data: &client.RelationWorkItemData{
Type: "workitems",
ID: target.WorkItemID,
},
},
},
},
})
if err != nil {
fmt.Println("Failed to create link", source, target, err)
} else if resp.StatusCode != http.StatusCreated {
fmt.Println("Not created", toString(resp.Body))
} else {
s := &client.WorkItemLinkSingle{}
err = json.NewDecoder(resp.Body).Decode(s)
if err != nil {
fmt.Println("Failed to decode response")
} else {
fmt.Println("Created link", s)
}
}
}
}
}
func XTestLoadPDD(t *testing.T) {
ctx := context.Background()
c := createClient(key)
c.Host = "localhost:8080"
spaceName := "DevTools"
iterationBanksia := "Banksia"
space, err := setupSpace(ctx, c, spaceName)
if err != nil {
t.Fatal("Could not SetupSpace", err)
}
banksia, err := setupIteration(ctx, c, space.ID.String(), iterationBanksia)
if err != nil {
t.Fatal("Could not SetupIteration", err)
}
fmt.Println("Using space", *space.Attributes.Name, *space.Attributes.CreatedAt)
fmt.Println("Using iteration", *banksia.Attributes.Name)
}
func setupIteration(ctx context.Context, c *client.Client, spaceID, iterationName string) (*client.Iteration, error) {
iterations, err := listIteration(ctx, c, spaceID)
if err != nil {
return nil, fmt.Errorf("Could not ListIteration %v", err)
}
if len(iterations.Data) == 0 {
// create
s, err := createIteration(ctx, c, spaceID, iterationName)
if err != nil {
return nil, fmt.Errorf("Could not CreateIteration %v", err)
}
return s.Data, nil
}
// locate or create
for _, s := range iterations.Data {
if *s.Attributes.Name == iterationName {
return s, nil
}
}
s, err := createIteration(ctx, c, spaceID, iterationName)
if err != nil {
return nil, fmt.Errorf("Could not CreateIteration %v", err)
}
return s.Data, nil
}
func setupSpace(ctx context.Context, c *client.Client, spaceName string) (*client.Space, error) {
spaces, err := listSpace(ctx, c)
if err != nil {
return nil, fmt.Errorf("Could not ListSpace %v", err)
}
if len(spaces.Data) == 0 {
// create
s, err := createSpace(ctx, c, spaceName)
if err != nil {
return nil, fmt.Errorf("Could not CreateSpace %v", err)
}
return s.Data, nil
}
// locate or create
for _, s := range spaces.Data {
if *s.Attributes.Name == spaceName {
return s, nil
}
}
s, err := createSpace(ctx, c, spaceName)
if err != nil {
return nil, fmt.Errorf("Could not CreateSpace %v", err)
}
return s.Data, nil
}
func listSpace(ctx context.Context, c *client.Client) (*client.SpaceList, error) {
resp, err := c.ListSpace(ctx, client.ListSpacePath(), nil, nil)
if err != nil {
return nil, err
}
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("ListSpace returned != 200 status [%v]", resp)
}
s := &client.SpaceList{}
err = json.NewDecoder(resp.Body).Decode(s)
if err != nil {
return nil, err
}
return s, nil
}
func listIteration(ctx context.Context, c *client.Client, spaceID string) (*client.IterationList, error) {
resp, err := c.ListSpaceIterations(ctx, client.ListSpaceIterationsPath(spaceID))
if err != nil {
return nil, err
}
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("ListIteration returned != 200 status [%v]", resp)
}
s := &client.IterationList{}
err = json.NewDecoder(resp.Body).Decode(s)
if err != nil {
return nil, err
}
return s, nil
}
type RESTError struct {
Cause error
Errors string
}
func (r RESTError) Error() string {
return r.Cause.Error() + r.Errors
}
func toString(data io.Reader) string {
b, err := ioutil.ReadAll(data)
if err != nil {
return err.Error()
}
return string(b)
}
func createSpace(ctx context.Context, c *client.Client, name string) (*client.SpaceSingle, error) {
resp, err := c.CreateSpace(
ctx,
client.CreateSpacePath(),
&client.CreateSpacePayload{
Data: &client.Space{
Type: "spaces",
Attributes: &client.SpaceAttributes{
Name: &name,
},
},
})
if err != nil {
return nil, RESTError{Errors: toString(resp.Body), Cause: err}
}
if resp.StatusCode != http.StatusCreated {
return nil, RESTError{Errors: toString(resp.Body), Cause: fmt.Errorf("CreateSpace returned != 201 status")}
}
s := &client.SpaceSingle{}
err = json.NewDecoder(resp.Body).Decode(s)
if err != nil {
return nil, err
}
return s, nil
}
func createIteration(ctx context.Context, c *client.Client, spaceID, name string) (*client.IterationSingle, error) {
resp, err := c.CreateSpaceIterations(
ctx,
client.CreateSpaceIterationsPath(spaceID),
&client.CreateSpaceIterationsPayload{
Data: &client.Iteration{
Type: "iterations",
Attributes: &client.IterationAttributes{
Name: &name,
},
},
})
if err != nil {
return nil, RESTError{Errors: toString(resp.Body), Cause: err}
}
if resp.StatusCode != http.StatusCreated {
return nil, RESTError{Errors: toString(resp.Body), Cause: fmt.Errorf("CreateIteration returned != 201 status")}
}
s := &client.IterationSingle{}
err = json.NewDecoder(resp.Body).Decode(s)
if err != nil {
return nil, err
}
return s, nil
}
func createClient(key string) *client.Client {
c := client.New(goaclient.HTTPClientDoer(http.DefaultClient))
c.SetJWTSigner(&goaclient.APIKeySigner{
SignQuery: false,
KeyName: "Authorization",
KeyValue: key,
Format: "Bearer %s",
})
return c
}
func cleanEntries(entries []Entry) map[string]*Entry {
entryMap := map[string]*Entry{}
for i := 0; i < len(entries); i++ {
entry := entries[i]
if entry.ID == "None" { //|| entry.ID == "1608E179" {
fmt.Println("Rubish ", entry)
entries = append(entries[:i], entries[i+1:]...)
i--
continue
}
if val, ok := entryMap[entry.ID]; ok {
fmt.Println("Duplicate ID", val)
} else {
entryMap[entry.ID] = &entry
}
}
for _, entry := range entries {
for i := 0; i < len(entry.Supporting); i++ {
supporting := entry.Supporting[i]
if _, ok := entryMap[supporting]; !ok {
fmt.Println("Not found supporting", supporting)
entry.Supporting = append(entry.Supporting[:i], entry.Supporting[i+1:]...)
i--
}
}
}
return entryMap
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment