blob: 95eedb84b17ad8beee53fd11ad2bd8088e2ca557 [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package base_profile
import (
"flag"
"fmt"
"v.io/jiri"
"v.io/jiri/profiles"
"v.io/jiri/profiles/profilesmanager"
"v.io/jiri/profiles/profilesreader"
"v.io/x/lib/envvar"
)
type versionSpec struct {
dependencies []struct{ name, version string }
}
func Register(installer, profile string) {
m := &Manager{
profileInstaller: installer,
profileName: profile,
qualifiedName: profiles.QualifiedProfileName(installer, profile),
versionInfo: profiles.NewVersionInfo(profile,
map[string]interface{}{
"1": &versionSpec{[]struct{ name, version string }{
{"go", ""},
{"syncbase", ""}},
},
"2": &versionSpec{[]struct{ name, version string }{
{"go", "1.5.1.1:2738c5e0"},
{"syncbase", ""}},
},
"3": &versionSpec{[]struct{ name, version string }{
{"go", "1.5.2"},
{"syncbase", ""}},
},
"4": &versionSpec{[]struct{ name, version string }{
{"go", "1.5.2.1:56093743"},
{"syncbase", ""}},
},
"5": &versionSpec{[]struct{ name, version string }{
{"go", "1.6"},
{"syncbase", ""}},
},
}, "5"),
}
profilesmanager.Register(m)
}
type Manager struct {
profileInstaller, profileName, qualifiedName string
versionInfo *profiles.VersionInfo
spec versionSpec
}
func (m Manager) Name() string {
return m.profileName
}
func (m Manager) Installer() string {
return m.profileInstaller
}
func (m Manager) String() string {
return fmt.Sprintf("%s[%s]", m.qualifiedName, m.versionInfo.Default())
}
func (m Manager) Info() string {
return `
The base profile is a convenient shorthand for installing the profiles that all
vanadium projects need, this is currently go and syncbase.`
}
func (m Manager) VersionInfo() *profiles.VersionInfo {
return m.versionInfo
}
func (m *Manager) AddFlags(flags *flag.FlagSet, action profiles.Action) {
}
func (m *Manager) OSPackages(jirix *jiri.X, pdb *profiles.DB, root jiri.RelPath, target profiles.Target) ([]string, error) {
if err := m.versionInfo.Lookup(target.Version(), &m.spec); err != nil {
return nil, err
}
var packages []string
if !target.CrossCompiling() && target.OS() == "linux" && (target.Version() == "1" || target.Version() == "2" || target.Version() == "3" || target.Version() == "4") {
// Version 5 onwards uses go 1.6+, where there is no need for "libssl-dev".
packages = []string{"libssl-dev"}
}
// Get packages from dependent profiles.
// TODO(nlacasse): Consider making the notion of "dependent profiles"
// something that jiri understands, and move this logic (and the similar
// logic in Install) into jiri.
for _, profile := range m.spec.dependencies {
qname := profiles.QualifiedProfileName(m.profileInstaller, profile.name)
depManager := profilesmanager.LookupManager(qname)
if depManager == nil {
return nil, fmt.Errorf("no manager found for dependent profile %v", profile.name)
}
depPackages, err := depManager.OSPackages(jirix, pdb, root, target)
if err != nil {
return nil, err
}
packages = append(packages, depPackages...)
}
return packages, nil
}
func (m *Manager) Install(jirix *jiri.X, pdb *profiles.DB, root jiri.RelPath, target profiles.Target) error {
if err := m.versionInfo.Lookup(target.Version(), &m.spec); err != nil {
return err
}
// Install profiles.
profileEnvs := [][]string{}
for _, profile := range m.spec.dependencies {
dependency := target
dependency.SetVersion(profile.version)
if err := profilesmanager.EnsureProfileTargetIsInstalled(jirix, pdb, m.profileInstaller, profile.name, root, dependency); err != nil {
return err
}
installed := pdb.LookupProfileTarget(m.profileInstaller, profile.name, dependency)
if installed == nil {
return fmt.Errorf("%s %s should have been installed, but apparently is not", profile.name, dependency)
}
profileEnvs = append(profileEnvs, installed.Env.Vars)
}
// Merge the environments for go and syncbase and store it in the base profile.
base := envvar.VarsFromSlice(target.Env.Vars)
base.Set("GOARCH", target.Arch())
// iOS specifically uses Darwin as its GOOS. Using "ios" aka target.OS() will make go cry.
os := target.OS()
if target.OS() == "ios" {
os = "darwin"
}
base.Set("GOOS", os)
// Slight modifications to ProfileMergePolicies: Want the values from
// the "go" profile we depend on to prevail.
mp := profilesreader.ProfileMergePolicies()
mp["GOROOT"] = profilesreader.UseLast
mp["GOROOT_BOOTSTRAP"] = profilesreader.IgnoreBaseUseLast
mp["CGO_ENABLED"] = profilesreader.IgnoreBaseUseLast
profilesreader.MergeEnv(mp, base, profileEnvs...)
target.Env.Vars = base.ToSlice()
pdb.InstallProfile(m.profileInstaller, m.profileName, string(root))
return pdb.AddProfileTarget(m.profileInstaller, m.profileName, target)
}
func (m *Manager) Uninstall(jirix *jiri.X, pdb *profiles.DB, root jiri.RelPath, target profiles.Target) error {
if err := m.versionInfo.Lookup(target.Version(), &m.spec); err != nil {
return err
}
for _, profile := range m.spec.dependencies {
dependency := target
dependency.SetVersion(profile.version)
if err := profilesmanager.EnsureProfileTargetIsUninstalled(jirix, pdb, m.profileInstaller, profile.name, root, dependency); err != nil {
return err
}
}
pdb.RemoveProfileTarget(m.profileInstaller, m.profileName, target)
return nil
}