def do_publish(args): """publish [ DOWNLOAD-BASE-URL ]""" parser = OptionParser(usage="usage: %prog publish [options] [ DOWNLOAD-BASE-URL ]") parser.add_option('', "--target-feed", help="name of output feed file to create", metavar='FILE') (options, args2) = parser.parse_args(args) buildenv = BuildEnv() if len(args2) == 0: if not buildenv.download_base_url: raise SafeException("No download base set. Give the URL for a remote directory.") elif len(args2) == 1: buildenv.config.set('compile', 'download-base-url', args2[0]) buildenv.save() info("Using download base URL: %s", buildenv.download_base_url) if not os.path.isdir(buildenv.distdir): raise SafeException("Directory '%s' does not exist. Try 'compile build'." % buildenv.distdir) distdir = os.path.basename(buildenv.distdir) archive_name = buildenv.archive_stem + '.tar.bz2' # Make all directories in the archive user writable for main, dirs, files in os.walk(distdir): os.chmod(main, os.stat(main).st_mode | 0200) import tarfile archive = tarfile.open(archive_name, mode = 'w:bz2') archive.add(distdir, buildenv.archive_stem) archive.close() target_feed = options.target_feed or buildenv.local_download_iface download_url = os.path.join(buildenv.download_base_url, archive_name) shutil.copyfile(buildenv.local_iface_file, target_feed) # XXX: we're assuming that 0publish requires the same version of Python as # 0compile. This is currently needed for Arch Linux, but long-term we need to # use the <runner>. spawn_and_check(sys.executable, [ pubish_command, target_feed, '--archive-url', download_url, '--archive-extract', buildenv.archive_stem]) if options.target_feed is None: # If --target-feed is used this is probably a script, so don't print # out hints. print "Now upload '%s' as:\n%s\n" % (archive_name, download_url) print "Once uploaded, you can download and run with:" print "$ 0launch %s" % target_feed
def do_setup(args, get_dir_callback = None): "setup [ SOURCE-URI [ DIR ] ]" if len(args) == 0: assert get_dir_callback is None buildenv = BuildEnv() interface = buildenv.interface assert interface create_dir = None buildenv.get_selections(prompt = True) else: buildenv = BuildEnv(need_config = False) interface = args[0] if get_dir_callback: assert len(args) == 1 if len(args) == 1: create_dir = os.path.basename(interface) if create_dir.endswith('.xml'): create_dir = create_dir[:-4] if create_dir.startswith('alias:'): create_dir = create_dir.split(':', 1)[1] assert os.path.dirname(create_dir) == '' assert create_dir != os.path.curdir if get_dir_callback: create_dir = get_dir_callback(create_dir) elif len(args) == 2: create_dir = args[1] if create_dir == '.': create_dir = None else: raise __main__.UsageError() iface_uri = model.canonical_iface_uri(args[0]) if os.path.isabs(iface_uri): root = qdom.parse(file(iface_uri)) if root.uri == namespaces.XMLNS_IFACE and root.name == 'selections': # Looks like this is a selections file, not an interface. buildenv.config.set('compile', 'selections', iface_uri) iface_uri = root.getAttribute('interface') buildenv.config.set('compile', 'interface', iface_uri) if create_dir and os.path.exists(create_dir): raise SafeException("Directory '%s' already exists." % create_dir) buildenv.get_selections() if create_dir: try: os.mkdir(create_dir) except: print >>sys.stderr, "Failed to create new directory '%s'" % os.path.abspath(create_dir) raise os.chdir(create_dir) print "Created directory %s" % create_dir buildenv.save()
def do_publish(args): """publish [ DOWNLOAD-BASE-URL ]""" parser = OptionParser( usage="usage: %prog publish [options] [ DOWNLOAD-BASE-URL ]") parser.add_option('', "--target-feed", help="name of output feed file to create", metavar='FILE') (options, args2) = parser.parse_args(args) buildenv = BuildEnv() if len(args2) == 1: buildenv.config.set('compile', 'download-base-url', args2[0]) buildenv.save() elif len(args2) > 1: parser.print_help() sys.exit(1) download_base_url = buildenv.download_base_url or None if download_base_url: info("Using download base URL: %s", download_base_url) if not os.path.isdir(buildenv.distdir): raise SafeException( "Directory '%s' does not exist. Try 'compile build'." % buildenv.distdir) distdir = os.path.basename(buildenv.distdir) archive_name = buildenv.archive_stem + '.tar.bz2' # Make all directories in the archive user writable for main, dirs, files in os.walk(distdir): os.chmod(main, os.stat(main).st_mode | 0o200) import tarfile archive = tarfile.open(archive_name, mode='w:bz2') archive.add(distdir, buildenv.archive_stem) archive.close() target_feed = options.target_feed or buildenv.local_download_iface if download_base_url: download_url = os.path.join(download_base_url, archive_name) else: download_url = archive_name shutil.copyfile(buildenv.local_iface_file, target_feed) # XXX: we're assuming that 0publish requires the same version of Python as # 0compile. This is currently needed for Arch Linux, but long-term we need to # use the <runner>. spawn_and_check(sys.executable, [ pubish_command, target_feed, '--archive-url', download_url, '--archive-extract', buildenv.archive_stem ]) if options.target_feed is None: # If --target-feed is used this is probably a script, so don't print # out hints. if download_base_url: print("Now upload '%s' as:\n%s\n" % (archive_name, download_url)) print("Once uploaded, you can download and run with:") print("0launch %s" % target_feed) else: print("Generated archive '%s' and feed '%s'." % (archive_name, target_feed)) print("Upload it to a repository with:") print("0repo add %s" % target_feed)
def compile_and_register(self, sels, forced_iface_uri = None): """If forced_iface_uri, register as an implementation of this interface, ignoring the any <feed-for>, etc.""" buildenv = BuildEnv(need_config = False) buildenv.config.set('compile', 'interface', sels.interface) buildenv.config.set('compile', 'selections', 'selections.xml') # Download any required packages now, so we can use the GUI to request confirmation, etc download_missing = sels.download_missing(self.config, include_packages = True) if download_missing: yield download_missing tasks.check(download_missing) tmpdir = tempfile.mkdtemp(prefix = '0compile-') try: os.chdir(tmpdir) # Write configuration for build... buildenv.save() sel_file = open('selections.xml', 'w') try: doc = sels.toDOM() doc.writexml(sel_file) sel_file.write('\n') finally: sel_file.close() # Do the build... build = self.spawn_build(buildenv.iface_name) if build: yield build tasks.check(build) # Register the result... dom = minidom.parse(buildenv.local_iface_file) feed_for_elem, = dom.getElementsByTagNameNS(namespaces.XMLNS_IFACE, 'feed-for') claimed_iface = feed_for_elem.getAttribute('interface') if forced_iface_uri is not None: if forced_iface_uri != claimed_iface: self.note("WARNING: registering as feed for {forced}, though feed claims to be for {claimed}".format( forced = forced_iface_uri, claimed = claimed_iface)) else: forced_iface_uri = claimed_iface # (the top-level interface being built) version = sels.selections[sels.interface].version site_package_versions_dir = basedir.save_data_path('0install.net', 'site-packages', *model.escape_interface_uri(forced_iface_uri)) leaf = '%s-%s' % (version, uname[4]) site_package_dir = os.path.join(site_package_versions_dir, leaf) self.note("Storing build in %s" % site_package_dir) # 1. Copy new version in under a temporary name. Names starting with '.' are ignored by 0install. tmp_distdir = os.path.join(site_package_versions_dir, '.new-' + leaf) shutil.copytree(buildenv.distdir, tmp_distdir, symlinks = True) # 2. Rename the previous build to .old-VERSION (deleting that if it already existed) if os.path.exists(site_package_dir): self.note("(moving previous build out of the way)") previous_build_dir = os.path.join(site_package_versions_dir, '.old-' + leaf) if os.path.exists(previous_build_dir): shutil.rmtree(previous_build_dir) os.rename(site_package_dir, previous_build_dir) else: previous_build_dir = None # 3. Rename the new version immediately after renaming away the old one to minimise time when there's # no version. os.rename(tmp_distdir, site_package_dir) # 4. Delete the old version. if previous_build_dir: self.note("(deleting previous build)") shutil.rmtree(previous_build_dir) local_feed = os.path.join(site_package_dir, '0install', 'feed.xml') assert os.path.exists(local_feed), "Feed %s not found!" % local_feed # Reload - our 0install will detect the new feed automatically iface = self.config.iface_cache.get_interface(forced_iface_uri) reader.update_from_cache(iface, iface_cache = self.config.iface_cache) self.config.iface_cache.get_feed(local_feed, force = True) # Write it out - 0install will add the feed so that older 0install versions can find it writer.save_interface(iface) except: self.note("\nBuild failed: leaving build directory %s for inspection...\n" % tmpdir) raise else: # Can't delete current directory on Windows, so move to parent first os.chdir(os.path.join(tmpdir, os.path.pardir)) ro_rmtree(tmpdir)
def compile_and_register(self, sels, forced_iface_uri=None): """If forced_iface_uri, register as an implementation of this interface, ignoring the any <feed-for>, etc.""" buildenv = BuildEnv(need_config=False) buildenv.config.set('compile', 'interface', sels.interface) buildenv.config.set('compile', 'selections', 'selections.xml') # Download any required packages now, so we can use the GUI to request confirmation, etc download_missing = sels.download_missing(self.config, include_packages=True) if download_missing: yield download_missing tasks.check(download_missing) tmpdir = tempfile.mkdtemp(prefix='0compile-') try: os.chdir(tmpdir) # Write configuration for build... buildenv.save() sel_file = open('selections.xml', 'w') try: doc = sels.toDOM() doc.writexml(sel_file) sel_file.write('\n') finally: sel_file.close() # Do the build... build = self.spawn_build(buildenv.iface_name) if build: yield build tasks.check(build) # Register the result... dom = minidom.parse(buildenv.local_iface_file) feed_for_elem, = dom.getElementsByTagNameNS( namespaces.XMLNS_IFACE, 'feed-for') claimed_iface = feed_for_elem.getAttribute('interface') if forced_iface_uri is not None: if forced_iface_uri != claimed_iface: self.note( "WARNING: registering as feed for {forced}, though feed claims to be for {claimed}" .format(forced=forced_iface_uri, claimed=claimed_iface)) else: forced_iface_uri = claimed_iface # (the top-level interface being built) version = sels.selections[sels.interface].version site_package_versions_dir = basedir.save_data_path( '0install.net', 'site-packages', *model.escape_interface_uri(forced_iface_uri)) leaf = '%s-%s' % (version, build_target_machine_type) site_package_dir = os.path.join(site_package_versions_dir, leaf) self.note("Storing build in %s" % site_package_dir) # 1. Copy new version in under a temporary name. Names starting with '.' are ignored by 0install. tmp_distdir = os.path.join(site_package_versions_dir, '.new-' + leaf) shutil.copytree(buildenv.distdir, tmp_distdir, symlinks=True) # 2. Rename the previous build to .old-VERSION (deleting that if it already existed) if os.path.exists(site_package_dir): self.note("(moving previous build out of the way)") previous_build_dir = os.path.join(site_package_versions_dir, '.old-' + leaf) if os.path.exists(previous_build_dir): shutil.rmtree(previous_build_dir) os.rename(site_package_dir, previous_build_dir) else: previous_build_dir = None # 3. Rename the new version immediately after renaming away the old one to minimise time when there's # no version. os.rename(tmp_distdir, site_package_dir) # 4. Delete the old version. if previous_build_dir: self.note("(deleting previous build)") shutil.rmtree(previous_build_dir) local_feed = os.path.join(site_package_dir, '0install', 'feed.xml') assert os.path.exists( local_feed), "Feed %s not found!" % local_feed # Reload - our 0install will detect the new feed automatically iface = self.config.iface_cache.get_interface(forced_iface_uri) reader.update_from_cache(iface, iface_cache=self.config.iface_cache) self.config.iface_cache.get_feed(local_feed, force=True) # Write it out - 0install will add the feed so that older 0install versions can find it writer.save_interface(iface) seen_key = (forced_iface_uri, sels.selections[sels.interface].id) assert seen_key not in self.seen, seen_key self.seen[seen_key] = site_package_dir except: self.note( "\nBuild failed: leaving build directory %s for inspection...\n" % tmpdir) raise else: # Can't delete current directory on Windows, so move to parent first os.chdir(os.path.join(tmpdir, os.path.pardir)) ro_rmtree(tmpdir)
def do_setup(args, get_dir_callback=None): "setup [ SOURCE-URI [ DIR ] ]" if len(args) == 0: assert get_dir_callback is None buildenv = BuildEnv() interface = buildenv.interface assert interface create_dir = None buildenv.get_selections(prompt=True) else: buildenv = BuildEnv(need_config=False) interface = args[0] if get_dir_callback: assert len(args) == 1 if len(args) == 1: create_dir = os.path.basename(interface) if create_dir.endswith('.xml'): create_dir = create_dir[:-4] if create_dir.startswith('alias:'): create_dir = create_dir.split(':', 1)[1] assert os.path.dirname(create_dir) == '' assert create_dir != os.path.curdir if get_dir_callback: create_dir = get_dir_callback(create_dir) elif len(args) == 2: create_dir = args[1] if create_dir == '.': create_dir = None else: raise __main__.UsageError() iface_uri = model.canonical_iface_uri(args[0]) if os.path.isabs(iface_uri): # Use a relative path if the feed is inside the current directory. # This is useful if the properties file is shared with other users. rel_iface_uri = os.path.relpath(iface_uri, create_dir or ".") if not rel_iface_uri.startswith("."): iface_uri = rel_iface_uri root = qdom.parse(file(iface_uri)) if root.uri == namespaces.XMLNS_IFACE and root.name == 'selections': # Looks like this is a selections file, not an interface. buildenv.config.set('compile', 'selections', iface_uri) iface_uri = root.getAttribute('interface') buildenv.config.set('compile', 'interface', iface_uri) if create_dir and os.path.exists(create_dir): raise SafeException("Directory '%s' already exists." % create_dir) buildenv.get_selections() if create_dir: try: os.mkdir(create_dir) except: print >> sys.stderr, "Failed to create new directory '%s'" % os.path.abspath( create_dir) raise os.chdir(create_dir) print "Created directory %s" % create_dir buildenv.save()