From d6146e9ce270e05be91437da150cd7b7e8c90677 Mon Sep 17 00:00:00 2001 From: Volker Schukai <volker.schukai@schukai.com> Date: Mon, 20 Jun 2022 11:40:06 +0200 Subject: [PATCH] chore: commit save point --- .../reqman_issues_gitlab_sync.xml | 2 +- .../reqman_requirement_report.xml | 2 +- application/source/changelog.go | 5 +- application/source/commandline.go | 91 +++------ application/source/commandlineoptions.go | 62 ++++++ application/source/config.go | 4 +- application/source/defaults.go | 18 +- application/source/files.go | 7 +- application/source/gitlab.go | 21 +- application/source/issues.go | 110 +++++++---- application/source/items.go | 2 +- application/source/privacy.go | 2 +- application/source/requirements.go | 57 +++--- application/source/tasks.go | 2 +- application/source/util.go | 11 +- development/examples/example1/144444.md | 180 ++++++++++++++++++ .../examples/example1/req1/1/.test1.md.swp | Bin 16384 -> 0 bytes development/examples/example1/req1/1/test1.md | 13 +- 18 files changed, 423 insertions(+), 166 deletions(-) create mode 100644 application/source/commandlineoptions.go create mode 100644 development/examples/example1/144444.md delete mode 100644 development/examples/example1/req1/1/.test1.md.swp diff --git a/.idea/runConfigurations/reqman_issues_gitlab_sync.xml b/.idea/runConfigurations/reqman_issues_gitlab_sync.xml index 15cac09..61f5a0e 100644 --- a/.idea/runConfigurations/reqman_issues_gitlab_sync.xml +++ b/.idea/runConfigurations/reqman_issues_gitlab_sync.xml @@ -3,7 +3,7 @@ <module name="requirements-manager" /> <working_directory value="$PROJECT_DIR$/application/source" /> <go_parameters value="-ldflags "-X main.version=1.0.15 -X main.build=20220616123315"" /> - <parameters value="tasks gitlab -p $PROJECT_DIR$/development/examples/example1" /> + <parameters value="gitlab sync -p $PROJECT_DIR$/development/examples/example1" /> <kind value="DIRECTORY" /> <package value="gitlab.schukai.com/oss/utilities/requirements-manager" /> <directory value="$PROJECT_DIR$/application/source" /> diff --git a/.idea/runConfigurations/reqman_requirement_report.xml b/.idea/runConfigurations/reqman_requirement_report.xml index e2bbccb..b35e550 100644 --- a/.idea/runConfigurations/reqman_requirement_report.xml +++ b/.idea/runConfigurations/reqman_requirement_report.xml @@ -2,7 +2,7 @@ <configuration default="false" name="reqman requirement report" type="GoApplicationRunConfiguration" factoryName="Go Application"> <module name="requirements-manager" /> <working_directory value="$PROJECT_DIR$/application/source" /> - <parameters value="requirements report --gitlab --grouped-by Estimation -p $PROJECT_DIR$/development/examples/example1/req1/1/test1.md" /> + <parameters value="requirements report --remote --grouped-by Estimation -p $PROJECT_DIR$/development/examples/example1/req1/1/test1.md" /> <kind value="DIRECTORY" /> <package value="gitlab.schukai.com/oss/utilities/requirements-manager" /> <directory value="$PROJECT_DIR$/application/source" /> diff --git a/application/source/changelog.go b/application/source/changelog.go index 4c54ef5..b7465d5 100644 --- a/application/source/changelog.go +++ b/application/source/changelog.go @@ -8,12 +8,13 @@ import ( type logs []string -func buildChangelog(config *Configuration, pageMap map[string]requirement) (error, string, bool) { +func buildChangelog(config *Configuration, pageMap map[string]*requirement) (error, string, bool) { changelog := make(map[string]logs) datemap := make(map[string]string) - for _, p := range pageMap { + for _, q := range pageMap { + p := *q e := strings.Trim(p.Title+" ("+p.ID+")", " ") diff --git a/application/source/commandline.go b/application/source/commandline.go index 86ab5e4..0c7d2b1 100644 --- a/application/source/commandline.go +++ b/application/source/commandline.go @@ -9,63 +9,6 @@ import ( "github.com/jessevdk/go-flags" ) -type commandLineOptions struct { - Config string `short:"c" long:"config" description:"file with configuration values"` - Path string `short:"p" long:"path" description:"define the path where the specifications are located" default:"."` - DateFormat string `long:"date-format" description:"date format" default:"2006-01-02"` - Requirements struct { - Print struct { - Columns []string `short:"c" long:"column" description:"defines the columns used"` - } `command:"print"` - Add struct { - ID string `long:"id" required:"true" description:"new requirement id"` - } `command:"add"` - Report struct { - GroupedBy string `long:"grouped-by" required:"false" description:"grouped by"` - Gitlab bool `long:"gitlab" description:"get data from gitlab"` - } `command:"report"` - } `command:"requirements"` - Tasks struct { - Print struct { - } `command:"print"` - Gitlab struct { - ProjectID string `long:"project-id" required:"false" description:"gitlab project id"` - Token string `long:"token" required:"false" description:"gitlab token"` - } `command:"gitlab"` - } `command:"tasks"` - Issues struct { - Print struct { - } `command:"print"` - Gitlab struct { - ProjectID string `long:"project-id" required:"false" description:"gitlab project id"` - Token string `long:"token" required:"false" description:"gitlab token"` - } `command:"gitlab"` - } `command:"issues"` - Items struct { - Print struct { - } `command:"print"` - } `command:"items"` - Changelog struct { - Print struct { - } `command:"print"` - } `command:"changelog"` - Privacy struct { - Print struct { - } `command:"print"` - } `command:"privacy"` - Overview struct { - Print struct { - Columns []string `short:"c" long:"column" description:"defines the columns used"` - TemplatePath string `short:"t" long:"template" description:"file name of the template of the overview page"` - Output string `short:"o" long:"output" description:"redirect output to a file"` - Format string `short:"f" long:"format" description:"the desired output format" choice:"pdf" choice:"md"` - LatexTemplatePath string `short:"l" long:"latex-template-path" description:"latex template"` - } `command:"print"` - } `command:"overview"` - Version struct { - } `command:"version"` -} - func executeCommand() { arguments := new(commandLineOptions) @@ -178,25 +121,41 @@ func executeCommand() { subcommand := activeCommand.Active switch subcommand.Name { case "print": - err := printIssueTable(config) + + if arguments.Issues.Print.GitlabToken != "" { + config.Gitlab.Token = arguments.Issues.Print.GitlabToken + } + + err := printIssueTable(config, arguments) if err != nil { printErrorAndExit(2, err.Error()) } - case "gitlab": - syncTasksWithGitlab(config) + + case "items": + subcommand := activeCommand.Active + switch subcommand.Name { + case "print": + err := printItemTable(config) + if err != nil { + printErrorAndExit(2, err.Error()) + } + } + } - case "items": + case "gitlab": subcommand := activeCommand.Active switch subcommand.Name { - case "print": - err := printItemTable(config) - if err != nil { - printErrorAndExit(2, err.Error()) + case "sync": + + if arguments.Gitlab.GitlabToken != "" { + config.Gitlab.Token = arguments.Gitlab.GitlabToken } - } + syncTasksWithGitlab(config) + } } + } func readTemplate(argPath string) string { diff --git a/application/source/commandlineoptions.go b/application/source/commandlineoptions.go new file mode 100644 index 0000000..40b407e --- /dev/null +++ b/application/source/commandlineoptions.go @@ -0,0 +1,62 @@ +package main + +type commandLineOptions struct { + Config string `short:"c" long:"config" description:"file with configuration values"` + Path string `short:"p" long:"path" description:"define the path where the specifications are located" default:"."` + DateFormat string `long:"date-format" description:"date format" default:"2006-01-02"` + Requirements struct { + Print struct { + Columns []string `short:"c" long:"column" description:"defines the columns used"` + } `command:"print"` + Add struct { + ID string `long:"id" required:"true" description:"new requirement id"` + } `command:"add"` + Report struct { + GroupedBy string `long:"grouped-by" required:"false" description:"grouped by"` + Remote bool `long:"remote" description:"get data from remote"` + } `command:"report"` + } `command:"requirements"` + Tasks struct { + Print struct { + } `command:"print"` + //Sync struct { + // //ProjectID string `long:"project-id" required:"false" description:"gitlab project id"` + // //Token string `long:"token" required:"false" description:"gitlab token"` + //} `command:"sync"` + } `command:"tasks"` + Issues struct { + Print struct { + GitlabToken string `long:"gitlab-token" required:"false" description:"gitlab token"` + Remote bool `long:"remote" required:"false" description:"get data from remote"` + } `command:"print"` + } `command:"issues"` + Items struct { + Print struct { + } `command:"print"` + } `command:"items"` + Changelog struct { + Print struct { + } `command:"print"` + } `command:"changelog"` + Privacy struct { + Print struct { + } `command:"print"` + } `command:"privacy"` + Overview struct { + Print struct { + Columns []string `short:"c" long:"column" description:"defines the columns used"` + TemplatePath string `short:"t" long:"template" description:"file name of the template of the overview page"` + Output string `short:"o" long:"output" description:"redirect output to a file"` + Format string `short:"f" long:"format" description:"the desired output format" choice:"pdf" choice:"md"` + LatexTemplatePath string `short:"l" long:"latex-template-path" description:"latex template"` + } `command:"print"` + } `command:"overview"` + Version struct { + } `command:"version"` + Gitlab struct { + Sync struct { + } `command:"sync"` + // ProjectID string `long:"project-id" required:"false" description:"gitlab project id"` + GitlabToken string `long:"gitlab-token" required:"false" description:"gitlab token"` + } `command:"gitlab"` +} diff --git a/application/source/config.go b/application/source/config.go index ca5d6a4..84ef8bc 100644 --- a/application/source/config.go +++ b/application/source/config.go @@ -29,9 +29,9 @@ type Configuration struct { DateFormat string `yaml:"DateFormat"` } `yaml:"Locale"` - GitLab struct { + Gitlab struct { Token string `yaml:"Token"` - } `yaml:"GitLab"` + } `yaml:"Gitlab"` Overview struct { Template struct { diff --git a/application/source/defaults.go b/application/source/defaults.go index fb35a01..a54ff24 100644 --- a/application/source/defaults.go +++ b/application/source/defaults.go @@ -104,9 +104,23 @@ Created: %%CREATED%% Last Update: null # The issues that are associated with this requirement +# You can add an issue by adding a new line to the list with the following format: +# - Gitlab: +# ID: <issue-id> +# +# if the issue is not yet in the project, you can add it by using the following format: +# Only the Title is required. +# - Gitlab: +# Title: <issue-title> +# Description: <issue-description> +# Priority: <issue-priority> +# Status: <issue-status> +# Assignee: <issue-assignee> +# Milestone: <issue-milestone> +# Labels: <issue-labels> +# Issues: - - Title: null - URL: null + # the individual items as a list Items: diff --git a/application/source/files.go b/application/source/files.go index 9e6213f..41190a6 100644 --- a/application/source/files.go +++ b/application/source/files.go @@ -8,11 +8,11 @@ import ( ) // -func collectStructureFromFiles(directory string) (error, map[string]requirement) { +func collectStructureFromFiles(directory string) (error, map[string]*requirement) { cleanedDirectory := path.Clean(directory) - pageMap := make(map[string]requirement) + pageMap := make(map[string]*requirement) //pageMap := []requirement{} @@ -53,10 +53,11 @@ func collectStructureFromFiles(directory string) (error, map[string]requirement) p.data.File = "." + bs p.data.Absolute = cleanedPath p.data.ToDos = findTask(content) + p.data.Yaml = p.node k := cleanedPath - pageMap[k] = p.data + pageMap[k] = &p.data return nil }) diff --git a/application/source/gitlab.go b/application/source/gitlab.go index afdbc1f..afd3e06 100644 --- a/application/source/gitlab.go +++ b/application/source/gitlab.go @@ -76,8 +76,8 @@ func getGitlabContext(config *Configuration) *gitlabContext { options := gitlab.WithBaseURL(context.apiUrl.String()) - context.token = config.GitLab.Token - c, err := gitlab.NewClient(config.GitLab.Token, options) + context.token = config.Gitlab.Token + c, err := gitlab.NewClient(config.Gitlab.Token, options) if err != nil { printErrorAndExit(2, "Failed to create client", err.Error()) } @@ -116,26 +116,29 @@ func searchProject(context *gitlabContext) { } -func enrichIssuesWithGitlab(pageMap *map[string]requirement, config *Configuration) error { +func enrichIssuesWithGitlab(pageMap map[string]*requirement, config *Configuration) error { context := getGitlabContext(config) searchProject(context) - for _, requirement := range *pageMap { + for _, requirement := range pageMap { + for k, issue := range requirement.Issues { - if issue.GitlabID == 0 { + if issue.GitlabIntern == nil { + continue + } + + if issue.GitlabIntern.ID == 0 { continue } - i, err := loadIssuesFromGitlab(context, issue.GitlabID) + i, err := loadIssuesFromGitlab(context, issue.GitlabIntern.ID) if err != nil { return err } - // requirement is a copy of the original requirement - // this works because issue is a pointer - requirement.Issues[k].Gitlab = i + requirement.Issues[k].GitlabRemote = i } } diff --git a/application/source/issues.go b/application/source/issues.go index 36c58d7..ed88f4f 100644 --- a/application/source/issues.go +++ b/application/source/issues.go @@ -6,24 +6,26 @@ import ( "strings" "time" - "github.com/xanzy/go-gitlab" + "gopkg.in/yaml.v3" "github.com/olekukonko/tablewriter" + "github.com/xanzy/go-gitlab" ) +type GitlabInternalIssueStruct struct { + ID int `yaml:"ID"` + Title string `yaml:"Title"` + Description string `yaml:"Description"` + Priority string `yaml:"Priority"` + Status string `yaml:"Status"` + Assignee string `yaml:"Assignee"` + Milestone string `yaml:"Milestone"` + Labels []string `yaml:"Labels"` +} + type Issue struct { - GitlabID int `yaml:"Gitlab-ID"` - Gitlab *gitlab.Issue - //Title string `yaml:"Title"` - //URL string `yaml:"URL"` - //ID string `yaml:"ID"` - //Name string `yaml:"Name"` - //Type string `yaml:"Type"` - //Group string `yaml:"group"` - //Description string `yaml:"Description"` - //DeliveryUntil time.Time `yaml:"Delivery until"` - //ProvidedOn time.Time `yaml:"Provided on"` - //ProvidedBy string `yaml:"Provided by"` + GitlabIntern *GitlabInternalIssueStruct `yaml:"Gitlab"` + GitlabRemote *gitlab.Issue } func loadIssuesFromGitlab(context *gitlabContext, issueID int) (*gitlab.Issue, error) { @@ -40,7 +42,7 @@ func loadIssuesFromGitlab(context *gitlabContext, issueID int) (*gitlab.Issue, e //err, pageData := collectStructureFromFiles(config.Path) } -func buildIssueOverviewTable(config *Configuration, pageMap map[string]requirement, extended bool) (error, string, bool) { +func buildIssueOverviewTable(config *Configuration, pageMap map[string]*requirement, extended bool) (error, string, bool) { buf := new(bytes.Buffer) has := false @@ -71,12 +73,16 @@ func buildIssueOverviewTable(config *Configuration, pageMap map[string]requireme for _, requirement := range pageMap { for _, issue := range requirement.Issues { - gitlab := issue.Gitlab + gitlabIntern := issue.GitlabIntern + + if gitlabIntern == nil { + continue + } var col []string dueDate := "—" - id := printer.Sprintf("%d", issue.GitlabID) + id := "—" labels := "—" estimate := "—" spent := "—" @@ -84,20 +90,29 @@ func buildIssueOverviewTable(config *Configuration, pageMap map[string]requireme title := "—" assignees := "—" - if gitlab != nil { - if gitlab.DueDate != nil { - d := (time.Time)(*gitlab.DueDate) + id = printer.Sprintf("%d", gitlabIntern.ID) + if gitlabIntern.Labels != nil { + labels = strings.Join(gitlabIntern.Labels, ", ") + } + if gitlabIntern.Title != "" { + title = gitlabIntern.Title + } + + gitlabRemote := issue.GitlabRemote + if gitlabRemote != nil { + if gitlabRemote.DueDate != nil { + d := (time.Time)(*gitlabRemote.DueDate) dueDate = d.Format(config.Locale.DateFormat) } - labels = printer.Sprintf("%s", strings.Join(gitlab.Labels, ", ")) - estimate = printer.Sprintf("%s", gitlab.TimeStats.HumanTimeEstimate) - spent = printer.Sprintf("%s", gitlab.TimeStats.HumanTotalTimeSpent) - state = printer.Sprintf(gitlab.State) - title = printer.Sprintf("%s", gitlab.Title) + labels = printer.Sprintf("%s", strings.Join(gitlabRemote.Labels, ", ")) + estimate = printer.Sprintf("%s", gitlabRemote.TimeStats.HumanTimeEstimate) + spent = printer.Sprintf("%s", gitlabRemote.TimeStats.HumanTotalTimeSpent) + state = printer.Sprintf(gitlabRemote.State) + title = printer.Sprintf("%s", gitlabRemote.Title) a := []string{} - for _, assignee := range gitlab.Assignees { + for _, assignee := range gitlabRemote.Assignees { a = append(a, assignee.Name) } @@ -125,11 +140,14 @@ func buildIssueOverviewTable(config *Configuration, pageMap map[string]requireme return nil, buf.String(), has } -func printIssueTable(config *Configuration) error { +func printIssueTable(config *Configuration, arguments *commandLineOptions) error { err, pageMap := collectStructureFromFiles(config.Path) - enrichIssuesWithGitlab(&pageMap, config) - if err != nil { - return err + + if arguments.Issues.Print.Remote { + enrichIssuesWithGitlab(pageMap, config) + if err != nil { + return err + } } err, table, _ := buildIssueOverviewTable(config, pageMap, true) @@ -156,17 +174,35 @@ func syncTasksWithGitlab(config *Configuration) error { context := getGitlabContext(config) searchProject(context) - client := context.client + //client := context.client - issues, response, err := client.Issues.ListProjectIssues(context.project.ID, &gitlab.ListProjectIssuesOptions{}) - if err != nil { - printErrorAndExit(0, "Failed to get issues %s", err.Error()) - } + //issues, response, err := client.Issues.ListProjectIssues(context.project.ID, &gitlab.ListProjectIssuesOptions{}) + //if err != nil { + // printErrorAndExit(0, "Failed to get issues %s", err.Error()) + //} + + //for _, issue := range issues { + // fmt.Println(issue.Title) + //} + //fmt.Println(response.StatusCode) + + for file, pd := range pageData { + fmt.Println(file) + //fmt.Println(pd) + + buf := new(bytes.Buffer) + //pd.Yaml.Encode(buf) + + var encoder = yaml.NewEncoder(buf) + err := encoder.Encode(pd.Yaml) + if err != nil { + return err + } + encoder.Close() + + fmt.Println(string(buf.Bytes())) - for _, issue := range issues { - fmt.Println(issue.Title) } - fmt.Println(response.StatusCode) return nil } diff --git a/application/source/items.go b/application/source/items.go index 567df8f..1d1a262 100644 --- a/application/source/items.go +++ b/application/source/items.go @@ -19,7 +19,7 @@ type Item struct { ProvidedBy string `yaml:"Provided by"` } -func buildItemOverviewTable(config *Configuration, pageMap map[string]requirement, extended bool) (error, string, bool) { +func buildItemOverviewTable(config *Configuration, pageMap map[string]*requirement, extended bool) (error, string, bool) { buf := new(bytes.Buffer) has := false diff --git a/application/source/privacy.go b/application/source/privacy.go index ae97429..381ac02 100644 --- a/application/source/privacy.go +++ b/application/source/privacy.go @@ -19,7 +19,7 @@ type Privacy struct { TOM string `yaml:"TOM"` } -func buildPrivacy(config *Configuration, pageMap map[string]requirement) (error, string, bool) { +func buildPrivacy(config *Configuration, pageMap map[string]*requirement) (error, string, bool) { hasPrivacy := false text := "" diff --git a/application/source/requirements.go b/application/source/requirements.go index 69f8217..ec0319a 100644 --- a/application/source/requirements.go +++ b/application/source/requirements.go @@ -11,6 +11,8 @@ import ( "strings" "time" + "gopkg.in/yaml.v3" + "github.com/olekukonko/tablewriter" ) @@ -22,6 +24,9 @@ type requirement struct { Privacy []Privacy `yaml:"Privacy"` Issues []Issue `yaml:"Issues"` + // remember the node structure of yaml + Yaml *yaml.Node + ID string `yaml:"ID"` References []string `yaml:"References"` Type string `yaml:"Type"` // Display, Functional, Performance, Printing, Report, Testing and Validate @@ -66,7 +71,7 @@ func addRequirement(config *Configuration, arguments *commandLineOptions) error return nil } -func buildRequirements(config *Configuration, pageMap map[string]requirement) (error, string, bool) { +func buildRequirements(config *Configuration, pageMap map[string]*requirement) (error, string, bool) { hasRequirements := false @@ -162,45 +167,26 @@ func printRequirements(config *Configuration) error { return err } -func integrateGitlabTimeSpent(pageMap *map[string]requirement) { +func integrateGitlabTimeSpent(pageMap map[string]*requirement) { - for k, requirement := range *pageMap { + for _, requirement := range pageMap { for _, i := range requirement.Issues { - if i.Gitlab == nil { + if i.GitlabRemote == nil { continue } - //d := time.Duration(i.Gitlab.TimeStats.TotalTimeSpent) * time.Second - //fmt.Println(fn, d) - //ref[fn].TimeSpent += d - requirement.TimeSpent = 99999999 - requirement.Status = "done" - - // fmt.Println(i.Gitlab.TimeStats.TotalTimeSpent) + d := time.Duration(i.GitlabRemote.TimeStats.TotalTimeSpent) * time.Second + requirement.TimeSpent += d } - pageMap[k] = requirement - - //if &pd.Issues == nil || &pd.Issues. == nil { - // continue - //} - // - //for _, issue := range pd.Issues.Gitlab { - // if issue == nil { - // continue - // } - // pd.TimeSpent += *issue.TimeSpent - //} - } - fmt.Println("integrateGitlabTimeSpent") } -func buildTimeReport(config *Configuration, arguments *commandLineOptions, pageMap *map[string]requirement) (error, string, string, bool) { +func buildTimeReport(config *Configuration, arguments *commandLineOptions, pageMap map[string]*requirement) (error, string, string, bool) { - if arguments.Requirements.Report.Gitlab { + if arguments.Requirements.Report.Remote { err := enrichIssuesWithGitlab(pageMap, config) if err != nil { return err, "", "", false @@ -218,7 +204,8 @@ func buildTimeReport(config *Configuration, arguments *commandLineOptions, pageM hasReport := false found := false - for _, p := range *pageMap { + for _, q := range pageMap { + p := *q fields := reflect.VisibleFields(reflect.TypeOf(p)) for _, field := range fields { @@ -243,13 +230,13 @@ func buildTimeReport(config *Configuration, arguments *commandLineOptions, pageM return nil, t1, t2, hasReport } -func buildTable1(groupedByKey string, pageMap *map[string]requirement) string { +func buildTable1(groupedByKey string, pageMap map[string]*requirement) string { estimated := map[string]float64{} timeSpent := map[string]float64{} - for _, d := range *pageMap { - + for _, q := range pageMap { + d := *q r := reflect.ValueOf(d) f := r.FieldByName(groupedByKey) k := "" @@ -328,12 +315,12 @@ type mathData struct { time timeStruct } -func buildTable2(pageMap *map[string]requirement) string { +func buildTable2(pageMap map[string]*requirement) string { est := map[int]mathData{} // inti struct - for _, d := range *pageMap { + for _, d := range pageMap { k := d.Estimation m := mathData{} @@ -349,7 +336,7 @@ func buildTable2(pageMap *map[string]requirement) string { } // calc sum - for _, d := range *pageMap { + for _, d := range pageMap { k := d.Estimation s := est[k] @@ -427,7 +414,7 @@ func printRequirementReport(config *Configuration, arguments *commandLineOptions return err } - err, table1, table2, _ := buildTimeReport(config, arguments, &pageData) + err, table1, table2, _ := buildTimeReport(config, arguments, pageData) if err != nil { return err } diff --git a/application/source/tasks.go b/application/source/tasks.go index a7a8703..3db6634 100644 --- a/application/source/tasks.go +++ b/application/source/tasks.go @@ -72,7 +72,7 @@ func findTask(content []byte) []task { return toDos } -func buildTasksTable(config *Configuration, pageMap map[string]requirement, extended bool) (error, string, bool) { +func buildTasksTable(config *Configuration, pageMap map[string]*requirement, extended bool) (error, string, bool) { buf := new(bytes.Buffer) diff --git a/application/source/util.go b/application/source/util.go index 2f109cd..45ce7a1 100644 --- a/application/source/util.go +++ b/application/source/util.go @@ -14,6 +14,7 @@ import ( type contentRequirement struct { content string data requirement + node *yaml.Node } func splitYamlParts(content []byte) (error, contentRequirement) { @@ -71,13 +72,15 @@ func splitYamlParts(content []byte) (error, contentRequirement) { return err, contentRequirement{} } - data := requirement{} - err = yaml.Unmarshal([]byte(meta), &data) + var node yaml.Node + err = yaml.Unmarshal([]byte(meta), &node) if err != nil { - printError("YAML parse error", err.Error()) return err, contentRequirement{} } + data := requirement{} + node.Decode(&data) + tempItem := []Item{} for i, _ := range data.Items { @@ -107,6 +110,8 @@ func splitYamlParts(content []byte) (error, contentRequirement) { req := contentRequirement{} req.data = data + req.node = &node + var buffer bytes.Buffer err = t.Execute(&buffer, data) if err != nil { diff --git a/development/examples/example1/144444.md b/development/examples/example1/144444.md new file mode 100644 index 0000000..5ebaeec --- /dev/null +++ b/development/examples/example1/144444.md @@ -0,0 +1,180 @@ + +--- +ID: 144444 +Title: null + +# Reference to other requirements +References: null + +# Display, Functional, Performance, Printing, Report, Testing or Validation +Type: null + +Alias: null + +Keywords: + - Requirement + +# First and last name of the authors as a list +Author: + - null + +# Proposed (The requirement has been requested by an authorized source.), +# In Progress (A business analyst is actively working on crafting the requirement.), +# Drafted (The initial version of the requirement has been written.), +# Approved (The requirement has been analyzed, its impact on the project has been estimated, and it has been allocated to the baseline for a specific release. ), +# Implemented (The code that implements the requirement has been designed, written, and unit tested. The requirement has been traced to the pertinent design and code elements. It’s now ready for review or other verification.), +# Verified (The requirement has satisfied its acceptance criteria, meaning that the correct functioning of the implemented requirement has been confirmed.), +# Deferred (An approved requirement is now planned for implementation in a later release.), +# Deleted (An approved requirement has been removed from the baseline.) or +# Rejected (The requirement was proposed but was never approved and is not planned for implementation in any upcoming release.) +Status: "Proposed" + +# Low, Medium, Hi +Complexity: null +# Low, Medium, Hi +Difficulty: null +# Nice to have, Low, Medium, Hi or Blocker +Priority: null +Version: 0.0.1 +Milestone: null + +# 0 (means that a task has already been completed), 1 (is a very small task), 2, 3, 5 (are rather smaller tasks), +# 8, 13, 20, 40, 100 +Estimation: + +# The time required for this requirement +# Valid time units are “nsâ€, “us†(or “µsâ€), “msâ€, “sâ€, “mâ€, “hâ€. +Time Spent: + +# who is the source of the demand +Source: null +Created: 2022-06-19 +Last Update: null + +# The issues that are associated with this requirement +# You can add an issue by adding a new line to the list with the following format: +# - ID: <issue-id> +# +# if the issue is not yet in the project, you can add it by using the following format: +# Only the Title is required. +# - GitlabIntern: +# - Title: <issue-title> +# - Description: <issue-description> +# - Priority: <issue-priority> +# - Status: <issue-status> +# - Assignee: <issue-assignee> +# - Milestone: <issue-milestone> +# - Labels: <issue-labels> +# +# Issues: +# - GitlabIntern: +# - ID: <issue-id> + +# the individual items as a list +Items: + - ID: null + Name: null + # what is it, a image, font, legal information, access data, texts, decisions, etc. + Type: null + # does this belong to a group + group: null + Description: null + Delivery until: null + # when was the project items delivered and by whom? + Provided on: null + Provided by: null + +# https://gdpr-info.eu/art-30-gdpr/ +Privacy: + - ID: null + + # Purpose of the data processing, + # for example, shipping an order and handing it over to a shipping service provider. + Purposes: null + + # More detailed description of the reason and process of data processing. + Description: null + + # Who is responsible for data protection + Contact: null + + # But working with these categories might end up being a bad idea since doing so might + # mean packing different things into one. This leads to either oversimplifications or + # a lot of specifications within a category. It might be advisable to split some of them + # up or to add additional ones to make them fit your business reality. + # Examples: Employees, Suppliers, Customers, Job applicants, Consultants, Visitors, Prospects, Contractors, Trainees + Affected Groups: null + + # + Category: + + # Example: 5 years from the payment of the salary + Data Retention Period: null + + # On what legal basis is the data collected + # Special legal regulation outside the GDPR + # Consent of the data subject (Art. 6 para. 1 a) DSG-VO) use Consent field + # Collective agreement (e.g. company agreement, collective agreement) + # Establishment, performance or termination of an employment relationship (nationally regulated in the BDSG) + # Contract or initiation of a contract with the data subject (Art. 6 para. 1 b) DSG-VO.) + # Balancing of interests (Art. 6 para. 1 f) DSG-VO): Please name the overriding interests + Legal Basis: null + + # “Consent†of the data subject refers to any freely given specific, informed and unambiguous indication of his or + # her wishes in the form of a statement or other unambiguous affirmative act by which the data subject signifies + # his or her agreement to personal data relating to him or her being processed. + Consent: null + + # Where applicable, transfers of personal data to a third country or an international organisation, including + # the identification of that third country or international organisation and, in the case of transfers referred + # to in the second subparagraph of Article 49(1), the documentation of suitable safeguards; + Transfers: + + # Where possible, a general description of the technical and organisational + # security measures referred to in Article 32(1). + TOM: null + +... + +### {{ .Title }} - {{ .ID }} + +#### Subheading + +- [ ] task 1 +- [ ] task 2 + + +{{ if .Items }} +#### Items + +| ID | Name | Delivery until | Provided on | +|--------------------|--------------|----------------------:|-----------------------------------------:| +{{ range .Items + }}| {{ .ID }} | {{ .Name }} | {{ .DeliveryUntil.Format "02.Jan" }} | {{ .ProvidedOn.Format "02.Jan" }} | +{{ end }} + +{{ end }} + +{{ if .Privacy }} +#### Privacy + +{{ range .Privacy }} +{{ if .Purposes }}**{{ .Purposes }}** {{ end }}**({{ .ID }})** + +{{ if .Description }} {{ .Description }} +{{ end }} +| | | +|-----------------------|----------------------------| +| Category | {{ .Category }} | +| Data Retention Period | {{ .DataRetentionPeriod }} | +| Legal Basis | {{ .LegalBasis }} | +| Transfers | {{ .Transfers }} | +{{ end }} + +{{ end }} + + + + + + diff --git a/development/examples/example1/req1/1/.test1.md.swp b/development/examples/example1/req1/1/.test1.md.swp deleted file mode 100644 index fcb2c249530807b835475db75edcee1505ab2982..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 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 diff --git a/development/examples/example1/req1/1/test1.md b/development/examples/example1/req1/1/test1.md index a2b245f..b06ef96 100644 --- a/development/examples/example1/req1/1/test1.md +++ b/development/examples/example1/req1/1/test1.md @@ -44,7 +44,7 @@ Estimation: 13 # The time required for this requirement # Valid time units are “nsâ€, “us†(or “µsâ€), “msâ€, “sâ€, “mâ€, “hâ€. -Time Spent: 1h +Time Spent: 2h # who is the source of the demand Source: null @@ -52,7 +52,16 @@ Created: 2022-05-03 Last Update: null Issues: - - Gitlab-ID: 1 + - Gitlab: + ID: 1 + - Gitlab: + Title: Test 1 + Status: offen + Labels: + - a + - b + + # the individual items as a list Items: -- GitLab