v.io/jiri@v0.0.0-20160715023856-abfb8b131290/profiles/profiles.go (about) 1 // Copyright 2015 The Vanadium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package profiles and its subdirectoris implement support for managing external 6 // sofware dependencies. They offer a balance between providing no support at 7 // all and a full blown package manager. A profile is a named collection of 8 // software required for a given system component or application. The name of 9 // the profile refers to all of the required software, which may a single 10 // library or a collection of libraries or SDKs. Profiles thus refer to 11 // uncompiled source code that needs to be compiled for a specific "target". 12 // Targets represent compiled code and consist of: 13 // 14 // 1. An 'architecture' that refers to the CPU to be generate code for. 15 // 16 // 2. An 'operating system' that refers to the operating system to generate 17 // code for. 18 // 19 // 3. An 'environment' which is a set of environment variables to use when 20 // compiling and using the profile. 21 // 22 // Targets provide the essential support for cross compilation. 23 // 24 // The profiles package provides the data types to support its sub-packages, 25 // including a database format (in XML) that is used to store the state of 26 // the currently installed profiles. 27 // 28 // The profilesmanager sub-package provides a registry for profile 29 // implementations to register themselves (by calling manager.Register 30 // from an init function for example). 31 // 32 // The profilesreader sub-package provides support for reading the profiles 33 // database and performing common operations on it. 34 // profiles/commandline provides an easy to use command line environment for 35 // tools that need to read and/or write profiles. 36 // 37 // The profilescmdline sub-package provides support for implementing 38 // command line clients that implement profile installation and for 39 // reading profile information. It also provides support for invoking 40 // sub-commands to manage families of profiles which uses the notion 41 // of a 'qualified' profile name where the profile name includes a prefix 42 // (separated by InstallSeparator) which identifies the sub-command responsible 43 // for managing that profile. 44 // 45 // The profilesutil sub-package provides some utility routines intended 46 // for use by profile implementers. 47 // 48 // Profiles may be installed, updated or removed. When doing so, the name of 49 // the profile is required, but the other components of the target are optional 50 // and will default to the values of the system that the commands are run on 51 // (so-called native builds). These operations are defined by the 52 // profiles/manager.Manager interface. 53 package profiles 54 55 import ( 56 "flag" 57 "strings" 58 59 "v.io/jiri" 60 ) 61 62 // InstallerSeparator is the string used to separate the installer 63 // and profile name for qualified profile names. 64 const InstallerSeparator = ":" 65 66 // Profile represents an installed profile and its associated targets. 67 type Profile struct { 68 name, root, installer string 69 targets Targets 70 } 71 72 func clean(n string) string { 73 return strings.TrimRight(strings.TrimLeft(n, InstallerSeparator), InstallerSeparator) 74 } 75 76 // SplitProfileName returns the installer and profile name in the 77 // case where the name is qualified (see QualifiedProfileName) or just 78 // the profile name if it is not so qualified. 79 func SplitProfileName(name string) (string, string) { 80 if pos := strings.Index(name, InstallerSeparator); pos >= 0 { 81 return name[:pos], name[pos+len(InstallerSeparator):] 82 } 83 return "", name 84 } 85 86 // QualifiedProfileName returns the name of a profile qualified by 87 // the name of its installer, if any. If the installer is "myproject" 88 // and the profile name is "bar" then then returned string is 89 // "myproject" + InstallerSeparator + "bar". If the installer is not 90 // specified then the unqualified name, without InstallerSeparator is returned. 91 // If the supplied name is already qualified then the existing qualifier 92 // will be removed and the supplied one used instead. 93 // Any leading colons in name will be stripped. 94 func QualifiedProfileName(installer, name string) string { 95 name = clean(name) 96 installer = clean(installer) 97 if installer != "" { 98 // Strip any existing installer. 99 _, n := SplitProfileName(name) 100 return installer + InstallerSeparator + n 101 } 102 return name 103 } 104 105 // Name returns the qualified name of this profile. 106 func (p *Profile) Name() string { 107 return QualifiedProfileName(p.installer, p.name) 108 } 109 110 // Root returns the directory, relative to the jiri root, that this 111 // profile is installed at. 112 func (p *Profile) Root() string { 113 return p.root 114 } 115 116 // Targets returns the currently installed set of targets for this profile. 117 // Note that Targets is ordered by architecture, operating system and 118 // descending versions. 119 func (p *Profile) Targets() Targets { 120 r := make(Targets, len(p.targets), len(p.targets)) 121 for i, t := range p.targets { 122 tmp := *t 123 r[i] = &tmp 124 } 125 return r 126 } 127 128 type Action int 129 130 const ( 131 Install Action = iota 132 Uninstall 133 ) 134 135 // Manager is the interface that must be implemented in order to 136 // manage (i.e. install/uninstall) and describe a profile. 137 type Manager interface { 138 // Name returns the unqualified name of this profile. 139 Name() string 140 141 // Installer returns the installer for this profile. 142 Installer() string 143 144 // Info returns an informative description of the profile. 145 Info() string 146 147 // VersionInfo returns the VersionInfo instance for this profile. 148 VersionInfo() *VersionInfo 149 150 // String returns a string representation of the profile, conventionally 151 // this is its qualified name and version. 152 String() string 153 154 // AddFlags allows the profile manager to add profile specific flags 155 // to the supplied FlagSet for the specified Action. 156 // They should be named <profile-name>.<flag>. 157 AddFlags(*flag.FlagSet, Action) 158 159 // OSPackages returns the set of operating system packages required by the 160 // specified profile and target. 161 OSPackages(jirix *jiri.X, pdb *DB, root jiri.RelPath, target Target) ([]string, error) 162 163 // Install installs the profile for the specified build target. 164 Install(jirix *jiri.X, pdb *DB, root jiri.RelPath, target Target) error 165 166 // Uninstall uninstalls the profile for the specified build target. 167 Uninstall(jirix *jiri.X, pdb *DB, root jiri.RelPath, target Target) error 168 }