diff --git a/project.go b/project.go index 1464b71..cd7bb0b 100644 --- a/project.go +++ b/project.go @@ -23,13 +23,23 @@ func ParseProject(text string) (*Project, error) { AdditionalTags: make(map[string]string), } project.Original = strings.Trim(text, "\t\n\r ") - parts := strings.Fields(project.Original) - project.Name, parts = parts[0], parts[1:] - if parts[1][0] == '^' { - project.Directory, parts = parts[0], parts[1:] + parts := getParts(project.Original) + //parts := strings.Fields(project.Original) + var pIdx int + for pIdx = range parts { + if len(parts[pIdx]) > 0 { + if parts[pIdx][0] == '^' { + break + } + project.Name = project.Name + " " + parts[pIdx] + } } + project.Name = strings.TrimSpace(project.Name) + parts = parts[pIdx:] for _, v := range parts { switch v[0] { + case '^': // Project Directory + project.Directory = v[1:] case '@': // Contexts project.Contexts = append(project.Contexts, v[1:]) case '+': // ProjectTags @@ -47,6 +57,40 @@ func ParseProject(text string) (*Project, error) { return &project, err } +// getParts parses the text from text pulling out each part. +// By default it splits on spaces, the only exception is if we find a double-quote +func getParts(text string) []string { + var ret []string + var wrk string + quoteStart := -1 + for i := range text { + if quoteStart >= 0 { + if text[i] == '"' { + quoteStart = -1 + ret = append(ret, wrk) + } else { + wrk = wrk + string(text[i]) + } + } else { + switch text[i] { + case '"': + quoteStart = i + case ' ': + if len(wrk) > 0 { + ret = append(ret, wrk) + } + wrk = "" + default: + wrk = wrk + string(text[i]) + } + } + } + if len(wrk) > 0 { + ret = append(ret, wrk) + } + return ret +} + // String returns a complete project string in project.txt format. // // Contexts, ProjectTags, and Additional Tags are alphabetically sorted, @@ -92,6 +136,15 @@ func (project *Project) HasContext(context string) bool { return false } +func (project *Project) GetContextsString() string { + var text string + sort.Strings(project.Contexts) + for _, context := range project.Contexts { + text += fmt.Sprintf("%s ", context) + } + return text +} + func (project *Project) HasProjectTag(projectTag string) bool { for _, v := range project.ProjectTags { if v == projectTag { @@ -101,6 +154,15 @@ func (project *Project) HasProjectTag(projectTag string) bool { return false } +func (project *Project) GetProjectsString() string { + var text string + sort.Strings(project.ProjectTags) + for _, pTag := range project.ProjectTags { + text += fmt.Sprintf("%s ", pTag) + } + return text +} + func (project *Project) SetTag(name, val string) { project.AdditionalTags[name] = val } @@ -113,3 +175,16 @@ func (project *Project) HasTag(name string) bool { func (project *Project) GetTag(name string) string { return project.AdditionalTags[name] } + +func (project *Project) GetTagsString() string { + var text string + keys := make([]string, 0, len(project.AdditionalTags)) + for key := range project.AdditionalTags { + keys = append(keys, key) + } + sort.Strings(keys) + for _, key := range keys { + text += fmt.Sprintf("%s:%s ; ", key, project.AdditionalTags[key]) + } + return text +}