def test_generate_context_with_json_decoding_error(): with pytest.raises(ContextDecodingException) as excinfo: generate.generate_context('tests/test-generate-context/invalid-syntax.json') # original message from json module should be included assert re.search('Expecting \'{0,1}:\'{0,1} delimiter: line 1 column (19|20) \(char 19\)', str(excinfo.value)) # File name should be included too...for testing purposes, just test the last part of the file. # If we wanted to test the absolute path, we'd have to do some additional work in the test which # doesn't seem that needed at this point. assert 'tests/test-generate-context/invalid-syntax.json' in str(excinfo.value)
def test_generate_context_with_json_decoding_error(): with pytest.raises(ContextDecodingException) as excinfo: generate.generate_context('tests/test-generate-context/invalid-syntax.json') # original message from json module should be included assert re.search('Expecting \'{0,1}:\'{0,1} delimiter: line 1 column (19|20) \(char 19\)', str(excinfo.value)) # File name should be included too...for testing purposes, just test the last part of the file. # If we wanted to test the absolute path, we'd have to do some additional work in the test which # doesn't seem that needed at this point. path = os.path.sep.join(['tests', 'test-generate-context', 'invalid-syntax.json']) assert path in str(excinfo.value)
def test_generate_context_with_yaml_decoding_error(): path = os.path.sep.join( ['tests', 'test-generate-context', 'invalid-syntax.yml']) with pytest.raises(ContextDecodingException) as excinfo: generate.generate_context(path) # original message from json module should be included assert re.search('line 1: mapping values are not allowed here', str(excinfo.value)) # File name should be included too...for testing purposes, just # test the last part of the file. If we wanted to test the # absolute path, we'd have to do some additional work in the test # which doesn't seem that needed at this point. assert path in str(excinfo.value)
def test_generate_context_with_json_decoding_error(): with pytest.raises(ContextDecodingException) as excinfo: generate.generate_context("tests/test-generate-context/invalid-syntax.json") # original message from json module should be included pattern = ( "Expecting '{0,1}:'{0,1} delimiter: " "line 1 column (19|20) \\(char 19\\)" ) assert re.search(pattern, str(excinfo.value)) # File name should be included too...for testing purposes, just test the # last part of the file. If we wanted to test the absolute path, we'd have # to do some additional work in the test which doesn't seem that needed at # this point. path = os.path.sep.join(["tests", "test-generate-context", "invalid-syntax.json"]) assert path in str(excinfo.value)
def test_generate_context_with_json_decoding_error(): """Verify malformed JSON file generates expected error output.""" with pytest.raises(ContextDecodingException) as excinfo: generate.generate_context( 'tests/generate/test-generate-context/invalid-syntax.json') # original message from json module should be included pattern = 'Expecting \'{0,1}:\'{0,1} delimiter: line 1 column (19|20) \\(char 19\\)' assert re.search(pattern, str(excinfo.value)) # File name should be included too...for testing purposes, just test the # last part of the file. If we wanted to test the absolute path, we'd have # to do some additional work in the test which doesn't seem that needed at # this point. path = os.path.sep.join( ['tests', 'generate', 'test-generate-context', 'invalid-syntax.json']) assert path in str(excinfo.value)
def test_generate_context_with_extra(self): """ Call `generate_context()` with extra_context. """ context = generate.generate_context( context_file='tests/test-generate-context/test.json', extra_context={'1': 4}, ) self.assertEqual(context, {'test': {'1': 4, 'some_key': 'some_val'}})
def get_cookiecutter_config(template, default_config=None, version=None): """Obtains the configuration used for cookiecutter templating Args: template: Path to the template default_config (dict, optional): The default configuration version (str, optional): The git SHA or branch to use when checking out template. Defaults to latest version Returns: tuple: The cookiecutter repo directory and the config dict """ default_config = default_config or {} config_dict = cc_config.get_user_config() repo_dir, _ = cc_repository.determine_repo_dir( template=template, abbreviations=config_dict['abbreviations'], clone_to_dir=config_dict['cookiecutters_dir'], checkout=version, no_input=True) context_file = os.path.join(repo_dir, 'cookiecutter.json') context = cc_generate.generate_context( context_file=context_file, default_context={ **config_dict['default_context'], **default_config }) return repo_dir, cc_prompt.prompt_for_config(context)
def test_apply_overwrites_does_not_modify_choices_for_invalid_overwrite(): """Verify variables overwrite for list if variable not in list ignored.""" expected_context = { 'choices_template': OrderedDict([ ('full_name', 'Raphael Pierzina'), ('github_username', 'hackebrot'), ('project_name', 'Kivy Project'), ('repo_name', '{{cookiecutter.project_name|lower}}'), ('orientation', ['all', 'landscape', 'portrait']), ]) } generated_context = generate.generate_context( context_file='tests/test-generate-context/choices_template.json', default_context={ 'not_in_template': 'foobar', 'project_name': 'Kivy Project', 'orientation': 'foobar', }, extra_context={ 'also_not_in_template': 'foobar2', 'github_username': '******', }, ) assert generated_context == expected_context
def create_context(scaffold_name): config_dict = dict(default_context=dict()) context_file = path.join(get_scaffold(scaffold_name), 'cookiecutter.json') context = generate_context( context_file=context_file, default_context=config_dict['default_context']) return context
def _make_cookiecutter_context_for_prompts(cookiecutter_dir: Path): # pylint: disable=import-outside-toplevel from cookiecutter.generate import generate_context cookiecutter_context = generate_context(cookiecutter_dir / "cookiecutter.json") return cookiecutter_context.get("cookiecutter", {})
def create_project(args, _): context = generate_context( os.path.join(TEMPLATES_PATH, 'app', 'cookiecutter.json')) config = prompt_for_config(context) config['_app_dir'] = args.output_directory with open('.pywebui.yaml', 'w') as config_output: config_output.write( yaml.safe_dump(config, default_flow_style=False, encoding='utf-8')) cookiecutter(os.path.join(TEMPLATES_PATH, 'app'), no_input=True, extra_context=config) os.chdir(args.output_directory) if not args.without_electron: cookiecutter(os.path.join(TEMPLATES_PATH, 'electron'), no_input=True, extra_context=config) if not args.without_cordova: cookiecutter(os.path.join(TEMPLATES_PATH, 'cordova'), no_input=True, extra_context=config) if not args.without_flask: cookiecutter(os.path.join(TEMPLATES_PATH, 'flask'), no_input=True, extra_context=config) shell('npm install {} --no-save'.format( os.path.join(os.path.dirname(__file__), 'js')))
def generate_cookiecutter_context( template_git_url: str, cookiecutter_template_dir: Path, config_file: Optional[Path] = None, default_config: bool = False, extra_context: Optional[Dict[str, Any]] = None, no_input: bool = False, ) -> CookiecutterContext: _validate_cookiecutter(cookiecutter_template_dir) context_file = cookiecutter_template_dir / "cookiecutter.json" config_dict = get_user_config( config_file=str(config_file) if config_file else None, default_config=default_config) context = generate_context( context_file=context_file, default_context=config_dict["default_context"], extra_context=extra_context, ) # prompt the user to manually configure at the command line. # except when 'no-input' flag is set context["cookiecutter"] = prompt_for_config(context, no_input) context["cookiecutter"]["_template"] = template_git_url return context
def test_default_context_replacement_in_generate_context(): """Verify default content settings are correctly replaced by template settings. Make sure that the default for list variables of `orientation` is based on the user config (`choices_template.json`) and not changed to a single value from `default_context`. """ expected_context = { 'choices_template': OrderedDict([ ('full_name', 'Raphael Pierzina'), ('github_username', 'hackebrot'), ('project_name', 'Kivy Project'), ('repo_name', '{{cookiecutter.project_name|lower}}'), ('orientation', ['landscape', 'all', 'portrait']), ]) } generated_context = generate.generate_context( context_file='tests/test-generate-context/choices_template.json', default_context={ 'not_in_template': 'foobar', 'project_name': 'Kivy Project', 'orientation': 'landscape', }, extra_context={ 'also_not_in_template': 'foobar2', 'github_username': '******', }, ) assert generated_context == expected_context
def main(): repo_dir = sys.argv[1] user_config_path = sys.argv[2] user_config_path = user_config_path if os.path.isfile(user_config_path) else None context_file = os.path.join(repo_dir, 'cookiecutter.json') config_dict = get_user_config(user_config_path) context = generate_context(context_file, config_dict['default_context']) print(json.dumps(context))
def _custom_cookiecutter(template, output_dir, project_slug, package_slug): config_dict = get_user_config( config_file=None, default_config=False, ) template_name = os.path.splitext(os.path.basename(template))[0] repo_dir = os.path.join(config_dict['cookiecutters_dir'], template_name) if os.path.isdir(repo_dir): purge_dir(repo_dir) repo_dir, _ = determine_repo_dir( template=template, abbreviations=config_dict['abbreviations'], clone_to_dir=config_dict['cookiecutters_dir'], checkout=None, no_input=False, password=None, directory=None, ) context_file = os.path.join(repo_dir, 'cookiecutter.json') context = generate_context( context_file=context_file, default_context=config_dict['default_context'], extra_context=None, ) answers = dialogus( ADD_REPORT_QUESTIONS, 'Add report to existing project', intro=REPORT_ADD_WIZARD_INTRO, summary=REPORT_SUMMARY, finish_text='Add', previous_text='Back', ) if not answers: raise ClickException('Aborted by user input') context['cookiecutter']['_template'] = template context['cookiecutter']['project_slug'] = project_slug context['cookiecutter']['package_slug'] = package_slug context['cookiecutter']['initial_report_name'] = answers[ 'initial_report_name'] context['cookiecutter']['initial_report_slug'] = answers[ 'initial_report_slug'] context['cookiecutter']['initial_report_description'] = answers[ 'initial_report_description'] context['cookiecutter']['initial_report_renderer'] = answers[ 'initial_report_renderer'] result = _generate_files(context, output_dir, repo_dir) return result, context['cookiecutter']['initial_report_slug']
def test_generate_context_decodes_non_ascii_chars(monkeypatch): """Verify `generate_context` correctly decodes non-ascii chars.""" monkeypatch.chdir(os.path.join(os.path.abspath(os.path.dirname(__file__)))) expected_context = {'non_ascii': OrderedDict([('full_name', u'éèà ')])} generated_context = generate.generate_context( context_file='test-generate-context/non_ascii.json') assert generated_context == expected_context
def create( template_git_url: str, output_dir: str = ".", config_file: Optional[str] = None, default_config: bool = False, extra_context: Optional[dict] = None, no_input: bool = False, overwrite_if_exists: bool = False, ) -> str: """Expand a Git based Cookiecutter template into a new project on disk.""" with TemporaryDirectory() as cookiecutter_template_dir_str: cookiecutter_template_dir = Path(cookiecutter_template_dir_str) try: repo = Repo.clone_from(template_git_url, cookiecutter_template_dir) last_commit = repo.head.object.hexsha except Exception as e: raise InvalidCookiecutterRepository(e) main_cookiecutter_directory: Optional[Path] = None for dir_item in cookiecutter_template_dir.glob("*cookiecutter.*"): if dir_item.is_dir( ) and "{{" in dir_item.name and "}}" in dir_item.name: main_cookiecutter_directory = dir_item break if not main_cookiecutter_directory: # pragma: no cover raise UnableToFindCookiecutterTemplate(cookiecutter_template_dir) context_file = cookiecutter_template_dir / "cookiecutter.json" config_dict = get_user_config(config_file=config_file, default_config=default_config) context = generate_context( context_file=str(context_file), default_context=config_dict["default_context"], extra_context=extra_context, ) # prompt the user to manually configure at the command line. # except when 'no-input' flag is set context["cookiecutter"] = prompt_for_config(context, no_input) context["cookiecutter"]["_template"] = template_git_url (main_cookiecutter_directory / ".cruft.json").write_text( json_dumps({ "template": template_git_url, "commit": last_commit, "context": context })) return generate_files( repo_dir=cookiecutter_template_dir, context=context, overwrite_if_exists=overwrite_if_exists, output_dir=output_dir, )
def test_generate_context_with_default_and_extra(self): """ Call `generate_context()` with `default_context` and `extra_context`. """ context = generate.generate_context( context_file='tests/test-generate-context/test.json', default_context={'1': 3}, extra_context={'1': 5}, ) self.assertEqual(context, {'test': {'1': 5, 'some_key': 'some_val'}})
def render_file_template(template_path, use_defaults=False, extra_context=None): """Render a single-file template with Cookiecutter. Currently this function only renders a file using default values defined in a ``cookiecutter.json`` file. Parameters ---------- template_path : `str` Path to the file template. There should be a ``cookecutter.json`` in the same directory as the template file. This JSON file is used to define a provide defaults for the template's variables. use_defaults : `bool`, optional Disables Sphinx from interactively prompting for context variables, if `True`. extra_context : `dict`, optional Optional dictionary of key-value pairs that override defaults in the ``cookiecutter.json`` file. Returns ------- rendered_text : `str` Content rendered from the template and ``cookiecutter.json`` defaults. """ logger = logging.getLogger(__name__) logger.debug('Rendering file template %s', template_path) # Get variables for rendering the template template_dir = os.path.dirname(template_path) context_file = os.path.join(template_dir, 'cookiecutter.json') context = generate_context(context_file=context_file) context['cookiecutter'] = prompt_for_config(context, use_defaults) if extra_context is not None: context['cookiecutter'].update(extra_context) # Jinja2 template rendering environment env = StrictEnvironment( context=context, keep_trailing_newline=True, ) env.loader = FileSystemLoader(template_dir) try: tmpl = env.get_template(os.path.basename(template_path)) except TemplateSyntaxError as exception: # Disable translated so that printed exception contains verbose # information about syntax error location exception.translated = False raise rendered_text = tmpl.render(**context) return rendered_text
def test_exception_when_output_folder_exists(): context = generate.generate_context( context_file='tests/test-output-folder/cookiecutter.json') output_folder = context['cookiecutter']['test_name'] if not os.path.exists(output_folder): os.makedirs(output_folder) with pytest.raises(exceptions.OutputDirExistsException): generate.generate_files(context=context, repo_dir='tests/test-output-folder')
def test_generate_context_decodes_non_ascii_chars(): """Verify `generate_context` correctly decodes non-ascii chars.""" expected_context = { 'non_ascii': OrderedDict([ ('full_name', 'éèà '), ]) } generated_context = generate.generate_context( context_file='tests/test-generate-context/non_ascii.json') assert generated_context == expected_context
def test_exception_when_output_folder_exists(monkeypatch): """Tests should raise error as output folder created before `generate_files`.""" monkeypatch.chdir(os.path.join(os.path.abspath(os.path.dirname(__file__)))) context = generate.generate_context( context_file='test-output-folder/cookiecutter.json') output_folder = context['cookiecutter']['test_name'] if not os.path.exists(output_folder): os.makedirs(output_folder) with pytest.raises(exceptions.OutputDirExistsException): generate.generate_files(context=context, repo_dir='test-output-folder')
def test_exception_when_output_folder_exists(): context = generate.generate_context( context_file='tests/test-output-folder/cookiecutter.json' ) output_folder = context['cookiecutter']['test_name'] if not os.path.exists(output_folder): os.makedirs(output_folder) with pytest.raises(exceptions.OutputDirExistsException): generate.generate_files( context=context, repo_dir='tests/test-output-folder' )
def _prepare_cookiecutter_env(cookiecutter_dir) -> _CookiecutterEnv: """Prepare the cookiecutter environment to render its default values when prompting user on the CLI for inputs. """ # pylint: disable=import-outside-toplevel from cookiecutter.environment import StrictEnvironment from cookiecutter.generate import generate_context cookiecutter_json = cookiecutter_dir / "cookiecutter.json" cookiecutter_context = generate_context( context_file=cookiecutter_json).get("cookiecutter", {}) cookiecutter_env = StrictEnvironment(context=cookiecutter_context) return _CookiecutterEnv(context=cookiecutter_context, env=cookiecutter_env)
def cookiecutter(template, checkout=None, no_input=False, extra_context=None): """ Replacement for cookiecutter's own cookiecutter. The difference with cookiecutter's cookiecutter function is that this one doesn't automatically str() all the values passed along to the template. :param template: A directory containing a project template directory, or a URL to a git repository. :param checkout: The branch, tag or commit ID to checkout after clone. :param no_input: Prompt the user at command line for manual configuration? :param extra_context: A dictionary of context that overrides default and user configuration. """ # Get user config from ~/.cookiecutterrc or equivalent # If no config file, sensible defaults from config.DEFAULT_CONFIG are used config_dict = get_user_config() template = expand_abbreviations(template, config_dict) # TODO: find a better way to tell if it's a repo URL if 'git@' in template or 'https://' in template: repo_dir = clone( repo_url=template, checkout=checkout, clone_to_dir=config_dict['cookiecutters_dir'], no_input=no_input ) else: # If it's a local repo, no need to clone or copy to your # cookiecutters_dir repo_dir = template context_file = os.path.join(repo_dir, 'cookiecutter.json') logging.debug('context_file is {0}'.format(context_file)) context = generate_context( context_file=context_file, default_context=config_dict['default_context'], extra_context=extra_context, ) # Create project from local context and project template. generate_files( repo_dir=repo_dir, context=context )
def main(): repo_dir = sys.argv[1] user_config_path = sys.argv[2] user_config_path = user_config_path if os.path.isfile(user_config_path) else None output_folder_path = sys.argv[3] context_json_path = sys.argv[4] extra_context = json.load(open(context_json_path, 'r')) context_file = os.path.join(repo_dir, 'cookiecutter.json') config_dict = get_user_config(user_config_path) context = generate_context(context_file, config_dict['default_context'], extra_context=extra_context) rendered_context = render_context(context, output_folder_path) print(json.dumps(rendered_context))
def __init__(self, run_id='run_0001', model=None, template=None, checkout=None, settings=None, output_dir=None): self.model = model self.run_id = run_id self.template = template self.checkout = checkout self.output_dir = output_dir self.staging_dir = self.output_dir + '/' + self.run_id # The following code is mostly lifted from https://github.com/cookiecutter/cookiecutter/blob/master/cookiecutter/main.py # Load cookie-cutter config - see https://cookiecutter.readthedocs.io/en/1.7.0/advanced/user_config.html config_dict = cc_config.get_user_config( config_file=None, default_config=False, ) self._repo_dir, cleanup = cc_repository.determine_repo_dir( template=template, abbreviations=config_dict['abbreviations'], clone_to_dir=config_dict['cookiecutters_dir'], checkout=checkout, no_input=True) context_file = os.path.join(self._repo_dir, 'cookiecutter.json') logger.debug('context_file is {}'.format(context_file)) context = cc_generate.generate_context( context_file=context_file, default_context=config_dict['default_context'], extra_context=settings) print('Default context: (from cookiecutter.json)') pprint.pprint(context['cookiecutter']) self.default_context = context['cookiecutter'] if settings is None: self.settings = {} self.settings['_template'] = template self.settings['_checkout'] = checkout self.settings['model'] = model if not os.path.isdir(self.staging_dir): os.makedirs(self.staging_dir + '/downloads')
def test_output_folder(self): context = generate.generate_context(context_file="tests/test-output-folder/cookiecutter.json") logging.debug("Context is {0}".format(context)) generate.generate_files(context=context, repo_dir="tests/test-output-folder") something = """Hi! My name is Audrey Greenfeld. It is 2014.""" something2 = open("output_folder/something.txt").read() self.assertEqual(something, something2) in_folder = "The color is green and the letter is D." in_folder2 = open("output_folder/folder/in_folder.txt").read() self.assertEqual(in_folder, in_folder2) self.assertTrue(os.path.isdir("output_folder/im_a.dir")) self.assertTrue(os.path.isfile("output_folder/im_a.dir/im_a.file.py"))
def test_choices(context_file, default_context, extra_context): """Make sure that the default for list variables is based on the user \ config and the list as such is not changed to a single value.""" expected_context = { 'choices_template': OrderedDict([ ('full_name', 'Raphael Pierzina'), ('github_username', 'hackebrot'), ('project_name', 'Kivy Project'), ('repo_name', '{{cookiecutter.project_name|lower}}'), ('orientation', ['landscape', 'all', 'portrait']), ]) } generated_context = generate.generate_context( context_file, default_context, extra_context ) assert generated_context == expected_context
def test_output_folder(): context = generate.generate_context( context_file='tests/test-output-folder/cookiecutter.json') generate.generate_files(context=context, repo_dir='tests/test-output-folder') something = """Hi! My name is Audrey Greenfeld. It is 2014.""" something2 = open('output_folder/something.txt').read() assert something == something2 in_folder = "The color is green and the letter is D." in_folder2 = open('output_folder/folder/in_folder.txt').read() assert in_folder == in_folder2 assert os.path.isdir('output_folder/im_a.dir') assert os.path.isfile('output_folder/im_a.dir/im_a.file.py')
def cookiecutter(template, checkout=None, no_input=False, extra_context=None): """ Replacement for cookiecutter's own cookiecutter. The difference with cookiecutter's cookiecutter function is that this one doesn't automatically str() all the values passed along to the template. :param template: A directory containing a project template directory, or a URL to a git repository. :param checkout: The branch, tag or commit ID to checkout after clone. :param no_input: Prompt the user at command line for manual configuration? :param extra_context: A dictionary of context that overrides default and user configuration. """ # Get user config from ~/.cookiecutterrc or equivalent # If no config file, sensible defaults from config.DEFAULT_CONFIG are used config_dict = get_user_config() template = expand_abbreviations(template, config_dict) # TODO: find a better way to tell if it's a repo URL if 'git@' in template or 'https://' in template: repo_dir = clone(repo_url=template, checkout=checkout, clone_to_dir=config_dict['cookiecutters_dir'], no_input=no_input) else: # If it's a local repo, no need to clone or copy to your # cookiecutters_dir repo_dir = template context_file = os.path.join(repo_dir, 'cookiecutter.json') logging.debug('context_file is {0}'.format(context_file)) context = generate_context( context_file=context_file, default_context=config_dict['default_context'], extra_context=extra_context, ) # Create project from local context and project template. generate_files(repo_dir=repo_dir, context=context)
def test_output_folder(monkeypatch): """Tests should correctly create content, as output_folder does not yet exist.""" monkeypatch.chdir(os.path.join(os.path.abspath(os.path.dirname(__file__)))) context = generate.generate_context( context_file='test-output-folder/cookiecutter.json') generate.generate_files(context=context, repo_dir='test-output-folder') something = """Hi! My name is Audrey Greenfeld. It is 2014.""" something2 = open('output_folder/something.txt').read() assert something == something2 in_folder = "The color is green and the letter is D." in_folder2 = open('output_folder/folder/in_folder.txt').read() assert in_folder == in_folder2 assert os.path.isdir('output_folder/im_a.dir') assert os.path.isfile('output_folder/im_a.dir/im_a.file.py')
def test_choices(context_file, default_context, extra_context): """Make sure that the default for list variables is based on the user config and the list as such is not changed to a single value. """ expected_context = { 'choices_template': OrderedDict([ ('full_name', 'Raphael Pierzina'), ('github_username', 'hackebrot'), ('project_name', 'Kivy Project'), ('repo_name', '{{cookiecutter.project_name|lower}}'), ('orientation', ['landscape', 'all', 'portrait']), ]) } generated_context = generate.generate_context( context_file, default_context, extra_context ) assert generated_context == expected_context
def test_choices(context_file, default_context, extra_context): """Make sure that the default for list variables is based on the user \ config and the list as such is not changed to a single value.""" expected_context = { "choices_template": OrderedDict([ ("full_name", "Raphael Pierzina"), ("github_username", "hackebrot"), ("project_name", "Kivy Project"), ("repo_name", "{{cookiecutter.project_name|lower}}"), ("orientation", ["landscape", "all", "portrait"]), ]) } generated_context = generate.generate_context(context_file, default_context, extra_context) assert generated_context == expected_context
def _generate_output( context_file: str, cruft_state: dict, cookiecutter_input: bool, template_dir: str, output_dir: str, ) -> dict: context = generate_context( context_file=context_file, extra_context=cruft_state["context"]["cookiecutter"]) context["cookiecutter"] = prompt_for_config(context, not cookiecutter_input) context["cookiecutter"]["_template"] = cruft_state["template"] generate_files(repo_dir=template_dir, context=context, overwrite_if_exists=True, output_dir=output_dir) return context
def test_output_folder(self): context = generate.generate_context( context_file='tests/test-output-folder/cookiecutter.json') logging.debug('Context is {0}'.format(context)) generate.generate_files(context=context, repo_dir='tests/test-output-folder') something = """Hi! My name is Audrey Greenfeld. It is 2014.""" something2 = open('output_folder/something.txt').read() self.assertEqual(something, something2) in_folder = "The color is green and the letter is D." in_folder2 = open('output_folder/folder/in_folder.txt').read() self.assertEqual(in_folder, in_folder2) self.assertTrue(os.path.isdir('output_folder/im_a.dir')) self.assertTrue(os.path.isfile('output_folder/im_a.dir/im_a.file.py'))
def test_output_folder(self): context = generate.generate_context(config_file='tests/json2/stuff.json') logging.debug('Context is {0}'.format(context)) generate.generate_files( context=context, template_dir='tests/input{{stuff.color}}' ) something = """Hi! My name is Audrey Greenfeld. It is 2014.""" something2 = open('tests/inputgreen/something.txt').read() self.assertEqual(something, something2) in_folder = "The color is green and the letter is D." in_folder2 = open('tests/inputgreen/folder/in_folder.txt').read() self.assertEqual(in_folder, in_folder2) self.assertTrue(os.path.isdir('tests/inputgreen/im_a.dir')) self.assertTrue(os.path.isfile('tests/inputgreen/im_a.dir/im_a.file.py'))
def test_output_folder(): context = generate.generate_context( context_file='tests/test-output-folder/cookiecutter.json' ) generate.generate_files( context=context, repo_dir='tests/test-output-folder' ) something = """Hi! My name is Audrey Greenfeld. It is 2014.""" something2 = open('output_folder/something.txt').read() assert something == something2 in_folder = "The color is green and the letter is D." in_folder2 = open('output_folder/folder/in_folder.txt').read() assert in_folder == in_folder2 assert os.path.isdir('output_folder/im_a.dir') assert os.path.isfile('output_folder/im_a.dir/im_a.file.py')
def test_generate_context(self): context = generate.generate_context(config_file='tests/json/test.json') self.assertEqual(context, {"test": {"1": 2}})
def test_generate_context(input_params, expected_context): """ Test the generated context for several input parameters against the according expected context. """ assert generate.generate_context(**input_params) == expected_context
def test_generate_context_with_default(self): context = generate.generate_context( context_file='tests/test-generate-context/test.json', default_context={"1": 3} ) self.assertEqual(context, {"test": {"1": 3, "some_key": "some_val"}})
def test_generate_context(self): context = generate.generate_context( context_file='tests/test-generate-context/test.json' ) self.assertEqual(context, {"test": {"1": 2, "some_key": "some_val"}})
def cookiepatch(): parser = argparse.ArgumentParser(description='Tool to apply / create patch from ' 'cookiecutter templates') parser.add_argument('--template', type=str, help='an integer for the accumulator') parser.add_argument('--diff', type=str, nargs='+', help='versions passed for git diff') parser.add_argument('--show', action='store_true', help='Just print diff') args = parser.parse_args() conf_file = None if os.path.exists(CONF_PATH): with open(CONF_PATH) as f: conf_file = json.load(f) if args.template: template = args.template elif conf_file and 'template' in conf_file: template = conf_file['template'] else: template = input('Input template repository url: ') if args.diff: diff = args.diff elif conf_file and 'revision' in conf_file: diff = [conf_file['revision']] else: cur = input('Input template version applied currently: ') to = input('Input version to follow [master]: ') or 'master' diff = [cur, to] no_input = False config_dict = get_user_config(config_file=USER_CONFIG_PATH) parsed_template = expand_abbreviations(template, config_dict) repo_dir = clone(repo_url=parsed_template, clone_to_dir=config_dict['cookiecutters_dir'], checkout=None, no_input=no_input) patch_bytes = subprocess.check_output(['git', 'diff'] + diff + ['--', '{{cookiecutter.repo_name}}'], cwd=repo_dir) patch_str = patch_bytes.decode() context_file = os.path.join(repo_dir, 'cookiecutter.json') context = generate_context( context_file=context_file, default_context=config_dict['default_context'], extra_context={}, ) if conf_file: context['cookiecutter'] = conf_file['variables'] else: # prompt the user to manually configure at the command line. # except when 'no-input' flag is set context['cookiecutter'] = prompt_for_config(context, no_input) rendered = Template(patch_str).render(**context) if args.show: print(rendered) return p = subprocess.Popen(['patch', '-Np1', '--no-backup-if-mismatch'], stdin=subprocess.PIPE, cwd='..') p.communicate(rendered.encode()) # Generate cookiepatcher JSON if len(diff) == 1: rev = 'HEAD' else: rev = diff[-1] revision_bytes = subprocess.check_output(['git', 'rev-parse'] + [rev], cwd=repo_dir) revision_str = revision_bytes.decode().rstrip('\n') json_content = { 'revision': revision_str, 'variables': context['cookiecutter'], 'template': template } with open(CONF_PATH, 'w') as f: json.dump(json_content, f, ensure_ascii=False, indent=2, sort_keys=True)