Skip to content

Commit

Permalink
Code cleanup and fix invalid context and configurations
Browse files Browse the repository at this point in the history
  • Loading branch information
soumeh01 authored Feb 22, 2023
1 parent e13797f commit 7c942e1
Show file tree
Hide file tree
Showing 4 changed files with 186 additions and 70 deletions.
41 changes: 21 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,26 +25,27 @@ Available Commands:
list List information

Flags:
-c, --clean Remove intermediate and output directories
--context string Input context name e.g. [project][.buildType][+targetType]
-d, --debug Enable debug messages
-g, --generator string Select build system generator (default "Ninja")
-h, --help Print usage
-i, --intdir string Set directory for intermediate files
-j, --jobs int Number of job slots for parallel execution
--load string Set policy for packs loading [latest|all|required]
-l, --log string Save output messages in a log file
-o, --outdir string Set directory for output binary files
-O, --output string Set directory for all output files
-p, --packs Download missing software packs with cpackget
-q, --quiet Suppress output messages except build invocations
-r, --rebuild Remove intermediate and output directories and rebuild
-s, --schema Validate project input file(s) against schema
-t, --target string Optional CMake target name
-u, --update string Generate *.cprj file for reproducing current build
--update-rte Update the RTE directory and files
-v, --verbose Enable verbose messages from toolchain builds
-V, --version Print version
-c, --clean Remove intermediate and output directories
--configuration string Input configuration name e.g. [.buildType][+targetType]
--context string Input context name e.g. project.buildType+targetType
-d, --debug Enable debug messages
-g, --generator string Select build system generator (default "Ninja")
-h, --help Print usage
-i, --intdir string Set directory for intermediate files
-j, --jobs int Number of job slots for parallel execution
--load string Set policy for packs loading [latest|all|required]
-l, --log string Save output messages in a log file
-o, --outdir string Set directory for output binary files
-O, --output string Set directory for all output files
-p, --packs Download missing software packs with cpackget
-q, --quiet Suppress output messages except build invocations
-r, --rebuild Remove intermediate and output directories and rebuild
-s, --schema Validate project input file(s) against schema
-t, --target string Optional CMake target name
-u, --update string Generate *.cprj file for reproducing current build
--update-rte Update the RTE directory and files
-v, --verbose Enable verbose messages from toolchain builds
-V, --version Print version

Use "cbuild [command] --help" for more information about a command.
```
29 changes: 21 additions & 8 deletions pkg/builder/csolution/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,21 @@ func (b CSolutionBuilder) getCsolutionPath() (path string, err error) {
return
}

func (b CSolutionBuilder) validateContext(allContexts []string) (err error) {
_, err = utils.ParseContext(b.Options.Context)
if err != nil {
return
}

if !utils.Contains(allContexts, b.Options.Context) {
sort.Strings(allContexts)
err = errors.New("specified context '" + b.Options.Context +
"' not found. One of the following contexts must be specified:\n" +
strings.Join(allContexts, "\n"))
}
return
}

func (b CSolutionBuilder) Build() (err error) {
_ = utils.UpdateEnvVars(b.InstallConfigs.BinPath, b.InstallConfigs.EtcPath)
csolutionBin, err := b.getCsolutionPath()
Expand All @@ -232,12 +247,7 @@ func (b CSolutionBuilder) Build() (err error) {

var selectedContexts []string
if b.Options.Context != "" {
// validate context
if !utils.Contains(allContexts, b.Options.Context) {
sort.Strings(allContexts)
err = errors.New("specified context '" + b.Options.Context +
"' not found. One of the following contexts must be specified:\n" +
strings.Join(allContexts, "\n"))
if err = b.validateContext(allContexts); err != nil {
return
}
selectedContexts = append(selectedContexts, b.Options.Context)
Expand Down Expand Up @@ -291,8 +301,11 @@ func (b CSolutionBuilder) Build() (err error) {
args = append(args, "--no-update-rte")
}
if b.Options.Configuration != "" {
configurationItem, _ := utils.ParseConfiguration(b.Options.Configuration)
contextQuery := "*" + b.Options.Configuration
configurationItem, err := utils.ParseConfiguration(b.Options.Configuration)
if err != nil {
return err
}
contextQuery := "*" + utils.CreateConfiguration(configurationItem)
if configurationItem.TargetType == "" {
contextQuery += "*"
}
Expand Down
115 changes: 80 additions & 35 deletions pkg/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,12 @@ func GetDefaultCmsisPackRoot() (root string) {
}

func ParseContext(context string) (item ContextItem, err error) {
parseError := errors.New("invalid context. Follow project.buildType+targetType symantic")

periodCount := strings.Count(context, ".")
plusCount := strings.Count(context, "+")
if context == "" || periodCount > 1 || plusCount > 1 {
err = errors.New("invalid context. Follow [project][.buildType][+targetType] symantic")
err = parseError
return
}

Expand All @@ -112,38 +114,35 @@ func ParseContext(context string) (item ContextItem, err error) {
targetIdx := strings.Index(context, "+")
buildIdx := strings.Index(context, ".")

if targetIdx == -1 && buildIdx == -1 {
// context with only projectName
projectName = context
} else if targetIdx != -1 && buildIdx == -1 {
// context with only projectName+targetType
projectName = context[:targetIdx]
targetType = context[targetIdx+1:]
} else if targetIdx == -1 && buildIdx != -1 {
// context with only projectName.buildType
projectName = context[:buildIdx]
buildType = context[buildIdx+1:]
if targetIdx == -1 || buildIdx == -1 {
err = parseError
return
}

// fully specified contexts
part := context[:targetIdx]
buildIdx = strings.Index(part, ".")

if buildIdx > -1 {
projectName = part[:buildIdx]
buildType = part[buildIdx+1:]
} else {
// fully specified contexts
part := context[:targetIdx]
buildIdx := strings.Index(part, ".")
projectName = part
}

if buildIdx > -1 {
projectName = part[:buildIdx]
buildType = part[buildIdx+1:]
} else {
projectName = part
}
part = context[targetIdx+1:]
buildIdx = strings.Index(part, ".")

part = context[targetIdx+1:]
buildIdx = strings.Index(part, ".")
if buildIdx > -1 {
targetType = part[:buildIdx]
buildType = part[buildIdx+1:]
} else {
targetType = part
}

if buildIdx > -1 {
targetType = part[:buildIdx]
buildType = part[buildIdx+1:]
} else {
targetType = part
}
if projectName == "" || buildType == "" || targetType == "" {
err = parseError
return
}

item.ProjectName = projectName
Expand All @@ -153,16 +152,62 @@ func ParseContext(context string) (item ContextItem, err error) {
}

func ParseConfiguration(configuration string) (item ConfigurationItem, err error) {
context, err := ParseContext(configuration)
if err != nil {
parseErr := errors.New("invalid context. Follow [.buildType][+targetType] symantic")
periodCount := strings.Count(configuration, ".")
plusCount := strings.Count(configuration, "+")
if configuration == "" || periodCount > 1 || plusCount > 1 {
err = parseErr
return
}

if context.ProjectName != "" {
return item, errors.New("invalid configuration")
var buildType, targetType string
targetIdx := strings.Index(configuration, "+")
buildIdx := strings.Index(configuration, ".")

if targetIdx == -1 && buildIdx == -1 {
err = parseErr
return
}

if !(targetIdx == 0 || buildIdx == 0) {
err = parseErr
return
}

if targetIdx == -1 {
// configuration contains only buildType
buildType = configuration[buildIdx+1:]
} else if buildIdx == -1 {
// configuration contains only targetType
targetType = configuration[targetIdx+1:]
} else {
// fully specified configuration
if buildIdx == 0 {
buildType = configuration[buildIdx+1 : targetIdx]
targetType = configuration[targetIdx+1:]
} else {
targetType = configuration[targetIdx+1 : buildIdx]
buildType = configuration[buildIdx+1:]
}
}

if buildType == "" && targetType == "" {
err = parseErr
return
}

item.BuildType = buildType
item.TargetType = targetType
return
}

func CreateConfiguration(configItem ConfigurationItem) (configuration string) {
if configItem.BuildType != "" {
configuration += "." + configItem.BuildType
}
if configItem.TargetType != "" {
configuration += "+" + configItem.TargetType
}
item.BuildType = context.BuildType
item.TargetType = context.TargetType
return
}

Expand Down
71 changes: 64 additions & 7 deletions pkg/utils/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,18 @@ func TestParseContext(t *testing.T) {
ExpectedContext ContextItem
}{
{"", true, ContextItem{}},
{".+", true, ContextItem{}},
{".Build+", true, ContextItem{}},
{".+Target", true, ContextItem{}},
{".Build.Build2+Target", true, ContextItem{}},
{".Build+Target+Test", true, ContextItem{}},
{"+Target", false, ContextItem{ProjectName: "", BuildType: "", TargetType: "Target"}},
{".Build", false, ContextItem{ProjectName: "", BuildType: "Build", TargetType: ""}},
{".Build+Target", false, ContextItem{ProjectName: "", BuildType: "Build", TargetType: "Target"}},
{"+Target.Build", false, ContextItem{ProjectName: "", BuildType: "Build", TargetType: "Target"}},
{"Project", false, ContextItem{ProjectName: "Project", BuildType: "", TargetType: ""}},
{"Project.Build", false, ContextItem{ProjectName: "Project", BuildType: "Build", TargetType: ""}},
{"Project+Target", false, ContextItem{ProjectName: "Project", BuildType: "", TargetType: "Target"}},
{"+Target", true, ContextItem{}},
{".Build", true, ContextItem{}},
{".Build+Target", true, ContextItem{}},
{"+Target.Build", true, ContextItem{}},
{"Project", true, ContextItem{}},
{"Project.Build", true, ContextItem{}},
{"Project+Target", true, ContextItem{}},
{"Project.Build+Target", false, ContextItem{ProjectName: "Project", BuildType: "Build", TargetType: "Target"}},
{"Project+Target.Build", false, ContextItem{ProjectName: "Project", BuildType: "Build", TargetType: "Target"}},
}
Expand All @@ -96,6 +99,60 @@ func TestParseContext(t *testing.T) {
}
}

func TestParseConfiguration(t *testing.T) {
assert := assert.New(t)

testCases := []struct {
Input string
ExpectError bool
ExpectedContext ConfigurationItem
}{
{"", true, ConfigurationItem{}},
{".+", true, ConfigurationItem{}},
{"Project", true, ConfigurationItem{}},
{".Build.Build2+Target", true, ConfigurationItem{}},
{".Build+Target+Test", true, ConfigurationItem{}},
{"Project.Build", true, ConfigurationItem{}},
{"Project+Target", true, ConfigurationItem{}},
{"Project.Build+Target", true, ConfigurationItem{}},
{"Project+Target.Build", true, ConfigurationItem{}},
{".+Target", false, ConfigurationItem{BuildType: "", TargetType: "Target"}},
{".Build+", false, ConfigurationItem{BuildType: "Build", TargetType: ""}},
{"+Target", false, ConfigurationItem{BuildType: "", TargetType: "Target"}},
{".Build", false, ConfigurationItem{BuildType: "Build", TargetType: ""}},
{".Build+Target", false, ConfigurationItem{BuildType: "Build", TargetType: "Target"}},
{"+Target.Build", false, ConfigurationItem{BuildType: "Build", TargetType: "Target"}},
}
for _, test := range testCases {
configItem, err := ParseConfiguration(test.Input)
if test.ExpectError {
assert.Error(err)
} else {
assert.Nil(err)
}
assert.Equal(configItem.BuildType, test.ExpectedContext.BuildType)
assert.Equal(configItem.TargetType, test.ExpectedContext.TargetType)
}
}

func TestCreateConfiguration(t *testing.T) {
assert := assert.New(t)

testCases := []struct {
Input ConfigurationItem
ExpectedOutput string
}{
{ConfigurationItem{}, ""},
{ConfigurationItem{BuildType: "Build", TargetType: "Target"}, ".Build+Target"},
{ConfigurationItem{BuildType: "", TargetType: "Target"}, "+Target"},
{ConfigurationItem{BuildType: "Build", TargetType: ""}, ".Build"},
}
for _, test := range testCases {
config := CreateConfiguration(test.Input)
assert.Equal(config, test.ExpectedOutput)
}
}

func TestGetSelectedContexts(t *testing.T) {
assert := assert.New(t)
var empty []string
Expand Down

0 comments on commit 7c942e1

Please sign in to comment.