def ensure_publish_dir(): # Make sure that a publish directory exists. If it does not, ask the # user if they would like to create one. After running the function # we should exit - we don't want to proceed with a publish if the # icons are dummy ones dir_exists = os.path.exists(PUBLISH_DIR) if not dir_exists: proceed = yn('A \'publish\' directory does not exist for this app. ' \ 'This folder will contain the icons for your app and is required ' \ 'for publishing. Would you like to create one now? [Y/n]: ') if not proceed: sys.exit(1) # Copy the icons over from our resources dir for platform in ALLOWED_PLATFORMS: icon_dir = os.path.join(PUBLISH_DIR, platform, 'icons') ensure_dir_exists(icon_dir) icon = os.path.join(CLI_RESOURCES, 'icons', platform, 'index.png') icon_dest = os.path.join(icon_dir, 'index.png') copyfile(icon, icon_dest) puts(colored.yellow('A \'publish\' directory has been created. ' \ 'This contains placeholder icons for your app. Please make ' \ 'sure you replace these with your own icons.')) sys.exit(0)
def ensure_build_dir(self): ensure_dir_exists(self.directory) build_contents = os.listdir(self.directory) if not build_contents: tf = tarfile.open(Cache.base_package_path(self.base_version), 'r:gz') tf.extractall(self.directory)
def ensure_develop_dir(self): ensure_dir_exists(self.directory) # Make sure that the entry script is copied over scripts_dir = os.path.join(PACKAGER_RESOURCES, self.base_version, 'scripts') scripts = os.listdir(scripts_dir) for s in scripts: src = os.path.join(scripts_dir, s) dest = os.path.join(self.directory, s) shutil.copyfile(src, dest) # We make sure that the required node modules are installed modules_installed = True dependencies = packager_dependencies(self.base_version) required_modules = list(dependencies.keys()) try: modules_dir = os.path.join(self.directory, 'node_modules') node_modules = os.listdir(modules_dir) if not set(node_modules) >= set(required_modules): modules_installed = False except OSError: modules_installed = False if not modules_installed: proceed = yn('We need to download some dependencies. ' \ 'This may take a few minutes. Proceed? [Y/n] ') if not proceed: sys.exit(1) with cd(self.directory): try: npm = npm_cmd(self.base_version) # We want to install react-native first so peer # dependencies are met required_modules.insert(0, required_modules.pop( \ required_modules.index('react-native'))) for m in required_modules: version = dependencies[m] is_repo = 'http' in version print('Downloading %s...' % m) if is_repo: p = background_process('%s install %s' % \ (npm, version), spinner=True) else: p = background_process('%s install ' \ '%s@%s' % (npm, m, version), spinner=True) out, err = p.communicate() if p.returncode != 0: print(err.decode()) sys.exit(1) # Run the associated post-install script if it exists if os.path.isfile('post-install.sh'): print('Running postinstall script...') background_process('sh post-install.sh', spinner=True) except KeyboardInterrupt: sys.exit(1)
def clean_builds(self): """ Remove all build directories for a given app """ tmp = SIPHON_TMP ensure_dir_exists(tmp) regex = 'build-%s-[0-9]+.[0-9]+' % self.app_id build_dirs = [os.path.join(tmp, f) for f in os.listdir(tmp) if re.search(regex, f)] for b in build_dirs: shutil.rmtree(b)
def clean_builds(self): """ Remove all build directories for a given app """ tmp = SIPHON_TMP ensure_dir_exists(tmp) regex = 'build-%s-[0-9]+.[0-9]+' % self.app_id build_dirs = [ os.path.join(tmp, f) for f in os.listdir(tmp) if re.search(regex, f) ] for b in build_dirs: shutil.rmtree(b)
def download_file(url, destination, download_msg=None): if not destination[0] == '/': destination = os.path.join(os.getcwd(), destination) response = requests.get(url, stream=True, timeout=(10, None)) content_length = response.headers.get('content-length') if not response.ok: err = 'Could not download file %s (server responded with status ' \ 'code %s)' % (url, response.status_code) response.close() raise SiphonCommandException(err) tmp = tempfile.mkdtemp() tmp_dest = os.path.join(tmp, os.path.basename(destination)) try: with open(tmp_dest, 'w+b') as f: if download_msg: puts(colored.yellow(download_msg)) if not content_length: f.write(response.content) return else: content_length = int(content_length) progress = 0 bar_width= 50 # Length in chars for data in response.iter_content(chunk_size=1024): progress += len(data) f.write(data) percentage = round((progress / content_length) * 100, 1) bar = int(bar_width * (progress / content_length)) stats = '%s%% (%s/%s)' % (percentage, format_size(progress), format_size(content_length)) # Include spaces at the end so that if the stat string shortens # previously printed text isn't visible sys.stdout.write('\r[%s%s] %s ' % ('=' * bar, ' ' * (bar_width - bar), stats)) sys.stdout.flush() response.close() dest_dir = os.path.dirname(destination) ensure_dir_exists(dest_dir) copyfile(tmp_dest, destination) puts(colored.green('\nDownload complete.')) except KeyboardInterrupt: puts(colored.red('\nDownload interrupted.')) raise finally: shutil.rmtree(tmp) response.close()
def set_key(k, val): ensure_dir_exists(CACHE_DIR) try: with open(CACHE_FILE, 'r') as fp: data = json.load(fp) except ValueError: data = {} except FileNotFoundError: data = {} data[k] = val with open(CACHE_FILE, 'w') as fp: json.dump(data, fp)
def download_file(url, destination, download_msg=None): if not destination[0] == '/': destination = os.path.join(os.getcwd(), destination) response = requests.get(url, stream=True, timeout=(10, None)) content_length = response.headers.get('content-length') if not response.ok: err = 'Could not download file %s (server responded with status ' \ 'code %s)' % (url, response.status_code) response.close() raise SiphonCommandException(err) tmp = tempfile.mkdtemp() tmp_dest = os.path.join(tmp, os.path.basename(destination)) try: with open(tmp_dest, 'w+b') as f: if download_msg: puts(colored.yellow(download_msg)) if not content_length: f.write(response.content) return else: content_length = int(content_length) progress = 0 bar_width = 50 # Length in chars for data in response.iter_content(chunk_size=1024): progress += len(data) f.write(data) percentage = round((progress / content_length) * 100, 1) bar = int(bar_width * (progress / content_length)) stats = '%s%% (%s/%s)' % (percentage, format_size(progress), format_size(content_length)) # Include spaces at the end so that if the stat string shortens # previously printed text isn't visible sys.stdout.write('\r[%s%s] %s ' % ('=' * bar, ' ' * (bar_width - bar), stats)) sys.stdout.flush() response.close() dest_dir = os.path.dirname(destination) ensure_dir_exists(dest_dir) copyfile(tmp_dest, destination) puts(colored.green('\nDownload complete.')) except KeyboardInterrupt: puts(colored.red('\nDownload interrupted.')) raise finally: shutil.rmtree(tmp) response.close()
def ensure_node(version): if not node_cmd(version): # Neither a valid global or siphon installation was found, so we # must download the correct binary. version_exists = NODE_BINARIES.get(version) if not version_exists: puts(colored.red('Base version not supported. Please set ' \ 'the "base_version" value in your app\'s Siphonfile to one ' \ 'of the following: ')) for k in reversed(sorted(list(NODE_BINARIES.keys()))): print(k) sys.exit(1) if get_platform_name() != PLATFORM_DARWIN: raise SiphonClientException('Node not supported on platform.') url = NODE_BINARIES[version]['darwin-64']['url'] node_size = format_size(get_download_size(url)) proceed = yn('We need to download Node.js & npm (we won\'t override ' \ 'any current installations you may have). ' \ 'These are required to run the packager and download ' \ 'any dependencies we need. Download? (%s) ' \ '[Y/n] ' % node_size) if not proceed: sys.exit(1) version_dest = os.path.join(NODE_DESTINATION, version) ensure_dir_exists(version_dest) dest = os.path.join(version_dest, os.path.basename(url)) download_file(url, dest, 'Downloading Node.js & npm...') print('Installing node...') tf = tarfile.open(dest, 'r:gz') content_dir = os.path.join(version_dest, NODE_BINARIES[version]['darwin-64']['content']) tf.extractall(version_dest) move_contents_to_parent(content_dir) print('Installation successful.')
def add_repo_to_directory(repo, commit, name, destination, directories=(), files=()): with make_temp_dir() as tmp: with cd(tmp): print('Clone destination: %s' % tmp) bash('git clone %s' % repo) bash('cd %s && git checkout %s' % (name, commit)) print('Copying required files & directories...') repo_base = os.path.join(tmp, name) for f in files: src_path = os.path.join(repo_base, f) dest_path = os.path.join(destination, f) # copyfile does not make intermediate directories if they do # not exist target_dir = os.path.dirname(dest_path) ensure_dir_exists(target_dir) copyfile(src_path, dest_path) for d in directories: src_path = os.path.join(repo_base, d) dest_path = os.path.join(destination, d) copy_tree(src_path, dest_path, preserve_symlinks=True)