File: mkdir.rst

package info (click to toggle)
python-ruffus 2.6.3%2Bdfsg-4
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 20,828 kB
  • ctags: 2,843
  • sloc: python: 15,745; makefile: 180; sh: 14
file content (152 lines) | stat: -rw-r--r-- 7,333 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
.. include:: ../../global.inc
.. include:: manual_chapter_numbers.inc

.. index::
    pair: mkdir; Tutorial

.. _new_manual.mkdir:

######################################################################################################################################################################
|new_manual.mkdir.chapter_num|: Preparing directories for output with :ref:`@mkdir() <decorators.mkdir>`
######################################################################################################################################################################

.. seealso::

   * :ref:`Manual Table of Contents <new_manual.table_of_contents>`
   * :ref:`@follows(mkdir()) syntax in detail <decorators.follows>`
   * :ref:`@mkdir syntax in detail <decorators.mkdir>`

.. note::

    Remember to look at the example code:

        * :ref:`new_manual.mkdir.code`


***************************************
Overview
***************************************

    In |new_manual.transform_in_parallel.chapter_num|, we saw that we could use :ref:`@follows(mkdir()) <new_manual.follows.mkdir>` to
    ensure that output directories exist:

    .. code-block:: python
        :emphasize-lines: 4

        #
        #   create_new_files() @follows mkdir
        #
        @follows(mkdir("output/results/here"))
        @originate(["output/results/here/a.start_file",
                    "output/results/here/b.start_file"])
        def create_new_files(output_file_pair):
            pass


    This ensures that the decorated task follows (:ref:`@follows <new_manual.follows.mkdir>`) the
    making of the specified directory (``mkdir()``).

    Sometimes, however, the **Output** is intended not for any single directory but a group
    of destinations depending on the parsed contents of **Input** paths.

*********************************************************************************************************************
Creating directories after string substitution in a zoo...
*********************************************************************************************************************

    You may remember :ref:`this example <new_manual.output_file_names.formatter.zoo>` from |new_manual.output_file_names.chapter_num|:

    We want to feed the denizens of a zoo. The original file names are spread over several directories and we
    group their food supply by the *clade* of the animal in the following manner:

        .. image:: ../../images/simple_tutorial_zoo_animals_formatter_example.jpg
           :scale: 50

        .. code-block:: python
            :emphasize-lines: 13,14

            #   Put different animals in different directories depending on their clade
            @transform(create_initial_files,                                       # Input

                       formatter(".+/(?P<clade>\w+).(?P<tame>\w+).animals"),       # Only animals: ignore plants!

                       "{subpath[0][1]}/{clade[0]}/{tame[0]}.{subdir[0][0]}.food", # Replacement

                       "{subpath[0][1]}/{clade[0]}",                               # new_directory
                       "{subdir[0][0]}",                                           # animal_name
                       "{tame[0]}")                                                # tameness
            def feed(input_file, output_file, new_directory, animal_name, tameness):
                print "%40s -> %90s" % (input_file, output_file)
                # this blows up
                # open(output_file, "w")


    The example code from |new_manual.output_file_names.chapter_num| is, however, incomplete. If we were to actually create the specified
    files we would realise that we had forgotten to create the destination directories ``reptiles``, ``mammals`` first!

==============================================================================
using :ref:`formatter() <decorators.formatter>`
==============================================================================

    We could of course create directories manually.
    However, apart from being tedious and error prone, we have already gone to some lengths
    to parse out the diretories for :ref:`@transform <decorators.transform>`.
    Why don't we use the same logic to make the directories?

    Can you see the parallels between the syntax for :ref:`@mkdir <decorators.mkdir>` and :ref:`@transform <decorators.transform>`?

        .. code-block:: python

            # create directories for each clade
            @mkdir(    create_initial_files,                                       # Input

                       formatter(".+/(?P<clade>\w+).(?P<tame>\w+).animals"),       # Only animals: ignore plants!
                       "{subpath[0][1]}/{clade[0]})                                # new_directory

            #   Put animals of each clade in the same directory
            @transform(create_initial_files,                                       # Input

                       formatter(".+/(?P<clade>\w+).(?P<tame>\w+).animals"),       # Only animals: ignore plants!

                       "{subpath[0][1]}/{clade[0]}/{tame[0]}.{subdir[0][0]}.food", # Replacement

                       "{subpath[0][1]}/{clade[0]}",                               # new_directory
                       "{subdir[0][0]}",                                           # animal_name
                       "{tame[0]}")                                                # tameness
            def feed(input_file, output_file, new_directory, animal_name, tameness):
                print "%40s -> %90s" % (input_file, output_file)
                # this works now
                open(output_file, "w")

    See the :ref:`example code <new_manual.mkdir.code>`

==============================================================================
using :ref:`regex() <decorators.regex>`
==============================================================================

    If you are particularly fond of using regular expression to parse file paths,
    you could also use :ref:`regex() <decorators.regex>`:


        .. code-block:: python

            # create directories for each clade
            @mkdir(    create_initial_files,                                       # Input

                       regex(r"(.*?)/?(\w+)/(?P<clade>\w+).(?P<tame>\w+).animals"), # Only animals: ignore plants!
                       r"\1/\g<clade>")                                             # new_directory

            #   Put animals of each clade in the same directory
            @transform(create_initial_files,                                       # Input

                       formatter(".+/(?P<clade>\w+).(?P<tame>\w+).animals"),       # Only animals: ignore plants!

                       "{subpath[0][1]}/{clade[0]}/{tame[0]}.{subdir[0][0]}.food", # Replacement

                       "{subpath[0][1]}/{clade[0]}",                               # new_directory
                       "{subdir[0][0]}",                                           # animal_name
                       "{tame[0]}")                                                # tameness
            def feed(input_file, output_file, new_directory, animal_name, tameness):
                print "%40s -> %90s" % (input_file, output_file)
                # this works now
                open(output_file, "w")