{"id":15653213,"url":"https://github.com/cjolowicz/retrocookie","last_synced_at":"2025-04-23T13:43:17.579Z","repository":{"id":37201064,"uuid":"268014603","full_name":"cjolowicz/retrocookie","owner":"cjolowicz","description":"Retrocookie updates Cookiecutter templates with changes from generated projects","archived":false,"fork":false,"pushed_at":"2024-07-30T11:32:56.000Z","size":913,"stargazers_count":30,"open_issues_count":42,"forks_count":7,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-23T01:19:59.072Z","etag":null,"topics":["cookiecutter","git","python"],"latest_commit_sha":null,"homepage":"https://retrocookie.readthedocs.io","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cjolowicz.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":"CONTRIBUTING.rst","funding":null,"license":"LICENSE.rst","code_of_conduct":"CODE_OF_CONDUCT.rst","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-05-30T05:20:20.000Z","updated_at":"2025-04-16T12:09:03.000Z","dependencies_parsed_at":"2024-05-30T17:01:49.819Z","dependency_job_id":"48684bd4-e4de-4030-af86-735d8d48f279","html_url":"https://github.com/cjolowicz/retrocookie","commit_stats":{"total_commits":394,"total_committers":5,"mean_commits":78.8,"dds":"0.36802030456852797","last_synced_commit":"21ca5c40bdadd6b17a8dc24cdf1959008b1d8831"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cjolowicz%2Fretrocookie","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cjolowicz%2Fretrocookie/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cjolowicz%2Fretrocookie/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cjolowicz%2Fretrocookie/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cjolowicz","download_url":"https://codeload.github.com/cjolowicz/retrocookie/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250441350,"owners_count":21431158,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cookiecutter","git","python"],"created_at":"2024-10-03T12:44:59.021Z","updated_at":"2025-04-23T13:43:17.562Z","avatar_url":"https://github.com/cjolowicz.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"Retrocookie\n===========\n\n|PyPI| |Python Version| |License| |Read the Docs| |Tests| |Codecov|\n\n.. |PyPI| image:: https://img.shields.io/pypi/v/retrocookie.svg\n   :target: https://pypi.org/project/retrocookie/\n   :alt: PyPI\n.. |Python Version| image:: https://img.shields.io/pypi/pyversions/retrocookie\n   :target: https://pypi.org/project/retrocookie\n   :alt: Python Version\n.. |License| image:: https://img.shields.io/pypi/l/retrocookie\n   :target: https://opensource.org/licenses/MIT\n   :alt: License\n.. |Read the Docs| image:: https://img.shields.io/readthedocs/retrocookie/latest.svg?label=Read%20the%20Docs\n   :target: https://retrocookie.readthedocs.io/\n   :alt: Read the documentation at https://retrocookie.readthedocs.io/\n.. |Tests| image:: https://github.com/cjolowicz/retrocookie/workflows/Tests/badge.svg\n   :target: https://github.com/cjolowicz/retrocookie/actions?workflow=Tests\n   :alt: Tests\n.. |Codecov| image:: https://codecov.io/gh/cjolowicz/retrocookie/branch/main/graph/badge.svg\n   :target: https://codecov.io/gh/cjolowicz/retrocookie\n   :alt: Codecov\n\n\nRetrocookie updates Cookiecutter_ templates with changes from generated projects.\n\nWhen developing Cookiecutter templates,\nyou often need to work in a generated project rather than the template itself.\nReasons for this include the following:\n\n- You need to run the Continuous Integration suite for the generated project\n- Your development tools choke when running on the templated project\n\nAny changes you make in the generated project\nneed to be backported into the template,\ncarefully replacing expanded variables from ``cookiecutter.json`` by templating tags,\nand escaping any use of ``{{`` and ``}}``\nor other tokens with special meaning in Jinja.\n\n✨ Retrocookie helps you in this situation. ✨\n\nIt is designed to fetch commits from the repository of a generated project,\nand import them into your Cookiecutter repository,\nrewriting them on the fly to insert templating tags,\nescape Jinja-special constructs,\nand place files in the template directory.\n\nUnder the hood,\nRetrocookie rewrites the selected commits using git-filter-repo_,\nsaving them to a temporary repository.\nIt then fetches and cherry-picks the rewritten commits\nfrom the temporary repository into the Cookiecutter template,\nusing pygit2_.\n\nMaybe you're thinking,\nhow can this possibly work?\nOne cannot reconstruct a Jinja template from its rendered output.\nHowever, simple replacements of template variables work well in practice\nwhen you're only importing a handful of commits at a time.\n\n**Important:**\n\nRetrocookie relies on a ``.cookiecutter.json`` file in the generated project\nto work out how to rewrite commits.\nThis file is similar to the ``cookiecutter.json`` file in the template,\nbut contains the specific values chosen during project generation.\nYou can generate this file by putting it into the template directory in the Cookiecutter,\nwith the following contents:\n\n.. code:: jinja\n\n   {{ cookiecutter | jsonify }}\n\n\nRequirements\n------------\n\n* Python 3.8+\n* git \u003e= 2.22.0\n\n\nInstallation\n------------\n\nYou can install *Retrocookie* via pip_ from PyPI_:\n\n.. code:: console\n\n   $ pip install retrocookie\n\nOptionally, install the ``pr`` extra for the retrocookie-pr_ command:\n\n.. code:: console\n\n   $ pip install retrocookie[pr]\n\n\nExample\n-------\n\nHere's an example to demonstrate the general workflow.\n\nTo start with, we clone the repository of your Cookiecutter template.\nFor this example, I'll use my own `Hypermodern Python Cookiecutter`_.\n\n.. code:: console\n\n   $ git clone https://github.com/cjolowicz/cookiecutter-hypermodern-python\n\nNext, we'll create a project from the template,\nand set up a git repository for it:\n\n.. code:: console\n\n   $ cookiecutter --no-input cookiecutter-hypermodern-python\n   $ cd hypermodern-python\n   $ git init\n   $ git add .\n   $ git commit --message=\"Initial commit\"\n\nLet's open a feature branch in the project repository,\nand make a fictitious change involving the default project name *hypermodern-python*:\n\n.. code:: console\n\n   $ git switch --create add-example\n   $ echo '# hypermodern-python' \u003e EXAMPLE.md\n   $ git add EXAMPLE.md\n   $ git commit --message=\"Add example\"\n\nBack in the Cookiecutter repository,\nwe can now invoke retrocookie to import the changes from the feature branch:\n\n.. code:: console\n\n   $ cd ../cookiecutter-hypermodern-python\n   $ retrocookie --branch add-example --create ../hypermodern-python\n\nA ``git show`` in the Cookiecutter shows the file under the template directory,\non a branch named as in the original repository,\nwith the project name replaced by a Jinja tag:\n\n.. code:: diff\n\n   commit abb4f823b9f1760e3a678c927ec9797c0a40a9b6 (HEAD -\u003e add-example)\n   Author: Your Name \u003cyour.name@example.com\u003e\n   Date:   Fri Dec 4 23:40:41 2020 +0100\n\n       Add example\n\n   diff --git a/{{cookiecutter.project_name}}/EXAMPLE.md b/{{cookiecutter.project_name}}/EXAMPLE.md\n   new file mode 100644\n   index 0000000..a158618\n   --- /dev/null\n   +++ b/{{cookiecutter.project_name}}/EXAMPLE.md\n   @@ -0,0 +1 @@\n   +# {{cookiecutter.project_name}}\n\n\nUsage\n-----\n\nThe basic form:\n\n.. code::\n\n   $ retrocookie \u003crepository\u003e [\u003ccommits\u003e...]\n   $ retrocookie \u003crepository\u003e -b \u003cbranch\u003e [--create]\n\nThe ``\u003crepository\u003e`` is a filesystem path to the source repository.\nFor ``\u003ccommits\u003e``, see `gitrevisions(7)`__.\n\n__ https://git-scm.com/docs/gitrevisions\n\nImport ``HEAD`` from ``\u003crepository\u003e``:\n\n.. code::\n\n   $ retrocookie \u003crepository\u003e\n\nImport the last two commits:\n\n.. code::\n\n   $ retrocookie \u003crepository\u003e HEAD~2..\n\nImport by commit hash:\n\n.. code::\n\n   $ retrocookie \u003crepository\u003e 53268f7 6a3368a c0b4c6c\n\nImport commits from branch ``topic``:\n\n.. code::\n\n   $ retrocookie \u003crepository\u003e --branch=topic\n\nEquivalently:\n\n.. code::\n\n   $ retrocookie \u003crepository\u003e master..topic\n\nImport commits from ``topic`` into a branch with the same name:\n\n.. code::\n\n   $ retrocookie \u003crepository\u003e --branch=topic --create\n\nEquivalently, using short options:\n\n.. code::\n\n   $ retrocookie \u003crepository\u003e -cb topic\n\nImport commits from branch ``topic``, which was branched off ``1.0``:\n\n.. code::\n\n   $ retrocookie \u003crepository\u003e --branch=topic --upstream=1.0\n\nEquivalently:\n\n.. code::\n\n   $ retrocookie \u003crepository\u003e 1.0..topic\n\nImport ``HEAD`` into a new branch ``topic``:\n\n.. code::\n\n   $ retrocookie \u003crepository\u003e --create-branch=topic\n\nPlease see the `Command-line Reference \u003cUsage_\u003e`_ for further details.\n\n\n.. _retrocookie-pr:\n\nImporting pull requests from generated projects with retrocookie-pr\n-------------------------------------------------------------------\n\nYou can import pull requests from a generated project to the project template,\nassuming their repositories are on GitHub_.\nThis requires activating the ``pr`` extra when installing with pip_:\n\n.. code::\n\n  $ pip install retrocookie[pr]\n\nThe command ``retrocookie-pr`` has the basic form:\n\n.. code::\n\n   $ retrocookie-pr [-R \u003crepository\u003e] [\u003cpr\u003e...]\n   $ retrocookie-pr [-R \u003crepository\u003e] --user=\u003cuser\u003e\n   $ retrocookie-pr [-R \u003crepository\u003e] --all\n\nCommand-line arguments specify pull requests to import, by number or by branch.\nPull requests from forks are currently not supported.\n\nUse the ``-R \u003crepository\u003e`` option to specify the GitHub repository of the generated project\nfrom which the pull requests should be imported.\nProvide the full name of the repository on GitHub in the form ``owner/name``.\nThe owner can be omitted if the repository is owned by the authenticated user.\nThis option can be omitted when the command is invoked from a local clone.\n\nYou can also select pull requests by specifying the user that opened them, via the ``--user`` option.\nThis is handy for importing automated pull requests, such as dependency updates from Dependabot_.\n\nUse the ``--all`` option to import all open pull requests in the generated project.\n\nYou can update previously imported pull requests by specifying ``--force``.\nBy default, ``retrocookie-pr`` refuses to overwrite existing pull requests.\n\nThe command needs a `personal access token`_ to access the GitHub API.\n(This token is also used to push to the GitHub repository of the project template.)\nYou will be prompted for the token when you invoke the command for the first time.\nOn subsequent invocations, the token is read from the application cache.\nAlternatively, you can specify the token using the ``--token`` option or the ``GITHUB_TOKEN`` environment variable;\nboth of these methods bypass the cache.\n\nUse the ``--open`` option to open each imported pull request in a web browser.\n\nPlease see the `Command-line Reference \u003cUsage_\u003e`_ for further details.\n\n\nContributing\n------------\n\nContributions are very welcome.\nTo learn more, see the `Contributor Guide`_.\n\n\nLicense\n-------\n\nDistributed under the terms of the MIT_ license,\n*Retrocookie* is free and open source software.\n\n\nIssues\n------\n\nIf you encounter any problems,\nplease `file an issue`_ along with a detailed description.\n\n\nCredits\n-------\n\nThis project was generated from `@cjolowicz`_'s `Hypermodern Python Cookiecutter`_ template.\n\n\n.. _@cjolowicz: https://github.com/cjolowicz\n.. _Cookiecutter: https://github.com/audreyr/cookiecutter\n.. _Dependabot: https://dependabot.com/\n.. _GitHub: https://github.com/\n.. _Hypermodern Python Cookiecutter: https://github.com/cjolowicz/cookiecutter-hypermodern-python\n.. _MIT: http://opensource.org/licenses/MIT\n.. _PyPI: https://pypi.org/\n.. _file an issue: https://github.com/cjolowicz/retrocookie/issues\n.. _git-filter-repo: https://github.com/newren/git-filter-repo\n.. _git rebase: https://git-scm.com/docs/git-rebase\n.. _pip: https://pip.pypa.io/\n.. _personal access token: https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/creating-a-personal-access-token\n.. _pygit2: https://github.com/libgit2/pygit2\n.. github-only\n.. _Contributor Guide: CONTRIBUTING.rst\n.. _Usage: https://retrocookie.readthedocs.io/en/latest/usage.html\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcjolowicz%2Fretrocookie","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcjolowicz%2Fretrocookie","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcjolowicz%2Fretrocookie/lists"}