Merge "v.io/jiri/profiles: prevent use of target Tags."
diff --git a/profiles/.api b/profiles/.api
index 4dee0b0..3e7f821 100644
--- a/profiles/.api
+++ b/profiles/.api
@@ -1,43 +1,61 @@
+pkg profiles, const Append MergeAction
+pkg profiles, const AppendJiriProfile AppendJiriProfileMode
pkg profiles, const DefaultDirPerm os.FileMode
pkg profiles, const DefaultFilePerm os.FileMode
+pkg profiles, const DoNotAppendJiriProfile bool
+pkg profiles, const First MergeAction
+pkg profiles, const Ignore MergeAction
+pkg profiles, const IgnoreBaseAndAppend MergeAction
+pkg profiles, const IgnoreBaseAndPrepend MergeAction
+pkg profiles, const IgnoreBaseAndUseFirst MergeAction
+pkg profiles, const IgnoreBaseAndUseLast MergeAction
+pkg profiles, const IgnoreProfiles MergeAction
pkg profiles, const Install Action
+pkg profiles, const Last MergeAction
pkg profiles, const Original Version
+pkg profiles, const Prepend MergeAction
pkg profiles, const SkipProfiles ProfilesMode
pkg profiles, const Uninstall Action
pkg profiles, const UseProfiles ProfilesMode
pkg profiles, const V2 Version
pkg profiles, const V3 Version
+pkg profiles, const V4 Version
pkg profiles, func AddProfileTarget(string, Target) error
pkg profiles, func AtomicAction(*tool.Context, func() error, string, string) error
-pkg profiles, func CommonConcatVariables() map[string]string
-pkg profiles, func CommonIgnoreVariables() map[string]bool
pkg profiles, func DefaultTarget() Target
-pkg profiles, func EnsureProfileTargetIsInstalled(*tool.Context, string, Target, string) error
-pkg profiles, func EnsureProfileTargetIsUninstalled(*tool.Context, string, Target, string) error
+pkg profiles, func EnsureProfileTargetIsInstalled(*tool.Context, string, RelativePath, Target) error
+pkg profiles, func EnsureProfileTargetIsUninstalled(*tool.Context, string, RelativePath, Target) error
+pkg profiles, func EnvFromProfile(Target, string) []string
+pkg profiles, func Fetch(*tool.Context, string, string) error
pkg profiles, func FindTarget(OrderedTargets, *Target) *Target
pkg profiles, func FindTargetByTag(OrderedTargets, *Target) *Target
pkg profiles, func FindTargetWithDefault(OrderedTargets, *Target) *Target
pkg profiles, func GitCloneRepo(*tool.Context, string, string, string, os.FileMode) error
pkg profiles, func GoEnvironmentFromOS() []string
+pkg profiles, func InitProfilesFromFlag(string, AppendJiriProfileMode) []string
pkg profiles, func InsertTarget(OrderedTargets, *Target) OrderedTargets
pkg profiles, func InstallPackages(*tool.Context, []string) error
pkg profiles, func InstallProfile(string, string)
+pkg profiles, func JiriMergePolicies() MergePolicies
pkg profiles, func LookupManager(string) Manager
pkg profiles, func LookupProfile(string) *Profile
pkg profiles, func LookupProfileTarget(string, Target) *Target
pkg profiles, func Managers() []string
-pkg profiles, func MergeEnv(map[string]string, map[string]bool, *envvar.Vars, ...[]string)
-pkg profiles, func MergeEnvFromProfiles(map[string]string, map[string]bool, *envvar.Vars, Target, ...string) ([]string, error)
+pkg profiles, func MergeEnv(map[string]MergePolicy, *envvar.Vars, ...[]string)
pkg profiles, func NativeTarget() Target
pkg profiles, func NewConfigHelper(*tool.Context, ProfilesMode, string) (*ConfigHelper, error)
+pkg profiles, func NewRelativePath(string, string) RelativePath
pkg profiles, func NewTarget(string) (Target, error)
pkg profiles, func NewTargetWithEnv(string, string) (Target, error)
pkg profiles, func NewVersionInfo(string, map[string]interface{}, string) *VersionInfo
+pkg profiles, func ProfileMergePolicies() MergePolicies
pkg profiles, func Profiles() []string
pkg profiles, func Read(*tool.Context, string) error
pkg profiles, func Register(string, Manager)
pkg profiles, func RegisterManifestFlag(*flag.FlagSet, *string, string)
-pkg profiles, func RegisterProfileFlags(*flag.FlagSet, *ProfilesMode, *string, *string, string, *Target)
+pkg profiles, func RegisterMergePoliciesFlag(*flag.FlagSet, *MergePolicies)
+pkg profiles, func RegisterProfileFlags(*flag.FlagSet, *ProfilesMode, *string, *string, string, *MergePolicies, *Target)
+pkg profiles, func RegisterProfilesFlag(*flag.FlagSet, *string)
pkg profiles, func RegisterTargetAndEnvFlags(*flag.FlagSet, *Target)
pkg profiles, func RegisterTargetFlag(*flag.FlagSet, *Target)
pkg profiles, func RemoveProfileTarget(string, Target) bool
@@ -46,25 +64,31 @@
pkg profiles, func SchemaVersion() Version
pkg profiles, func UnsetGoEnvMap(map[string]string)
pkg profiles, func UnsetGoEnvVars(*envvar.Vars)
+pkg profiles, func Unzip(*tool.Context, string, string) error
pkg profiles, func UpdateProfileTarget(string, Target) error
+pkg profiles, func WithDefaultVersion(Target) Target
pkg profiles, func Write(*tool.Context, string) error
+pkg profiles, method (*ConfigHelper) GoPath() string
+pkg profiles, method (*ConfigHelper) JiriProfile() []string
pkg profiles, method (*ConfigHelper) LegacyProfiles() bool
+pkg profiles, method (*ConfigHelper) MergeEnv(map[string]MergePolicy, ...[]string)
+pkg profiles, method (*ConfigHelper) MergeEnvFromProfiles(map[string]MergePolicy, Target, ...string)
pkg profiles, method (*ConfigHelper) PrependToPATH(string)
pkg profiles, method (*ConfigHelper) Root() string
-pkg profiles, method (*ConfigHelper) SetEnvFromProfiles(map[string]string, map[string]bool, string, Target)
-pkg profiles, method (*ConfigHelper) SetGoPath()
-pkg profiles, method (*ConfigHelper) SetVDLPath()
pkg profiles, method (*ConfigHelper) SkippingProfiles() bool
+pkg profiles, method (*ConfigHelper) VDLPath() string
pkg profiles, method (*ConfigHelper) ValidateRequestedProfilesAndTarget([]string, Target) error
pkg profiles, method (*Environment) Get() interface{}
pkg profiles, method (*Environment) Set(string) error
pkg profiles, method (*Environment) String() string
pkg profiles, method (*Environment) Usage() string
+pkg profiles, method (*MergePolicy) String() string
pkg profiles, method (*Profile) Targets() OrderedTargets
pkg profiles, method (*ProfilesMode) Get() interface{}
pkg profiles, method (*ProfilesMode) IsBoolFlag() bool
pkg profiles, method (*ProfilesMode) Set(string) error
pkg profiles, method (*ProfilesMode) String() string
+pkg profiles, method (*RelativePath) String() string
pkg profiles, method (*Target) Arch() string
pkg profiles, method (*Target) Less(*Target) bool
pkg profiles, method (*Target) OS() string
@@ -73,6 +97,7 @@
pkg profiles, method (*Target) Tag() string
pkg profiles, method (*Target) TargetSpecificDirname() string
pkg profiles, method (*Target) Usage() string
+pkg profiles, method (*Target) UseCommandLineEnv()
pkg profiles, method (*Target) Version() string
pkg profiles, method (*VersionInfo) Default() string
pkg profiles, method (*VersionInfo) IsNewerThanDefault(string) bool
@@ -81,10 +106,20 @@
pkg profiles, method (*VersionInfo) Select(string) (string, error)
pkg profiles, method (*VersionInfo) String() string
pkg profiles, method (*VersionInfo) Supported() []string
+pkg profiles, method (MergePolicies) DebugString() string
+pkg profiles, method (MergePolicies) Get() interface{}
+pkg profiles, method (MergePolicies) Set(string) error
+pkg profiles, method (MergePolicies) String() string
+pkg profiles, method (MergePolicies) Usage() string
pkg profiles, method (OrderedTargets) Len() int
pkg profiles, method (OrderedTargets) Less(int, int) bool
pkg profiles, method (OrderedTargets) Sort()
pkg profiles, method (OrderedTargets) Swap(int, int)
+pkg profiles, method (RelativePath) Expand() string
+pkg profiles, method (RelativePath) ExpandEnv(*envvar.Vars)
+pkg profiles, method (RelativePath) Join(...string) RelativePath
+pkg profiles, method (RelativePath) RelativePath() string
+pkg profiles, method (RelativePath) RootJoin(...string) RelativePath
pkg profiles, method (Target) CommandLineEnv() Environment
pkg profiles, method (Target) CrossCompiling() bool
pkg profiles, method (Target) DebugString() string
@@ -93,29 +128,48 @@
pkg profiles, method (Target) Match(*Target) bool
pkg profiles, method (Target) String() string
pkg profiles, type Action int
+pkg profiles, type AppendJiriProfileMode bool
pkg profiles, type ConfigHelper struct
pkg profiles, type ConfigHelper struct, embedded *envvar.Vars
pkg profiles, type Environment struct
pkg profiles, type Environment struct, Vars []string
-pkg profiles, type Manager interface { AddFlags, Info, Install, Name, Root, SetRoot, String, Uninstall, VersionInfo }
+pkg profiles, type Manager interface { AddFlags, Info, Install, Name, String, Uninstall, VersionInfo }
pkg profiles, type Manager interface, AddFlags(*flag.FlagSet, Action)
pkg profiles, type Manager interface, Info() string
-pkg profiles, type Manager interface, Install(*tool.Context, Target) error
+pkg profiles, type Manager interface, Install(*tool.Context, RelativePath, Target) error
pkg profiles, type Manager interface, Name() string
-pkg profiles, type Manager interface, Root() string
-pkg profiles, type Manager interface, SetRoot(string)
pkg profiles, type Manager interface, String() string
-pkg profiles, type Manager interface, Uninstall(*tool.Context, Target) error
+pkg profiles, type Manager interface, Uninstall(*tool.Context, RelativePath, Target) error
pkg profiles, type Manager interface, VersionInfo() *VersionInfo
+pkg profiles, type MergeAction int
+pkg profiles, type MergePolicies map[string]MergePolicy
+pkg profiles, type MergePolicy struct
+pkg profiles, type MergePolicy struct, Action MergeAction
+pkg profiles, type MergePolicy struct, Separator string
pkg profiles, type OrderedTargets []*Target
pkg profiles, type Profile struct
pkg profiles, type Profile struct, Name string
pkg profiles, type Profile struct, Root string
pkg profiles, type ProfilesMode bool
+pkg profiles, type RelativePath struct
pkg profiles, type Target struct
pkg profiles, type Target struct, Env Environment
pkg profiles, type Target struct, InstallationDir string
pkg profiles, type Target struct, UpdateTime time.Time
pkg profiles, type Version int
pkg profiles, type VersionInfo struct
+pkg profiles, var AppendFlag MergePolicy
+pkg profiles, var AppendPath MergePolicy
pkg profiles, var GoFlags []string
+pkg profiles, var IgnoreBaseAppendFlag MergePolicy
+pkg profiles, var IgnoreBaseAppendPath MergePolicy
+pkg profiles, var IgnoreBasePrependFlag MergePolicy
+pkg profiles, var IgnoreBasePrependPath MergePolicy
+pkg profiles, var IgnoreBaseUseFirst MergePolicy
+pkg profiles, var IgnoreBaseUseLast MergePolicy
+pkg profiles, var IgnoreVariable MergePolicy
+pkg profiles, var PrependFlag MergePolicy
+pkg profiles, var PrependPath MergePolicy
+pkg profiles, var UseBaseIgnoreProfiles MergePolicy
+pkg profiles, var UseFirst MergePolicy
+pkg profiles, var UseLast MergePolicy
diff --git a/profiles/commandline/driver.go b/profiles/commandline/driver.go
index 1b26baf..5f27d52 100644
--- a/profiles/commandline/driver.go
+++ b/profiles/commandline/driver.go
@@ -12,6 +12,7 @@
"bytes"
"flag"
"fmt"
+ "path/filepath"
"strings"
"text/template"
@@ -111,6 +112,7 @@
}
var (
+ rootPath profiles.RelativePath
targetFlag profiles.Target
manifestFlag string
showManifestFlag bool
@@ -123,6 +125,7 @@
mergePoliciesFlag profiles.MergePolicies
specificVersionsFlag bool
cleanupFlag bool
+ rmAllFlag bool
)
func Main(name string) {
@@ -140,6 +143,8 @@
panic(err)
}
+ rootPath = profiles.NewRelativePath("JIRI_ROOT", rootDir).Join("profiles")
+
// Every sub-command accepts: --manifest
for _, fs := range []*flag.FlagSet{
&cmdInstall.Flags,
@@ -191,6 +196,7 @@
// cleanup accepts the following flags:
cmdCleanup.Flags.BoolVar(&cleanupFlag, "gc", false, "uninstall profile targets that are older than the current default")
cmdCleanup.Flags.BoolVar(&specificVersionsFlag, "ensure-specific-versions-are-set", false, "ensure that profile targets have a specific version set")
+ cmdCleanup.Flags.BoolVar(&rmAllFlag, "rm-all", false, "remove profile manifest and all profile generated output files.")
}
func runList(env *cmdline.Env, args []string) error {
@@ -329,6 +335,14 @@
return out.String()
}
+func handleRelativePath(root profiles.RelativePath, s string) string {
+ // Handle the transition from absolute to relative paths.
+ if filepath.IsAbs(s) {
+ return s
+ }
+ return root.RootJoin(s).Expand()
+}
+
func fmtInfo(ctx *tool.Context, mgr profiles.Manager, profile *profiles.Profile, target *profiles.Target) (string, error) {
if len(infoFlag) > 0 {
// Populate an instance listInfo
@@ -348,7 +362,7 @@
}
info.SchemaVersion = profiles.SchemaVersion()
if target != nil {
- info.Target.InstallationDir = target.InstallationDir
+ info.Target.InstallationDir = handleRelativePath(rootPath, target.InstallationDir)
info.Target.CommandLineEnv = target.CommandLineEnv().Vars
info.Target.Env = target.Env.Vars
clenv := ""
@@ -358,7 +372,7 @@
info.Target.Command = fmt.Sprintf("jiri v23-profile install --target=%s %s%s", target, clenv, name)
}
if profile != nil {
- info.Profile.Root = profile.Root
+ info.Profile.Root = handleRelativePath(rootPath, profile.Root)
}
// Use a template to print out any field in our instance of listInfo.
@@ -454,14 +468,13 @@
continue
}
vi := mgr.VersionInfo()
- mgr.SetRoot(rootDir)
for _, target := range profile.Targets() {
if vi.IsNewerThanDefault(target.Version()) {
if verboseFlag {
fmt.Fprintf(ctx.Stdout(), "Updating %s %s from %q to %s\n", n, target, target.Version(), vi)
}
target.SetVersion(vi.Default())
- err := mgr.Install(ctx, *target)
+ err := mgr.Install(ctx, rootPath, *target)
logResult(ctx, "Update", mgr, *target, err)
if err != nil {
return err
@@ -483,7 +496,7 @@
profile := profiles.LookupProfile(n)
for _, target := range profile.Targets() {
if vi.IsOlderThanDefault(target.Version()) {
- err := mgr.Uninstall(ctx, *target)
+ err := mgr.Uninstall(ctx, rootPath, *target)
logResult(ctx, "gc", mgr, *target, err)
if err != nil {
return err
@@ -519,6 +532,16 @@
return nil
}
+func runRmAll(ctx *tool.Context) error {
+ if err := ctx.Run().Remove(manifestFlag); err != nil {
+ return err
+ }
+ if err := ctx.Run().RemoveAll(rootPath.Expand()); err != nil {
+ return err
+ }
+ return nil
+}
+
func runCleanup(env *cmdline.Env, args []string) error {
ctx := tool.NewContextFromEnv(env)
if err := profiles.Read(ctx, manifestFlag); err != nil {
@@ -547,6 +570,16 @@
}
dirty = true
}
+ if rmAllFlag {
+ if verboseFlag {
+ fmt.Fprintf(ctx.Stdout(), "Removing profile manifest and all profile output files\n")
+ }
+ if err := runRmAll(ctx); err != nil {
+ return err
+ }
+ // Don't write out the profiles manifest file again.
+ return nil
+ }
if !dirty {
return fmt.Errorf("at least one option must be specified")
}
@@ -570,7 +603,6 @@
return err
}
target.SetVersion(version)
- mgr.SetRoot(rootDir)
if err := fn(mgr, ctx, target); err != nil {
return err
}
@@ -599,7 +631,7 @@
}
if err := applyCommand(names, env, ctx, targetFlag,
func(mgr profiles.Manager, ctx *tool.Context, target profiles.Target) error {
- err := mgr.Install(ctx, target)
+ err := mgr.Install(ctx, rootPath, target)
logResult(ctx, "Install:", mgr, target, err)
return err
}); err != nil {
@@ -623,9 +655,8 @@
if profile == nil || mgr == nil {
continue
}
- mgr.SetRoot(rootDir)
for _, target := range profile.Targets() {
- if err := mgr.Uninstall(ctx, *target); err != nil {
+ if err := mgr.Uninstall(ctx, rootPath, *target); err != nil {
logResult(ctx, "Uninstall", mgr, *target, err)
return err
}
@@ -635,7 +666,7 @@
} else {
applyCommand(args, env, ctx, targetFlag,
func(mgr profiles.Manager, ctx *tool.Context, target profiles.Target) error {
- err := mgr.Uninstall(ctx, target)
+ err := mgr.Uninstall(ctx, rootPath, target)
logResult(ctx, "Uninstall", mgr, target, err)
return err
})
diff --git a/profiles/env.go b/profiles/env.go
index b848d57..0d1bacb 100644
--- a/profiles/env.go
+++ b/profiles/env.go
@@ -174,7 +174,8 @@
// MergeEnvFromProfiles merges the embedded environment with the environment
// variables stored in the requested profiles. The profiles are those read from
// the manifest and in addition the 'jiri' profile may be used which refers to
-// the environment variables maintained by the jiri tool itself.
+// the environment variables maintained by the jiri tool itself. It will also
+// expand all instances of ${JIRI_ROOT} in the returned environment.
func (ch *ConfigHelper) MergeEnvFromProfiles(policies map[string]MergePolicy, target Target, profileNames ...string) {
if ch.legacyMode {
return
@@ -193,6 +194,8 @@
envs = append(envs, e)
}
MergeEnv(policies, ch.Vars, envs...)
+ rp := NewRelativePath("JIRI_ROOT", ch.root)
+ rp.ExpandEnv(ch.Vars)
}
// SkippingProfiles returns true if no profiles are being used.
diff --git a/profiles/manager.go b/profiles/manager.go
index ba40ecd..5314174 100644
--- a/profiles/manager.go
+++ b/profiles/manager.go
@@ -38,10 +38,13 @@
import (
"flag"
+ "path/filepath"
"sort"
+ "strings"
"sync"
"v.io/jiri/tool"
+ "v.io/x/lib/envvar"
)
var (
@@ -86,6 +89,72 @@
return registry.managers[name]
}
+// RelativePath represents a relative path whose root is specified
+// by an environment variable, eg. ${JIRI_ROOT}/profiles/go. It provides
+// access to the 'expanded' value of this variable along with any
+// path components appended to it.
+type RelativePath struct {
+ name string
+ value string
+ path string
+}
+
+// NewRelativePath creates a new instance of RelativePath with
+// the variable name as its root and value as the value of the variable.
+func NewRelativePath(name, value string) RelativePath {
+ return RelativePath{name: name, value: value}
+}
+
+// Join returns a copy of RelativePath with the specified components
+// appended to it using filepath.Join.
+func (rp RelativePath) Join(components ...string) RelativePath {
+ nrp := rp
+ nrp.path = filepath.Join(append([]string{nrp.path}, components...)...)
+ return nrp
+}
+
+// RootJoin creates a new RelativePath that has the same variable
+// and associated value as its receiver and then appends components to it
+// using filepath.Join.
+func (rp RelativePath) RootJoin(components ...string) RelativePath {
+ nrp := RelativePath{name: rp.name, value: rp.value}
+ nrp.path = filepath.Join(append([]string{nrp.path}, components...)...)
+ return nrp
+}
+
+// Expand returns the path with the root variable expanded.
+func (rp RelativePath) Expand() string {
+ return filepath.Join(rp.value, rp.path)
+}
+
+// String returns the RelativePath with the root variable name as the
+// root - i.e. ${name}[/<any append components>].
+func (rp *RelativePath) String() string {
+ root := "${" + rp.name + "}"
+ if len(rp.path) == 0 {
+ return root
+ }
+ return root + string(filepath.Separator) + rp.path
+}
+
+// RelativePath returns just the relative path component of RelativePath.
+func (rp RelativePath) RelativePath() string {
+ return rp.path
+}
+
+// ExpandEnv expands all instances of the root variable in the supplied
+// environment.
+func (rp RelativePath) ExpandEnv(env *envvar.Vars) {
+ e := env.ToMap()
+ root := "${" + rp.name + "}"
+ for k, v := range e {
+ n := strings.Replace(v, root, rp.value, -1)
+ if n != v {
+ env.Set(k, n)
+ }
+ }
+}
+
type Action int
const (
@@ -100,11 +169,6 @@
// to the supplied FlagSet for the specified Action.
// They should be named <profile-name>.<flag>.
AddFlags(*flag.FlagSet, Action)
- // SetRoot sets the top level directory for the installation. It must be
- // called once and before Install/Uninstall/Update are called.
- SetRoot(dir string)
- // Root returns the top level directory for the installation.
- Root() string
// Name returns the name of this profile.
Name() string
// Info returns an informative description of the profile.
@@ -115,9 +179,9 @@
// is its name and version.
String() string
// Install installs the profile for the specified build target.
- Install(ctx *tool.Context, target Target) error
+ Install(ctx *tool.Context, root RelativePath, target Target) error
// Uninstall uninstalls the profile for the specified build target. When
// the last target for any given profile is uninstalled, then the profile
// itself (i.e. the source code) will be uninstalled.
- Uninstall(ctx *tool.Context, target Target) error
+ Uninstall(ctx *tool.Context, root RelativePath, target Target) error
}
diff --git a/profiles/manager_test.go b/profiles/manager_test.go
index f7ec878..400fe7e 100644
--- a/profiles/manager_test.go
+++ b/profiles/manager_test.go
@@ -9,11 +9,39 @@
"fmt"
"os"
"path/filepath"
+ "testing"
"v.io/jiri/profiles"
"v.io/jiri/tool"
)
+func TestRelativePath(t *testing.T) {
+ rp := profiles.NewRelativePath("VAR", "var")
+ if got, want := rp.Expand(), "var"; got != want {
+ t.Errorf("got %v, want %v", got, want)
+ }
+ if got, want := rp.String(), "${VAR}"; got != want {
+ t.Errorf("got %v, want %v", got, want)
+ }
+ rp = rp.Join("a", "b")
+ if got, want := rp.Expand(), filepath.Join("var", "a", "b"); got != want {
+ t.Errorf("got %v, want %v", got, want)
+ }
+ if got, want := rp.String(), "${VAR}"+string(filepath.Separator)+filepath.Join("a", "b"); got != want {
+ t.Errorf("got %v, want %v", got, want)
+ }
+ rp = rp.Join("x")
+ if got, want := rp.RootJoin("a").Expand(), filepath.Join("var", "a"); got != want {
+ t.Errorf("got %v, want %v", got, want)
+ }
+ if got, want := rp.Join("y").Expand(), filepath.Join("var", "a", "b", "x", "y"); got != want {
+ t.Errorf("got %v, want %v", got, want)
+ }
+ if got, want := rp.RelativePath(), filepath.Join("a", "b", "x"); got != want {
+ t.Errorf("got %v, want %v", got, want)
+ }
+}
+
type myNewProfile struct {
name, root, status string
versionInfo *profiles.VersionInfo
@@ -32,14 +60,6 @@
return p.name
}
-func (p *myNewProfile) SetRoot(root string) {
- p.root = root
-}
-
-func (p *myNewProfile) Root() string {
- return p.root
-}
-
func (p *myNewProfile) Info() string {
return `
The myNewProfile is for testing purposes only
@@ -61,13 +81,13 @@
func (p *myNewProfile) AddFlags(*flag.FlagSet, profiles.Action) {
}
-func (p *myNewProfile) Install(ctx *tool.Context, target profiles.Target) error {
+func (p *myNewProfile) Install(ctx *tool.Context, root profiles.RelativePath, target profiles.Target) error {
p.status = "installed"
profiles.AddProfileTarget(p.name, target)
return nil
}
-func (p *myNewProfile) Uninstall(ctx *tool.Context, target profiles.Target) error {
+func (p *myNewProfile) Uninstall(ctx *tool.Context, root profiles.RelativePath, target profiles.Target) error {
profiles.RemoveProfileTarget(p.name, target)
if profiles.LookupProfile(p.name) == nil {
p.status = "uninstalled"
@@ -87,6 +107,7 @@
}
init()
+ rootPath := profiles.NewRelativePath("JIRI_ROOT", ".").Join("profiles")
mgr := profiles.LookupManager(myProfile)
if mgr == nil {
panic("manager not found for: " + myProfile)
@@ -94,7 +115,7 @@
ctx := tool.NewDefaultContext()
// Install myNewProfile for target.
- if err := mgr.Install(ctx, target); err != nil {
+ if err := mgr.Install(ctx, rootPath, target); err != nil {
panic("failed to find manager for: " + myProfile)
}
@@ -120,7 +141,7 @@
}
fmt.Println(mgr.String())
- mgr.Uninstall(ctx, target)
+ mgr.Uninstall(ctx, rootPath, target)
fmt.Println(mgr.String())
fmt.Println(mgr.VersionInfo().Supported())
fmt.Println(mgr.VersionInfo().Default())
diff --git a/profiles/manifest.go b/profiles/manifest.go
index 4c54ce1..91f798c 100644
--- a/profiles/manifest.go
+++ b/profiles/manifest.go
@@ -22,9 +22,14 @@
type Version int
const (
+ // Original, old-style profiles without a version #
Original Version = 0
- V2 Version = 2
- V3 Version = 3
+ // First version of new-style profiles.
+ V2 Version = 2
+ // V3 added support for recording the options that were used to install profiles.
+ V3 Version = 3
+ // V4 adds support for relative path names in profiles and environment variables.
+ V4 Version = 4
)
// Profile represents a suite of software that is managed by an implementation
diff --git a/profiles/util.go b/profiles/util.go
index 2ce3e91..248fdba 100644
--- a/profiles/util.go
+++ b/profiles/util.go
@@ -18,7 +18,7 @@
"v.io/jiri/collect"
"v.io/jiri/project"
- "v.io/jiri/runutil"
+ "v.io/jiri/runutil"
"v.io/jiri/tool"
)
@@ -106,7 +106,9 @@
if !ctx.Run().FileExists(completionLogPath) {
ctx.Run().RemoveAll(dir)
} else {
- fmt.Fprintf(ctx.Stdout(), "AtomicAction: %s already completed in %s\n", message, dir)
+ if ctx.Verbose() {
+ fmt.Fprintf(ctx.Stdout(), "AtomicAction: %s already completed in %s\n", message, dir)
+ }
return nil
}
}
@@ -209,12 +211,22 @@
return ctx.Run().Function(installDepsFn, "Install dependencies")
}
-// EnsureProfileTargetIsInstalled ensures that the requested profile and target
-// is installed, installing it if only if necessary.
-func EnsureProfileTargetIsInstalled(ctx *tool.Context, profile string, target Target, root string) error {
+// ensureAction ensures that the requested profile and target
+// is installed/uninstalled, installing/uninstalling it if only if necessary.
+func ensureAction(ctx *tool.Context, action Action, profile string, root RelativePath, target Target) error {
+ verb := ""
+ switch action {
+ case Install:
+ verb = "install"
+ case Uninstall:
+ verb = "uninstall"
+ default:
+ return fmt.Errorf("unrecognised action %v", action)
+ }
+
if t := LookupProfileTarget(profile, target); t != nil {
if ctx.Run().Opts().Verbose {
- fmt.Fprintf(ctx.Stdout(), "%v %v is already installed as %v\n", profile, target, t)
+ fmt.Fprintf(ctx.Stdout(), "%v %v is already %sed as %v\n", profile, target, verb, t)
}
return nil
}
@@ -227,42 +239,25 @@
return err
}
target.SetVersion(version)
- mgr.SetRoot(root)
if ctx.Run().Opts().Verbose || ctx.Run().Opts().DryRun {
- fmt.Fprintf(ctx.Stdout(), "install %s %s\n", profile, target.DebugString())
+ fmt.Fprintf(ctx.Stdout(), "%s %s %s\n", verb, profile, target.DebugString())
}
- if err := mgr.Install(ctx, target); err != nil {
- return err
+ if action == Install {
+ return mgr.Install(ctx, root, target)
}
- return nil
+ return mgr.Uninstall(ctx, root, target)
+}
+
+// EnsureProfileTargetIsInstalled ensures that the requested profile and target
+// is installed, installing it if only if necessary.
+func EnsureProfileTargetIsInstalled(ctx *tool.Context, profile string, root RelativePath, target Target) error {
+ return ensureAction(ctx, Install, profile, root, target)
}
// EnsureProfileTargetIsUninstalled ensures that the requested profile and target
// are no longer installed.
-func EnsureProfileTargetIsUninstalled(ctx *tool.Context, profile string, target Target, root string) error {
- if LookupProfileTarget(profile, target) != nil {
- if ctx.Run().Opts().Verbose {
- fmt.Fprintf(ctx.Stdout(), "%v is not installed: %v", profile, target)
- }
- return nil
- }
- mgr := LookupManager(profile)
- if mgr == nil {
- return fmt.Errorf("profile %v is not supported", profile)
- }
- version, err := mgr.VersionInfo().Select(target.Version())
- if err != nil {
- return err
- }
- target.SetVersion(version)
- mgr.SetRoot(root)
- if ctx.Run().Opts().Verbose || ctx.Run().Opts().DryRun {
- fmt.Fprintf(ctx.Stdout(), "uninstall %s %s\n", profile, target.DebugString())
- }
- if err := mgr.Uninstall(ctx, target); err != nil {
- return err
- }
- return nil
+func EnsureProfileTargetIsUninstalled(ctx *tool.Context, profile string, root RelativePath, target Target) error {
+ return ensureAction(ctx, Uninstall, profile, root, target)
}
// Fetch downloads the specified url and saves it to dst.