Skip to content

Commit

Permalink
Convert to using new string GIDs and remove injected client references
Browse files Browse the repository at this point in the history
  • Loading branch information
kothar committed Jan 13, 2019
1 parent 7418b63 commit bbe591e
Show file tree
Hide file tree
Showing 17 changed files with 185 additions and 260 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
cmd/asana/asana
/.idea
3 changes: 0 additions & 3 deletions asana.go
Original file line number Diff line number Diff line change
Expand Up @@ -254,8 +254,5 @@ func (c *Client) parseResponseData(data []byte, result interface{}) error {
return err
}

// Inject the client into expandable types
c.inject(result)

return nil
}
6 changes: 3 additions & 3 deletions attachments.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ type Attachment struct {
}

// Attachments lists all stories attached to a task
func (t *Task) Attachments(opts ...*Options) ([]*Attachment, *NextPage, error) {
t.trace("Listing attachments for %q", t.Name)
func (t *Task) Attachments(client *Client, opts ...*Options) ([]*Attachment, *NextPage, error) {
client.trace("Listing attachments for %q", t.Name)

var result []*Attachment

// Make the request
nextPage, err := t.client.get(fmt.Sprintf("/tasks/%d/attachments", t.ID), nil, &result, opts...)
nextPage, err := client.get(fmt.Sprintf("/tasks/%s/attachments", t.ID), nil, &result, opts...)
return result, nextPage, err
}
24 changes: 12 additions & 12 deletions cmd/asana/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ import (
var options struct {
Token string `long:"token" description:"Personal Access Token used to authorize access to the API" env:"ASANA_TOKEN" required:"true"`

Workspace []int64 `long:"workspace" short:"w" description:"Workspace to access"`
Project []int64 `long:"project" short:"p" description:"Project to access"`
Task []int64 `long:"task" short:"t" description:"Task to access"`
Workspace []string `long:"workspace" short:"w" description:"Workspace to access"`
Project []string `long:"project" short:"p" description:"Project to access"`
Task []string `long:"task" short:"t" description:"Task to access"`

Debug bool `short:"d" long:"debug" description:"Show debug information"`
Verbose []bool `short:"v" long:"verbose" description:"Show verbose output"`
Expand Down Expand Up @@ -63,40 +63,40 @@ func main() {
}

for _, w := range options.Workspace {
workspace := client.Workspace(w)
check(util.ListProjects(workspace))
workspace := asana.NewWorkspace(w)
check(util.ListProjects(client, workspace))
}
return
}

for _, p := range options.Project {
project := client.Project(p)

check(util.ListTasks(project))
check(util.ListTasks(client, project))
}
return
}

for _, t := range options.Task {
task := client.Task(t)
check(task.Expand())
task := asana.NewTask(t)
check(task.Expand(client))

fmt.Printf("Task %d: %s\n", task.ID, task.Name)
fmt.Printf("Task %s: %q\n", task.ID, task.Name)
fmt.Printf(" Completed: %v\n", task.Completed)
if !task.Completed {
fmt.Printf(" Due: %s\n", task.DueAt)
}
if task.Notes != "" {
fmt.Printf(" Notes: %s\n", task.Notes)
fmt.Printf(" Notes: %q\n", task.Notes)
}

// Get subtasks
subtasks, nextPage, err := task.Subtasks()
subtasks, nextPage, err := task.Subtasks(client)
check(err)
_ = nextPage

for _, subtask := range subtasks {
fmt.Printf(" Subtask %d: %s\n", subtask.ID, subtask.Name)
fmt.Printf(" Subtask %s: %q\n", subtask.ID, subtask.Name)
}
}
}
24 changes: 12 additions & 12 deletions customfields.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,38 +73,38 @@ type CustomFieldValue struct {
EnumValue *EnumValue `json:"enum_value,omitempty"`
}

// CustomField retrieves a custom field record by ID
func (c *Client) CustomField(id int64) *CustomField {
// NewCustomField creates a custom field record with the given ID
func NewCustomField(id string) *CustomField {
result := &CustomField{}
result.init(id, c)
result.ID = id
return result
}

// Expand loads the full details for this CustomField
func (f *CustomField) Expand() error {
f.trace("Loading details for custom field %q", f.ID)
func (f *CustomField) Expand(client *Client) error {
client.trace("Loading details for custom field %q", f.ID)

if f.expanded {
return nil
}

_, err := f.client.get(fmt.Sprintf("/custom_fields/%d", f.ID), nil, f)
_, err := client.get(fmt.Sprintf("/custom_fields/%s", f.ID), nil, f)
return err
}

// CustomFields returns the compact records for all custom fields in the workspace
func (w *Workspace) CustomFields(options ...*Options) ([]*CustomField, *NextPage, error) {
w.trace("Listing custom fields in workspace %d...\n", w.ID)
func (w *Workspace) CustomFields(client *Client, options ...*Options) ([]*CustomField, *NextPage, error) {
client.trace("Listing custom fields in workspace %s...\n", w.ID)
var result []*CustomField

// Make the request
nextPage, err := w.client.get(fmt.Sprintf("/workspaces/%d/custom_fields", w.ID), nil, &result, options...)
nextPage, err := client.get(fmt.Sprintf("/workspaces/%s/custom_fields", w.ID), nil, &result, options...)
return result, nextPage, err
}

// AllCustomFields repeatedly pages through all available custom fields in a workspace
func (w *Workspace) AllCustomFields(options ...*Options) ([]*CustomField, error) {
allCustomFields := []*CustomField{}
func (w *Workspace) AllCustomFields(client *Client, options ...*Options) ([]*CustomField, error) {
var allCustomFields []*CustomField
nextPage := &NextPage{}

var customFields []*CustomField
Expand All @@ -117,7 +117,7 @@ func (w *Workspace) AllCustomFields(options ...*Options) ([]*CustomField, error)
}

allOptions := append([]*Options{page}, options...)
customFields, nextPage, err = w.CustomFields(allOptions...)
customFields, nextPage, err = w.CustomFields(client, allOptions...)
if err != nil {
return nil, err
}
Expand Down
12 changes: 0 additions & 12 deletions log.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,3 @@ func (c *Client) debug(format string, args ...interface{}) {
log.Printf(format, args...)
}
}

func (e *Expandable) info(format string, args ...interface{}) {
e.client.info(format, args...)
}

func (e *Expandable) trace(format string, args ...interface{}) {
e.client.trace(format, args...)
}

func (e *Expandable) debug(format string, args ...interface{}) {
e.client.debug(format, args...)
}
24 changes: 12 additions & 12 deletions projects.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ type ProjectBase struct {
type NewProject struct {
ProjectBase

Workspace int64 `json:"workspace,omitempty"`
Team int64 `json:"team,omitempty"`
Workspace string `json:"workspace,omitempty"`
Team string `json:"team,omitempty"`
}

// Project represents a prioritized list of tasks in Asana. It exists in a
Expand Down Expand Up @@ -94,37 +94,37 @@ type Project struct {
}

// Project creates an unexpaned Project object with the given ID
func (c *Client) Project(id int64) *Project {
func (c *Client) Project(id string) *Project {
result := &Project{}
result.init(id, c)
result.ID = id
return result
}

// Expand loads the full details for this Project
func (p *Project) Expand() error {
p.trace("Loading project details for %q", p.Name)
func (p *Project) Expand(client *Client) error {
client.trace("Loading project details for %q", p.Name)

if p.expanded {
return nil
}

_, err := p.client.get(fmt.Sprintf("/projects/%d", p.ID), nil, p)
_, err := client.get(fmt.Sprintf("/projects/%s", p.ID), nil, p)
return err
}

// Projects returns a list of projects in this workspace
func (w *Workspace) Projects(options ...*Options) ([]*Project, *NextPage, error) {
w.trace("Listing projects in %q", w.Name)
func (w *Workspace) Projects(client *Client, options ...*Options) ([]*Project, *NextPage, error) {
client.trace("Listing projects in %q", w.Name)

var result []*Project

// Make the request
nextPage, err := w.client.get(fmt.Sprintf("/workspaces/%d/projects", w.ID), nil, &result, options...)
nextPage, err := client.get(fmt.Sprintf("/workspaces/%s/projects", w.ID), nil, &result, options...)
return result, nextPage, err
}

// AllProjects repeatedly pages through all available projects in a workspace
func (w *Workspace) AllProjects(options ...*Options) ([]*Project, error) {
func (w *Workspace) AllProjects(client *Client, options ...*Options) ([]*Project, error) {
allProjects := []*Project{}
nextPage := &NextPage{}

Expand All @@ -138,7 +138,7 @@ func (w *Workspace) AllProjects(options ...*Options) ([]*Project, error) {
}

allOptions := append([]*Options{page}, options...)
projects, nextPage, err = w.Projects(allOptions...)
projects, nextPage, err = w.Projects(client, allOptions...)
if err != nil {
return nil, err
}
Expand Down
42 changes: 0 additions & 42 deletions reflect.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,48 +5,6 @@ import (
"strings"
)

var expandableType = reflect.TypeOf(Expandable{})

// Populates expandable objects with a reference to the current client.
// Object graph must not contain cycles, or an infinite loop will occur.
func (c *Client) inject(object interface{}) {
clientValue := reflect.ValueOf(c)
value := reflect.ValueOf(object)

c.injectClientValue(clientValue, value)
}

func (c *Client) injectClientValue(clientValue, value reflect.Value) {
if value.Kind() == reflect.Ptr || value.Kind() == reflect.Interface {
if !value.IsNil() {
c.injectClientValue(clientValue, value.Elem())
}
return
}

if value.Kind() == reflect.Slice || value.Kind() == reflect.Array {
for j := 0; j < value.Len(); j++ {
element := value.Index(j)
c.injectClientValue(clientValue, element)
}
return
}

if value.Kind() == reflect.Struct {
// Inject into child fields
for i := 0; i < value.NumField(); i++ {
c.injectClientValue(clientValue, value.Field(i))
}

if value.Type() == expandableType {
exp := value.Interface().(Expandable)
exp.client = clientValue.Interface().(*Client)
}
}

return
}

// Fields gets all valid JSON fields for a type
func Fields(i interface{}) *Options {
t := reflect.TypeOf(i)
Expand Down
38 changes: 19 additions & 19 deletions sections.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,54 +20,54 @@ type Section struct {
WithCreated

// Read-only. The project which contains the section.
Project int64 `json:"project,omitempty"`
Project string `json:"project,omitempty"`
}

// Section creates an unexpanded Section object with the given ID
func (c *Client) Section(id int64) *Section {
func (c *Client) Section(id string) *Section {
result := &Section{}
result.init(id, c)
result.ID = id
return result
}

// Expand loads the full details for this Section
func (s *Section) Expand() error {
s.trace("Loading section details for %q", s.Name)
func (s *Section) Expand(client *Client) error {
client.trace("Loading section details for %q", s.Name)

if s.expanded {
return nil
}

_, err := s.client.get(fmt.Sprintf("/sections/%d", s.ID), nil, s)
_, err := client.get(fmt.Sprintf("/sections/%s", s.ID), nil, s)
return err
}

// Sections returns a list of sections in this project
func (p *Project) Sections(opts ...*Options) ([]*Section, *NextPage, error) {
p.trace("Listing sections in %q", p.Name)
func (p *Project) Sections(client *Client, opts ...*Options) ([]*Section, *NextPage, error) {
client.trace("Listing sections in %q", p.Name)
var result []*Section

// Make the request
nextPage, err := p.client.get(fmt.Sprintf("/projects/%d/sections", p.ID), nil, &result, opts...)
nextPage, err := client.get(fmt.Sprintf("/projects/%s/sections", p.ID), nil, &result, opts...)
return result, nextPage, err
}

// CreateSection creates a new section in the given project
func (p *Project) CreateSection(section *SectionBase) (*Section, error) {
p.info("Creating section %q", section.Name)
func (p *Project) CreateSection(client *Client, section *SectionBase) (*Section, error) {
client.info("Creating section %q", section.Name)

result := &Section{}
result.expanded = true

err := p.client.post(fmt.Sprintf("projects/%d/sections", p.ID), section, result)
err := client.post(fmt.Sprintf("projects/%s/sections", p.ID), section, result)
return result, err
}

type SectionInsertRequest struct {
Project int64 `json:"project"`
Section int64 `json:"section"`
BeforeSection int64 `json:"before_section,omitempty"`
AfterSection int64 `json:"after_section,omitempty"`
Project string `json:"project_gid"`
Section string `json:"section"`
BeforeSection string `json:"before_section,omitempty"`
AfterSection string `json:"after_section,omitempty"`
}

// InsertSection moves sections relative to each other in a board view.
Expand All @@ -76,9 +76,9 @@ type SectionInsertRequest struct {
// Sections cannot be moved between projects.
//
// At this point in time, moving sections is not supported in list views, only board views.
func (p *Project) InsertSection(request *SectionInsertRequest) error {
p.info("Moving section %d", request.Section)
func (p *Project) InsertSection(client *Client, request *SectionInsertRequest) error {
client.info("Moving section %s", request.Section)

err := p.client.post(fmt.Sprintf("projects/%d/sections/insert", p.ID), request, nil)
err := client.post(fmt.Sprintf("projects/%s/sections/insert", p.ID), request, nil)
return err
}
Loading

0 comments on commit bbe591e

Please sign in to comment.