mirror of
https://github.com/turbot/steampipe.git
synced 2025-12-19 18:12:43 -05:00
115 lines
3.1 KiB
Go
115 lines
3.1 KiB
Go
package modconfig
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/hashicorp/hcl/v2"
|
|
"github.com/turbot/go-kit/helpers"
|
|
"github.com/turbot/steampipe/pkg/versionhelpers"
|
|
"github.com/zclconf/go-cty/cty"
|
|
)
|
|
|
|
const filePrefix = "file:"
|
|
|
|
type VersionConstrainCollection []*ModVersionConstraint
|
|
|
|
type ModVersionConstraint struct {
|
|
// the fully qualified mod name, e.g. github.com/turbot/mod1
|
|
Name string `cty:"name" hcl:"name,label"`
|
|
VersionString string `cty:"version" hcl:"version"`
|
|
// variable values to be set on the dependency mod
|
|
Args map[string]cty.Value `cty:"args" hcl:"args,optional"`
|
|
// only one of Constraint, Branch and FilePath will be set
|
|
Constraint *versionhelpers.Constraints
|
|
// the local file location to use
|
|
FilePath string
|
|
DeclRange hcl.Range
|
|
}
|
|
|
|
// NewModVersionConstraint creates a new ModVersionConstraint - this is called when installing a mod
|
|
func NewModVersionConstraint(modFullName string) (*ModVersionConstraint, error) {
|
|
m := &ModVersionConstraint{
|
|
Args: make(map[string]cty.Value),
|
|
}
|
|
|
|
// if name has `file:` prefix, just set the name and ignore version
|
|
if strings.HasPrefix(modFullName, filePrefix) {
|
|
m.Name = modFullName
|
|
} else {
|
|
// otherwise try to extract version from name
|
|
segments := strings.Split(modFullName, "@")
|
|
if len(segments) > 2 {
|
|
return nil, fmt.Errorf("invalid mod name %s", modFullName)
|
|
}
|
|
m.Name = segments[0]
|
|
if len(segments) == 2 {
|
|
m.VersionString = segments[1]
|
|
}
|
|
}
|
|
|
|
// try to convert version into a semver constraint
|
|
if err := m.Initialise(nil); err != nil {
|
|
return nil, err
|
|
}
|
|
return m, nil
|
|
}
|
|
|
|
// Initialise parses the version and name properties
|
|
func (m *ModVersionConstraint) Initialise(block *hcl.Block) hcl.Diagnostics {
|
|
if block != nil {
|
|
m.DeclRange = block.DefRange
|
|
}
|
|
|
|
if strings.HasPrefix(m.Name, filePrefix) {
|
|
m.setFilePath()
|
|
return nil
|
|
}
|
|
|
|
// now default the version string to latest
|
|
if m.VersionString == "" || m.VersionString == "latest" {
|
|
m.VersionString = "*"
|
|
}
|
|
|
|
// does the version parse as a semver version
|
|
if c, err := versionhelpers.NewConstraint(m.VersionString); err == nil {
|
|
// no error
|
|
m.Constraint = c
|
|
return nil
|
|
}
|
|
|
|
// so there was an error
|
|
return hcl.Diagnostics{&hcl.Diagnostic{
|
|
Severity: hcl.DiagError,
|
|
Summary: fmt.Sprintf("invalid mod version %s", m.VersionString),
|
|
Subject: &m.DeclRange,
|
|
}}
|
|
|
|
}
|
|
|
|
func (m *ModVersionConstraint) DependencyPath() string {
|
|
if m.HasVersion() {
|
|
return fmt.Sprintf("%s@%s", m.Name, m.VersionString)
|
|
}
|
|
return m.Name
|
|
}
|
|
|
|
// HasVersion returns whether the mod has a version specified, or is the latest
|
|
// if no version is specified, or the version is "latest", this is the latest version
|
|
func (m *ModVersionConstraint) HasVersion() bool {
|
|
return !helpers.StringSliceContains([]string{"", "latest", "*"}, m.VersionString)
|
|
}
|
|
|
|
func (m *ModVersionConstraint) String() string {
|
|
return m.DependencyPath()
|
|
}
|
|
|
|
func (m *ModVersionConstraint) setFilePath() {
|
|
m.FilePath = strings.TrimPrefix(m.FilePath, filePrefix)
|
|
}
|
|
|
|
func (m *ModVersionConstraint) Equals(other *ModVersionConstraint) bool {
|
|
// just check the hcl properties
|
|
return m.Name == other.Name && m.VersionString == other.VersionString
|
|
}
|