def create(info, verbose=False): verify_nsis_install() tmp_dir = tempfile.mkdtemp() preconda.write_files(info, tmp_dir) if 'pre_install' in info: sys.exit("Error: Cannot run pre install on Windows, sorry.\n") post_dst = join(tmp_dir, 'post_install.bat') try: shutil.copy(info['post_install'], post_dst) except KeyError: with open(post_dst, 'w') as fo: fo.write(":: this is an empty post install .bat script\n") write_images(info, tmp_dir) nsi = make_nsi(info, tmp_dir) if verbose: verbosity = '/V4' else: verbosity = '/V2' args = [MAKENSIS_EXE, verbosity, nsi] print('Calling: %s' % args) if verbose: sub = Popen(args, stdout=PIPE, stderr=PIPE) stdout, stderr = sub.communicate() for msg, info in zip((stdout, stderr), ('stdout', 'stderr')): # on Python3 we're getting bytes if hasattr(msg, 'decode'): msg = msg.decode() print('makensis {}:'.format(info)) print(msg) else: check_call(args) shutil.rmtree(tmp_dir)
def create(info): tmp_dir = tempfile.mkdtemp() preconda.write_files(info, tmp_dir) tarball = join(tmp_dir, 'tmp.tar') t = tarfile.open(tarball, 'w') if 'license_file' in info: t.add(info['license_file'], 'LICENSE.txt') for fn in preconda.files: t.add(join(tmp_dir, fn), 'pkgs/' + fn) for fn in info['_dists']: t.add(join(info['_download_dir'], fn), 'pkgs/' + fn) for key in 'pre_install', 'post_install': if key in info: t.add(info[key], 'pkgs/%s.sh' % key) t.close() header = get_header(tarball, info) shar_path = info['_outpath'] with open(shar_path, 'wb') as fo: fo.write(header.encode('utf-8')) with open(tarball, 'rb') as fi: while True: chunk = fi.read(262144) if not chunk: break fo.write(chunk) os.unlink(tarball) os.chmod(shar_path, 0o755) shutil.rmtree(tmp_dir)
def create(info): verify_nsis_install() tmp_dir = tempfile.mkdtemp() preconda.write_files(info, tmp_dir) if 'pre_install' in info: sys.exit("Error: Cannot run pre install on Windows, sorry.\n") post_dst = join(tmp_dir, 'post_install.bat') try: shutil.copy(info['post_install'], post_dst) except KeyError: with open(post_dst, 'w') as fo: fo.write(":: this is an empty post install .bat script\n") write_images(info, tmp_dir) nsi = make_nsi(info, tmp_dir) args = [MAKENSIS_EXE, '/V2', nsi] print('Calling: %s' % args) check_call(args) shutil.rmtree(tmp_dir)
def create(info, verbose=False): global CACHE_DIR, PACKAGE_ROOT, PACKAGES_DIR CACHE_DIR = info['_download_dir'] PACKAGE_ROOT = join(CACHE_DIR, "package_root") PACKAGES_DIR = join(CACHE_DIR, "built_pkgs") # See http://stackoverflow.com/a/11487658/161801 for how all this works. prefix = join(PACKAGE_ROOT, info['name'].lower()) fresh_dir(PACKAGES_DIR) fresh_dir(PACKAGE_ROOT) pkgs_dir = join(prefix, 'pkgs') os.makedirs(pkgs_dir) preconda.write_files(info, pkgs_dir) # TODO: Refactor code such that the argument to preconda.write_files is # /path/to/base/env, so that such workarounds are not required. shutil.move(join(pkgs_dir, 'conda-meta'), prefix) pkgbuild('preconda') for dist in info['_dists']: if isinstance(dist, str if version_info[0] >= 3 else basestring): fn = dist dname = dist[:-8] ndist(fn) else: fn = dist.fn dname = dist.dist_name ndist = dist.name fresh_dir(PACKAGE_ROOT) if bool(info.get('attempt_hardlinks')): t = tarfile.open(join(CACHE_DIR, fn), 'r:bz2') os.makedirs(join(pkgs_dir, dname)) t.extractall(join(pkgs_dir, dname)) t.close() else: t = tarfile.open(join(CACHE_DIR, fn), 'r:bz2') t.extractall(prefix) t.close() os.rename(join(prefix, 'info'), join(prefix, 'info-tmp')) os.mkdir(join(prefix, 'info')) os.rename(join(prefix, 'info-tmp'), join(prefix, 'info', fn[:-8])) pkgbuild(ndist) # Create special preinstall and postinstall packages to check if Anaconda # is already installed, build Anaconda, and to update the shell profile. # First script pkgbuild_script('postextract', info, 'post_extract.sh') # Next, the script to edit bashrc with the PATH. This is separate so it # can be disabled. pkgbuild_script('pathupdate', info, 'update_path.sh') # Next, the script to be run before everything, which checks if Anaconda # is already installed. pkgbuild_script('apreinstall', info, 'preinstall.sh', 'preinstall') # Now build the final package names = ['apreinstall', 'preconda'] names.extend(name_dist(dist) for dist in info['_dists']) names.extend(['postextract', 'pathupdate']) xml_path = join(PACKAGES_DIR, 'distribution.xml') args = ["productbuild", "--synthesize"] for name in names: args.extend(['--package', join(PACKAGES_DIR, "%s.pkg" % name)]) args.append(xml_path) check_call(args) modify_xml(xml_path, info) check_call([ "productbuild", "--distribution", xml_path, "--package-path", PACKAGES_DIR, "--identifier", info['name'], "tmp.pkg", ]) identity_name = info.get('signing_identity_name') if identity_name: check_call([ 'productsign', '--sign', identity_name, "tmp.pkg", info['_outpath'], ]) os.unlink("tmp.pkg") else: os.rename('tmp.pkg', info['_outpath']) print("done")
def create(info, verbose=False): global CACHE_DIR, PACKAGE_ROOT, PACKAGES_DIR, SCRIPTS_DIR CACHE_DIR = info['_download_dir'] SCRIPTS_DIR = join(CACHE_DIR, "scripts") PACKAGE_ROOT = join(CACHE_DIR, "package_root") PACKAGES_DIR = join(CACHE_DIR, "built_pkgs") fresh_dir(PACKAGES_DIR) prefix = join(PACKAGE_ROOT, info['name'].lower()) # See http://stackoverflow.com/a/11487658/161801 for how all this works. # The main package contains the prepopulated package cache, the modified # conda-meta metadata staged into pkgs/conda-meta, and conda.exe fresh_dir(PACKAGE_ROOT) fresh_dir(SCRIPTS_DIR) pkgs_dir = join(prefix, 'pkgs') os.makedirs(pkgs_dir) preconda.write_files(info, pkgs_dir) for dist in info['_dists']: os.link(join(CACHE_DIR, dist), join(pkgs_dir, dist)) shutil.copyfile(info['_conda_exe'], join(prefix, "conda.exe")) # This script checks to see if the install location already exists move_script(join(OSX_DIR, 'preinstall.sh'), join(SCRIPTS_DIR, 'preinstall'), info) # This script performs the full installation move_script(join(OSX_DIR, 'post_extract.sh'), join(SCRIPTS_DIR, 'postinstall'), info) pkgbuild('main') names = ['main'] # The next three packages contain nothing but scripts to execute a # particular optional task. The Mac installer GUI will allow each of # these scripts to be enabled or disabled by the user in the GUI # The user-supplied post-install script if info.get('post_install'): pkgbuild_script('postinstall', info, abspath(info['post_install'])) names.append('postinstall') # The script to run conda init pkgbuild_script('pathupdate', info, 'update_path.sh') names.append('pathupdate') # The script to clear the package cache pkgbuild_script('cacheclean', info, 'clean_cache.sh') names.append('cacheclean') # The default distribution file needs to be modified, so we create # it to a temporary location, edit it, and supply it to the final call. xml_path = join(PACKAGES_DIR, 'distribution.xml') args = ["productbuild", "--synthesize"] for name in names: args.extend(['--package', join(PACKAGES_DIR, "%s.pkg" % name)]) args.append(xml_path) check_call(args) modify_xml(xml_path, info) identity_name = info.get('signing_identity_name') check_call([ "productbuild", "--distribution", xml_path, "--package-path", PACKAGES_DIR, "--identifier", info['name'], "tmp.pkg" if identity_name else info['_outpath'] ]) if identity_name: check_call([ 'productsign', '--sign', identity_name, "tmp.pkg", info['_outpath'], ]) os.unlink("tmp.pkg") print("done")
def create(info, verbose=False): global CACHE_DIR, PACKAGE_ROOT, PACKAGES_DIR, SCRIPTS_DIR CACHE_DIR = info['_download_dir'] SCRIPTS_DIR = join(CACHE_DIR, "scripts") PACKAGE_ROOT = join(CACHE_DIR, "package_root") PACKAGES_DIR = join(CACHE_DIR, "built_pkgs") fresh_dir(PACKAGES_DIR) prefix = join(PACKAGE_ROOT, info.get("pkg_name", info['name']).lower()) # See http://stackoverflow.com/a/11487658/161801 for how all this works. # The main package contains the prepopulated package cache, the modified # conda-meta metadata staged into pkgs/conda-meta, and conda.exe fresh_dir(PACKAGE_ROOT) fresh_dir(SCRIPTS_DIR) pkgs_dir = join(prefix, 'pkgs') os.makedirs(pkgs_dir) preconda.write_files(info, pkgs_dir) for dist in info['_dists']: os.link(join(CACHE_DIR, dist), join(pkgs_dir, dist)) shutil.copyfile(info['_conda_exe'], join(prefix, "conda.exe")) # Sign conda-standalone so it can pass notarization notarization_identity_name = info.get('notarization_identity_name') if notarization_identity_name: with NamedTemporaryFile(suffix=".plist", delete=False) as f: plist = { "com.apple.security.cs.allow-jit": True, "com.apple.security.cs.allow-unsigned-executable-memory": True, "com.apple.security.cs.disable-executable-page-protection": True, "com.apple.security.cs.disable-library-validation": True, "com.apple.security.cs.allow-dyld-environment-variables": True, } plist_dump(plist, f) check_call( [ 'codesign', "--verbose", '--sign', notarization_identity_name, "--prefix", info.get("reverse_domain_identifier", info['name']), "--options", "runtime", "--force", "--entitlements", f.name, join(prefix, "conda.exe"), ] ) os.unlink(f.name) # This script checks to see if the install location already exists move_script(join(OSX_DIR, 'preinstall.sh'), join(SCRIPTS_DIR, 'preinstall'), info) # This script performs the full installation move_script(join(OSX_DIR, 'post_extract.sh'), join(SCRIPTS_DIR, 'postinstall'), info) pkgbuild_main(info) names = ['main'] # The next three packages contain nothing but scripts to execute a # particular optional task. The Mac installer GUI will allow each of # these scripts to be enabled or disabled by the user in the GUI # The user-supplied post-install script if info.get('post_install'): pkgbuild_script('postinstall', info, abspath(info['post_install'])) names.append('postinstall') # The script to run conda init pkgbuild_script('pathupdate', info, 'update_path.sh') names.append('pathupdate') # The script to clear the package cache pkgbuild_script('cacheclean', info, 'clean_cache.sh') names.append('cacheclean') # The default distribution file needs to be modified, so we create # it to a temporary location, edit it, and supply it to the final call. xml_path = join(PACKAGES_DIR, 'distribution.xml') args = ["productbuild", "--synthesize"] for name in names: args.extend(['--package', join(PACKAGES_DIR, "%s.pkg" % name)]) args.append(xml_path) check_call(args) modify_xml(xml_path, info) identity_name = info.get('signing_identity_name') check_call([ "productbuild", "--distribution", xml_path, "--package-path", PACKAGES_DIR, "--identifier", info.get("reverse_domain_identifier", info['name']), "tmp.pkg" if identity_name else info['_outpath'] ]) if identity_name: check_call([ 'productsign', '--sign', identity_name, "tmp.pkg", info['_outpath'], ]) os.unlink("tmp.pkg") print("done")
def create(info): global CACHE_DIR, PACKAGE_ROOT, PACKAGES_DIR CACHE_DIR = info['_download_dir'] PACKAGE_ROOT = join(CACHE_DIR, "package_root") PACKAGES_DIR = join(CACHE_DIR, "built_pkgs") # See http://stackoverflow.com/a/11487658/161801 for how all this works. prefix = join(PACKAGE_ROOT, info['name'].lower()) fresh_dir(PACKAGES_DIR) fresh_dir(PACKAGE_ROOT) pkgs_dir = join(prefix, 'pkgs') os.makedirs(pkgs_dir) preconda.write_files(info, pkgs_dir) pkgbuild('preconda') for fn in info['_dists']: fresh_dir(PACKAGE_ROOT) t = tarfile.open(join(CACHE_DIR, fn), 'r:bz2') t.extractall(prefix) t.close() os.rename(join(prefix, 'info'), join(prefix, 'info-tmp')) os.mkdir(join(prefix, 'info')) os.rename(join(prefix, 'info-tmp'), join(prefix, 'info', fn[:-8])) pkgbuild(name_dist(fn)) # Create special preinstall and postinstall packages to check if Anaconda # is already installed, build Anaconda, and to update the shell profile. # First script pkgbuild_script('postextract', info, 'post_extract.sh') # Next, the script to edit bashrc with the PATH. This is separate so it # can be disabled. pkgbuild_script('pathupdate', info, 'update_path.sh') # Next, the script to be run before everything, which checks if Anaconda # is already installed. pkgbuild_script('apreinstall', info, 'preinstall.sh', 'preinstall') # Now build the final package names = ['apreinstall', 'preconda'] names.extend(name_dist(dist) for dist in info['_dists']) names.extend(['postextract', 'pathupdate']) xml_path = join(PACKAGES_DIR, 'distribution.xml') args = ["productbuild", "--synthesize"] for name in names: args.extend(['--package', join(PACKAGES_DIR, "%s.pkg" % name)]) args.append(xml_path) check_call(args) modify_xml(xml_path, info) check_call([ "productbuild", "--distribution", xml_path, "--package-path", PACKAGES_DIR, "--identifier", info['name'], info['_outpath'], ])