├── {{cookiecutter.directory_name}} └── {{cookiecutter.file_name}}.py ├── cookiecutter.json ├── .gitattributes ├── .gitignore └── Readme.rst /{{cookiecutter.directory_name}}/{{cookiecutter.file_name}}.py: -------------------------------------------------------------------------------- 1 | print("Hello, {{cookiecutter.greeting_recipient}}!") -------------------------------------------------------------------------------- /cookiecutter.json: -------------------------------------------------------------------------------- 1 | { 2 | "directory_name": "Hello", 3 | "file_name": "Howdy", 4 | "greeting_recipient": "Julie" 5 | } -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear in the root of a volume 35 | .DocumentRevisions-V100 36 | .fseventsd 37 | .Spotlight-V100 38 | .TemporaryItems 39 | .Trashes 40 | .VolumeIcon.icns 41 | 42 | # Directories potentially created on remote AFP share 43 | .AppleDB 44 | .AppleDesktop 45 | Network Trash Folder 46 | Temporary Items 47 | .apdisk 48 | -------------------------------------------------------------------------------- /Readme.rst: -------------------------------------------------------------------------------- 1 | =========================================================== 2 | Learn the Basics of Cookiecutter by Creating a Cookiecutter 3 | =========================================================== 4 | 5 | The easiest way to understand what Cookiecutter does is to create a simple one 6 | and see how it works. 7 | 8 | Cookiecutter takes a source directory tree and copies it into your new 9 | project. It replaces all the names that it finds surrounded by *templating 10 | tags* ``{{`` and ``}}`` with names that it finds in the file 11 | ``cookiecutter.json``. That's basically it. [1]_ 12 | 13 | The replaced names can be file names, directory names, and strings inside 14 | files. 15 | 16 | With Cookiecutter, you can easily bootstrap a new project from a standard 17 | form, which means you skip all the usual mistakes when starting a new 18 | project. 19 | 20 | Before you can do anything in this example, you must have Python installed on 21 | your machine. Go to the `Python Website `_ and follow 22 | the instructions there. This includes the ``pip`` installer tool. Now run: 23 | 24 | .. code-block:: bash 25 | 26 | $ pip install cookiecutter 27 | 28 | Your First Cookiecutter 29 | ----------------------- 30 | 31 | To get started, create a directory somewhere on your computer. The name of 32 | this directory will be the name of your Cookiecutter template, but it doesn't 33 | constrain anything else---the generated project doesn't need to use the 34 | template name, for example. Our project will be called ``HelloCookieCutter1``: 35 | 36 | .. code-block:: bash 37 | 38 | $ mkdir HelloCookieCutter1 39 | $ cd HelloCookieCutter1 40 | 41 | Inside this directory, we create the directory tree to be copied into the 42 | generated project. We want to generate a name for this directory, so we put 43 | the directory name in templating tags ``{{`` and ``}}`` (yes, you type the 44 | double-curly-braces onto the command line, just as you see them here): [2]_ 45 | 46 | .. code-block:: bash 47 | 48 | $ mkdir {{cookiecutter.directory_name}} 49 | $ cd {{cookiecutter.directory_name}} 50 | 51 | Anything inside templating tags can be placed inside a *namespace*. Here, by 52 | putting ``directory_name`` inside the ``cookiecutter`` namespace, 53 | ``cookiecutter.directory_name`` will be looked up from the ``cookiecutter.json`` 54 | file as the project is generated by Cookiecutter. 55 | 56 | Now we are inside the directory tree that will be copied. For the simplest 57 | possible Cookiecutter template, we'll just include a single file. Again, we 58 | want the file name to be looked up from ``cookiecutter.json``, so we name it 59 | appropriately: 60 | 61 | .. code-block:: bash 62 | 63 | $ touch {{cookiecutter.file_name}}.py 64 | 65 | (``touch`` creates an empty file; you can just open it up in your editor). Now 66 | edit the file so it contains: 67 | 68 | .. code-block:: python 69 | 70 | print("Hello, {{cookiecutter.greeting_recipient}}!") 71 | 72 | To finish, we create the ``cookiecutter.json`` file itself, so that 73 | Cookiecutter can look up all our templated items. This file goes in our 74 | ``HelloCookieCutter1`` directory, and contains all the names we've used: 75 | 76 | .. code-block:: json 77 | 78 | { 79 | "directory_name": "Hello", 80 | "file_name": "Howdy", 81 | "greeting_recipient": "Julie" 82 | } 83 | 84 | Now we can actually run Cookiecutter and create a new project from our 85 | template. Move to a directory where you want to create the new project. Then 86 | run Cookiecutter and hand it the directory where the template lives. On my 87 | (Windows, so the slashes go back instead of forward) machine, this happens to 88 | be under the ``Git`` directory: 89 | 90 | .. code-block:: bash 91 | 92 | $ cookiecutter C:\Users\bruce\Documents\Git\HelloCookieCutter1 93 | directory_name [Hello]: 94 | file_name [Howdy]: 95 | greeting_recipient [Julie]: 96 | 97 | Cookiecutter tells us what the default name for each item is, and gives us the 98 | option of replacing that name with something new. In this case, I just pressed 99 | ``Return`` for each one, to accept all the defaults. 100 | 101 | Now we have a generated directory called ``Hello``, containing a file 102 | ``Howdy.py``. When we run it: 103 | 104 | .. code-block:: bash 105 | 106 | $ cd Hello 107 | $ python Howdy.py 108 | Hello, Julie! 109 | 110 | Voila! Instant generated project! 111 | 112 | **Note**: The project we've created here happens to be Python, but 113 | Cookiecutter is just replacing templated items with names it looks up in 114 | ``cookiecutter.json``, so you can produce projects of any kind, including 115 | projects that aren't programs. 116 | 117 | This is nice, but what if you want to share your Cookiecutter template with 118 | everyone on the Internet? The easiest way is to upload it to a version control 119 | repository. As you might have guessed by the ``Git`` subdirectory, this 120 | example is on GitHub. Conveniently, Cookiecutter can build a project directly 121 | from an internet repository, like the one for this very example. For variety, 122 | this time we'll replace the values from ``cookiecutter.json`` with our own: 123 | 124 | .. code-block:: bash 125 | 126 | $ cookiecutter https://github.com/BruceEckel/HelloCookieCutter1 127 | Cloning into 'HelloCookieCutter1'... 128 | remote: Counting objects: 37, done. 129 | Unpacking objects: 21% (8/37) 130 | remote: Total 37 (delta 19), reused 21 (delta 3), pack-reused 0 131 | Unpacking objects: 100% (37/37), done. 132 | Checking connectivity... done. 133 | directory_name [Hello]: Fabulous 134 | file_name [Howdy]: Zing 135 | greeting_recipient [Julie]: Roscoe 136 | 137 | $ cd Fabulous 138 | 139 | $ python Zing.py 140 | Hello, Roscoe! 141 | 142 | Same effect, but this time produced from the Internet! You'll notice that even 143 | though it says ``Cloning into 'HelloCookieCutter1'...``, you don't see any 144 | directory called ``HelloCookieCutter1`` in your local directory. Cookiecutter 145 | has its own storage area for cookiecutters, which is in your home directory 146 | in a subdirectory called ``.cookiecutters`` (the leading ``.`` hides the directory 147 | on most operating systems). You don't need to do anything with this directory 148 | but it can sometimes be useful to know where it is. 149 | 150 | Now if you ever find yourself duplicating effort when starting new projects, 151 | you'll know how to eliminate that duplication using cookiecutter. But even 152 | better, lots of people have created and published cookiecutters, so when you 153 | are starting a new project, make sure you look at the `list of pre-defined 154 | cookiecutters 155 | `_ 156 | first! 157 | 158 | .. [1] You can also run *hooks* before and/or after generation, but that's 159 | more complex than what we want to cover here. 160 | 161 | .. [2] Note that in some shells, you will need to put quote marks around the 162 | double curly braces to prevent them from being misinterpreted 163 | according to the shell's variable substition rules. Use this 164 | syntax if you encounter the error, "Cannot evaluate parameter 165 | Path' because its argument is specified as a script block and 166 | there is no input": 167 | 168 | .. code-block:: powershell 169 | 170 | $ mkdir "{{cookiecutter.directory_name}}" 171 | $ cd "{{cookiecutter.directory_name}}" 172 | --------------------------------------------------------------------------------