blob: 109fa9f394bafe670a93908145c1660a9b4f337d [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 profiles implements support for managing external sofware dependencies.
// It offers a balance between providing no support at all and a full blown package
// manager. A profile is a named collection of software required for a given
// system component or application. The name of the profile refers to all of the
// required software, which may a single library or a collection of libraries or
// SDKs. Profiles thus refer to uncompiled source code that needs to be compiled
// for a specific "target". Targets represent compiled code and consist of:
//
// 1. An 'architecture' that refers to the CPU to be generate code for
// 2. An 'operating system' that refers to the operating system to generate
// code for.
// 3. An 'environment' which is a set of environment variables to use when
// compiling and using the profile.
//
// Targets provide the essential support for cross compilation.
//
// The profiles package provides a registry for profile implementations to
// register themselves (by calling profiles.Register from an init function
// for example) and for managing a 'manifest' of the currently built
// profiles. The manifest is represented as an XML file.
//
// Profiles may be installed, updated or removed. When doing so, the name of
// the profile is required, but the other components of the target are optional
// and will default to the values of the system that the commands are run on
// (so-called native builds). These operations are defined by the
// profiles.Manager interface.
//
// The manifest tracks the installed profiles and their configurations.
// Other command line tools and packages are expected read information about
// the currently installed profiles from this manifest via profiles.ConfigHelper.
package profiles
import (
"flag"
"sort"
"sync"
"v.io/jiri/jiri"
)
var (
registry = struct {
sync.Mutex
managers map[string]Manager
}{
managers: make(map[string]Manager),
}
)
// Register is used to register a profile manager. It is an error
// to call Registerr more than once with the same name, though it
// is possible to register the same Manager using different names.
func Register(name string, mgr Manager) {
registry.Lock()
defer registry.Unlock()
if _, present := registry.managers[name]; present {
panic("a profile manager is already registered for: " + name)
}
registry.managers[name] = mgr
}
// Managers returns the names, in lexicographic order, of all of the currently
// available profile managers.
func Managers() []string {
registry.Lock()
defer registry.Unlock()
names := make([]string, 0, len(registry.managers))
for name := range registry.managers {
names = append(names, name)
}
sort.Strings(names)
return names
}
// LookupManager returns the manager for the named profile or nil if one is
// not found.
func LookupManager(name string) Manager {
registry.Lock()
defer registry.Unlock()
return registry.managers[name]
}
type Action int
const (
Install Action = iota
Uninstall
)
// Manager is the interface that must be implemented in order to
// manage (i.e. install/uninstall/update) a profile.
type Manager interface {
// AddFlags allows the profile manager to add profile specific flags
// to the supplied FlagSet for the specified Action.
// They should be named <profile-name>.<flag>.
AddFlags(*flag.FlagSet, Action)
// Name returns the name of this profile.
Name() string
// Info returns an informative description of the profile.
Info() string
// VersionInfo returns the VersionInfo instance for this profile.
VersionInfo() *VersionInfo
// String returns a string representation of the profile, conventionally this
// is its name and version.
String() string
// Install installs the profile for the specified build target.
Install(jirix *jiri.X, root jiri.RelPath, 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(jirix *jiri.X, root jiri.RelPath, target Target) error
}