def generate_non_cookiecutter_project(location, output_dir): """ Uses Cookiecutter APIs to download a project at given ``location`` to the ``output_dir``. This does *not* run cookiecutter on the downloaded project. Parameters ---------- location : str Path to where the project is. This supports all formats of location cookiecutter supports (ex: zip, git, ssh, hg, local zipfile) NOTE: This value *cannot* be a local directory. We didn't see a value in simply copying the directory contents to ``output_dir`` without any processing. output_dir : str Directory where the project should be downloaded to Returns ------- str Name of the directory where the project was downloaded to. Raises ------ cookiecutter.exception.CookiecutterException if download failed for some reason """ LOG.debug("Downloading project from %s to %s", location, output_dir) # Don't prompt ever no_input = True # Expand abbreviations in URL such as gh:awslabs/aws-sam-cli location = repository.expand_abbreviations(location, config.BUILTIN_ABBREVIATIONS) # If this is a zip file, download and unzip into output directory if repository.is_zip_file(location): LOG.debug("%s location is a zip file", location) download_fn = functools.partial( repository.unzip, zip_uri=location, is_url=repository.is_repo_url(location), no_input=no_input) # Else, treat it as a git/hg/ssh URL and try to clone elif repository.is_repo_url(location): LOG.debug("%s location is a source control repository", location) download_fn = functools.partial(repository.clone, repo_url=location, no_input=no_input) else: raise ArbitraryProjectDownloadFailed(msg=BAD_LOCATION_ERROR_MSG) try: return _download_and_copy(download_fn, output_dir) except exceptions.RepositoryNotFound: # Download failed because the zip or the repository was not found raise ArbitraryProjectDownloadFailed(msg=BAD_LOCATION_ERROR_MSG)
def test_expand_abbreviations(): template = 'gh:audreyr/cookiecutter-pypackage' # This is not a valid repo url just yet! # First `repository.expand_abbreviations` needs to translate it assert is_repo_url(template) is False expanded_template = expand_abbreviations(template, BUILTIN_ABBREVIATIONS) assert is_repo_url(expanded_template) is True
def test_expand_abbreviations(): template = "gh:audreyr/cookiecutter-pypackage" # This is not a valid repo url just yet! # First `repository.expand_abbreviations` needs to translate it assert is_repo_url(template) is False expanded_template = expand_abbreviations(template, BUILTIN_ABBREVIATIONS) assert is_repo_url(expanded_template) is True
def template_type(template): status = 'local directory' if re.match(r'(gh|hg):', template): status = 'remote alias' if is_repo_url(template): status = 'url' return status
def compile_data(template, target, data): context = {"cookiecutter": {"project_name": target, "data": data}} is_repo = repository.is_repo_url(template) if is_repo: logger.info(f"Template is a repo, cloning") template = vcs.clone(template, None, "remote_repos", True) result = generate.generate_files(template, context=context, overwrite_if_exists=True) return result
def test_is_repo_url_for_local_urls(local_repo_url): """Verify is_repo_url works.""" assert is_repo_url(local_repo_url) is False
def test_is_repo_url_for_remote_urls(remote_repo_url): """Verify is_repo_url works.""" assert is_repo_url(remote_repo_url) is True
def update_cookiecutter_cache(self, template: str, branch="master"): """Ensure that we have a current checkout of a template path. If the path is a local path, use the path as is. If the path is a URL, look for a local cache; if one exists, update it, including checking out the required branch. :param template: The template URL or path. :param branch: The template branch to use. Default: ``master`` :return: The path to the cached template. This may be the originally provided path if the template was a file path. """ if is_repo_url(template): # The app template is a repository URL. # # When in `no_input=True` mode, cookiecutter deletes and reclones # a template directory, rather than updating the existing repo. # # Look for a cookiecutter cache of the template; if one exists, # try to update it using git. If no cache exists, or if the cache # directory isn't a git directory, or git fails for some reason, # fall back to using the specified template directly. try: cached_template = cookiecutter_cache_path(template) repo = self.git.Repo(cached_template) try: # Attempt to update the repository remote = repo.remote(name="origin") remote.fetch() except self.git.exc.GitCommandError: # We are offline, or otherwise unable to contact # the origin git repo. It's OK to continue; but warn # the user that the template may be stale. self.logger.warning(""" ************************************************************************* ** WARNING: Unable to update template ** ************************************************************************* Briefcase is unable the update the application template. This may be because your computer is currently offline. Briefcase will use existing template without updating. ************************************************************************* """) try: # Check out the branch for the required version tag. head = remote.refs[branch] self.logger.info( f"Using existing template (sha {head.commit.hexsha}, " f"updated {head.commit.committed_datetime.strftime('%c')})" ) head.checkout() except IndexError as e: # No branch exists for the requested version. raise TemplateUnsupportedVersion(branch) from e except self.git.exc.NoSuchPathError: # Template cache path doesn't exist. # Just use the template directly, rather than attempting an update. cached_template = template except self.git.exc.InvalidGitRepositoryError: # Template cache path exists, but isn't a git repository # Just use the template directly, rather than attempting an update. cached_template = template else: # If this isn't a repository URL, treat it as a local directory cached_template = template return cached_template