Skip to content
This repository has been archived by the owner on Jan 15, 2021. It is now read-only.

Commit

Permalink
add --save flag to yotta install, and install in the yotta_modules di…
Browse files Browse the repository at this point in the history
…rectory if working with a component; fixes #23 and #22
  • Loading branch information
James Crosby authored and James Crosby committed Sep 8, 2014
1 parent a9837e8 commit 3b98977
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 23 deletions.
100 changes: 83 additions & 17 deletions yotta/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,34 +17,51 @@ def addOptions(parser):
help='If specified, install this component instead of installing '+
'the dependencies of the current component.'
)
parser.add_argument('--global', '-g', dest='act_globally', default=False, action='store_true',
help='Install globally instead of in the current working directory.'
)
parser.add_argument('-l', '--install-linked', dest='install_linked',
action='store_true', default=False,
help='Traverse linked components, and install dependencies needed there too.'
)
group = parser.add_mutually_exclusive_group()
group.add_argument('--global', '-g', dest='act_globally', default=False, action='store_true',
help='Install globally instead of in the current working directory.'
)
group.add_argument('--save', dest='save', action='store_true',
default=False,
help='Add the specified component to dependencies in module.json'
)
group.add_argument('--save-target', dest='save_target',
action='store_true', default=False,
help='Add the specified component to targetDependencies in module.json'
)


def execCommand(args):
cwd = os.getcwd()
c = component.Component(cwd)
if args.component is None:
installDeps(args)
installDeps(args, c)
elif c or c.exists():
installComponentAsDependency(args, c)
else:
installComponent(args)


def installDeps(args):
cwd = os.getcwd()
c = component.Component(cwd)
if not c:
logging.debug(str(c.error))
def installDeps(args, current_component):
logging.debug('install deps for %s' % current_component)
if args.save:
logging.error('must specify a component name when using --save')
return 1
if args.save_target:
logging.error('must specify a component name when using --save-target')
return 1
if not current_component:
logging.debug(str(current_component.getError()))
logging.error('The current directory does not contain a valid component.')
return 1
logging.debug('install for %s' % c)
if not args.target:
logging.error('No target has been set, use "yotta target" to set one.')
return 1
target, errors = c.satisfyTarget(args.target)
target, errors = current_component.satisfyTarget(args.target)
if errors:
for error in errors:
logging.error(error)
Expand All @@ -57,21 +74,70 @@ def installDeps(args):
install_linked = False
if 'install_linked' in args:
install_linked = args.install_linked
components, errors = c.satisfyDependenciesRecursive(
components, errors = current_component.satisfyDependenciesRecursive(
target = target,
traverse_links = install_linked,
available_components = [(c.getName(), c)]
available_components = [(current_component.getName(), current_component)]
)
for error in errors:
logging.error(error)



def installComponentAsDependency(args, current_component):
logging.debug('install component %s as dependency of %s' % (args.component, current_component))
if not current_component:
logging.debug(str(current_component.getError()))
logging.error('The current directory does not contain a valid component.')
return -1
target, errors = current_component.satisfyTarget(args.target)
if errors:
for error in errors:
logging.error(error)
return 1
#!!! FIXME: non-registry component spec support (see also installComponent
# below), for these the original source should be included in the version
# spec, too
component_name = args.component
modules_dir = os.path.join(os.getcwd(), 'node_modules')
installed = access.satisfyVersion(
component_name,
'*',
available = {current_component.getName():current_component},
search_paths = [modules_dir],
working_directory = modules_dir
)
# always add the component to the dependencies of the current component
# - but don't write the dependency file back to disk if we're not meant to
# save it
if installed and args.save:
current_component.saveDependency(installed)
current_component.writeDescription()
elif installed and args.save_target:
current_component.saveTargetDependency(target, installed)
current_component.writeDescription()
else:
current_component.saveDependency(installed)
# !!! should only install dependencies necessary for the one thing that
# we're installing (but existing components should be made available to
# satisfy dependencies)
components, errors = current_component.satisfyDependenciesRecursive(
target = target,
available_components = [(current_component.getName(), current_component)]
)
for error in errors:
logging.error(error)


def installComponent(args):
path = folders.globalInstallDirectory() if args.act_globally else os.getcwd()
logging.debug('install component %s to %s' % (args.component, path))

# !!! FIXME: if the current directory is a component, it should be
# made available to satisfy dependencies of the installed component
if args.save:
logging.error('cannot --save unless the current directory is a component')
return 1
if args.save_target:
logging.error('cannot --save-target unless the current directory is a component')
return 1

# !!! FIXME: should support other URL specs, spec matching should be in
# access module
Expand All @@ -95,4 +161,4 @@ def installComponent(args):
working_directory = path
)
os.chdir(component_name)
installDeps(args)
installDeps(args, component.Component(os.getcwd()))
29 changes: 29 additions & 0 deletions yotta/lib/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -528,3 +528,32 @@ def getExtraObjcFlags(self):

def getRegistryNamespace(self):
return Registry_Namespace

def __saveSpecForComponent(self, component):
version = component.getVersion()
if version.isTip():
spec = '*'
elif version.major() == 0:
# for 0.x.x versions, when we save a dependency we don't use ^0.x.x
# a that would peg to the exact version - instead we use ~ to peg
# to the same minor version
spec = '~' + str(version)
else:
spec = '^' + str(version)
return spec

def saveDependency(self, component, spec=None):
if not 'dependencies' in self.description:
self.description['dependencies'] = OrderedDict()
if spec is None:
spec = self.__saveSpecForComponent(component)
self.description['dependencies'][component.getName()] = spec

def saveTargetDependency(self, target, component, spec=None):
if not 'targetDependencies' in self.description:
self.description['targetDependencies'] = OrderedDict()
if not target.getName() in self.description['targetDependencies']:
self.description['targetDependencies'][target.getName()] = OrderedDict()
if spec is None:
spec = self.__saveSpecForComponent(component)
self.description['targetDependencies'][target.getName()][component.getName()] = spec
4 changes: 2 additions & 2 deletions yotta/test/git_access.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ def test_versionSpec(self):
self.assertTrue(v)

def test_installDeps(self):
Args = namedtuple('Args', ['component', 'target', 'act_globally', 'install_linked'])
install.installComponent(Args(Test_Deps_Name, Test_Deps_Target, False, False))
Args = namedtuple('Args', ['component', 'target', 'act_globally', 'install_linked', 'save', 'save_target'])
install.installComponent(Args(Test_Deps_Name, Test_Deps_Target, False, False, False, False))


if __name__ == '__main__':
Expand Down
4 changes: 2 additions & 2 deletions yotta/test/github_access.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ def tearDown(self):
pass

def test_installDeps(self):
Args = namedtuple('Args', ['component', 'target', 'act_globally', 'install_linked'])
install.installComponent(Args(Test_Deps_Name, Test_Deps_Target, False, False))
Args = namedtuple('Args', ['component', 'target', 'act_globally', 'install_linked', 'save', 'save_target'])
install.installComponent(Args(Test_Deps_Name, Test_Deps_Target, False, False, False, False))


if __name__ == '__main__':
Expand Down
4 changes: 2 additions & 2 deletions yotta/test/hg_access.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ def tearDown(self):
fsutils.rmRf(self.working_copy.directory)

def test_installDeps(self):
Args = namedtuple('Args', ['component', 'target', 'act_globally', 'install_linked'])
install.installComponent(Args(Test_Deps_Name, Test_Deps_Target, False, False))
Args = namedtuple('Args', ['component', 'target', 'act_globally', 'install_linked', 'save', 'save_target'])
install.installComponent(Args(Test_Deps_Name, Test_Deps_Target, False, False, False, False))
def test_availableVersions(self):
versions = self.working_copy.availableVersions()
self.assertIn(version.Version('v0.0.1'), versions)
Expand Down

0 comments on commit 3b98977

Please sign in to comment.