Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UW-657 fs makedirs #572

Merged
merged 42 commits into from
Aug 21, 2024
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
c1ae271
WIP
maddenp-noaa Aug 10, 2024
9cd667d
Work on tests
maddenp-noaa Aug 10, 2024
5514c1e
Work on tests
maddenp-noaa Aug 10, 2024
8901b79
Work on tests
maddenp-noaa Aug 10, 2024
2b78d89
Work on tests
maddenp-noaa Aug 10, 2024
28472f8
WIP
maddenp-noaa Aug 10, 2024
ed73451
Add stage-dirs.jsonschema
maddenp-noaa Aug 10, 2024
1a5df26
Works
maddenp-noaa Aug 10, 2024
e2d7d6d
WIP
maddenp-noaa Aug 10, 2024
8e52ebb
Update docs
maddenp-noaa Aug 10, 2024
d0da865
Update docs
maddenp-noaa Aug 10, 2024
ffaeab4
WIP
maddenp-noaa Aug 12, 2024
b8d145a
WIP
maddenp-noaa Aug 12, 2024
219960f
WIP
maddenp-noaa Aug 12, 2024
ce2e4d4
WIP
maddenp-noaa Aug 12, 2024
dc7e828
WIP
maddenp-noaa Aug 12, 2024
778a2eb
Revert 'stage-files' to 'files-to-stage'
maddenp-noaa Aug 14, 2024
6e523e4
Reposition test block
maddenp-noaa Aug 14, 2024
b7ea345
Fix doc
maddenp-noaa Aug 14, 2024
e73ac23
Doc update
maddenp-noaa Aug 14, 2024
a2c92b6
Update docs/sections/user_guide/yaml/mkdir.rst
maddenp-noaa Aug 14, 2024
6068ad9
Update docstring
maddenp-noaa Aug 14, 2024
f615100
mkdir -> makedirs
maddenp-noaa Aug 15, 2024
d7c612e
Merge branch 'main' into uw-657-file-mkdir
maddenp-noaa Aug 16, 2024
9b9c944
Merge branch 'main' into uw-657-file-mkdir
maddenp-noaa Aug 16, 2024
09c6055
Merge branch 'main' into uw-657-file-mkdir
maddenp-noaa Aug 16, 2024
ad8a74e
Merge branch 'main' into uw-657-file-mkdir
maddenp-noaa Aug 18, 2024
ccfc3e5
Merge branch 'main' into uw-657-file-mkdir
maddenp-noaa Aug 19, 2024
d562142
Merge branch 'main' into uw-657-file-mkdir
maddenp-noaa Aug 20, 2024
e56c47d
Renames
maddenp-noaa Aug 20, 2024
7297e46
file -> fs
maddenp-noaa Aug 20, 2024
1802f37
WIP
maddenp-noaa Aug 20, 2024
04402ee
Renames
maddenp-noaa Aug 20, 2024
e08b0a7
file -> fs in docs
maddenp-noaa Aug 20, 2024
4e978b3
Work on docs
maddenp-noaa Aug 20, 2024
159709e
Work on docs
maddenp-noaa Aug 20, 2024
8e6bebb
Update mode fs description in CLI
maddenp-noaa Aug 20, 2024
23e37a1
Update docs
maddenp-noaa Aug 20, 2024
81db421
Doc update
maddenp-noaa Aug 20, 2024
dfca65a
Doc update
maddenp-noaa Aug 20, 2024
d7d79fd
Merge branch 'main' into uw-657-file-mkdir
maddenp-noaa Aug 20, 2024
5389215
Update docs/index.rst
maddenp-noaa Aug 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -71,22 +71,19 @@ This tool helps transform legacy configuration files templated with the atparse

| :any:`CLI documentation with examples<cli_template_translate_examples>`

File Provisioning
^^^^^^^^^^^^^^^^^
File/Directory Provisioning
maddenp-noaa marked this conversation as resolved.
Show resolved Hide resolved
^^^^^^^^^^^^^^^^^^^^^^^^^^^
maddenp-noaa marked this conversation as resolved.
Show resolved Hide resolved

This tool helps users define the source and destination of files to be copied or linked, in the same UW YAML language used by UW drivers.

| :any:`CLI documentation with examples<cli_file_copy_examples>`
This tool helps users define the source and destination of files to be copied or linked, or directories to be created, in the same UW YAML language used by UW drivers.

| :any:`CLI documentation with examples<cli_file_mode>`

There is a video demonstration of the use of the ``uw file`` tool available via YouTube.

.. raw:: html

<iframe width="560" height="315" src="https://www.youtube.com/embed/b2HXOlt-Ulw?si=rLWatBFu4mvNR65S" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

|

Rocoto Configurability
^^^^^^^^^^^^^^^^^^^^^^

Expand Down
46 changes: 42 additions & 4 deletions docs/sections/user_guide/cli/tools/file.rst
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
``file``
========

.. _cli_file_mode:
maddenp-noaa marked this conversation as resolved.
Show resolved Hide resolved

The ``uw`` mode for handling filesystem files.

.. literalinclude:: file/help.cmd
:emphasize-lines: 1
.. literalinclude:: file/help.out
:language: text

.. _cli_file_copy_examples:

``copy``
--------

Expand Down Expand Up @@ -52,8 +52,6 @@ The ``--target-dir`` option is optional when all destination paths are absolute,
.. literalinclude:: file/copy-exec-no-target-dir-err.out
:language: text

.. _cli_file_link_examples:

``link``
--------

Expand Down Expand Up @@ -95,3 +93,43 @@ The ``--target-dir`` option is optional when all linkname paths are absolute, an
:emphasize-lines: 1
.. literalinclude:: file/link-exec-no-target-dir-err.out
:language: text

``mkdir``
---------

The ``mkdir`` action creates directories. Any ``KEY`` positional arguments are used to navigate, in the order given, from the top of the config to the :ref:`mkdir block <mkdir_yaml>`.

.. literalinclude:: file/mkdir-help.cmd
:emphasize-lines: 1
.. literalinclude:: file/mkdir-help.out
:language: text

Examples
^^^^^^^^

Given ``mkdir-config.yaml`` containing

.. literalinclude:: file/mkdir-config.yaml
:language: yaml
.. literalinclude:: file/mkdir-exec.cmd
:emphasize-lines: 2
.. literalinclude:: file/mkdir-exec.out
:language: text

The ``--cycle`` and ``--leadtime`` options can be used to make Python ``datetime`` and ``timedelta`` objects, respectively, available for use in Jinja2 expression in the config. For example:

.. literalinclude:: file/mkdir-config-timedep.yaml
:language: yaml
.. literalinclude:: file/mkdir-exec-timedep.cmd
:emphasize-lines: 2
.. literalinclude:: file/mkdir-exec-timedep.out
:language: text

The ``--target-dir`` option is optional when all directory paths are absolute, and will never be applied to absolute linkname paths. If any linkname paths are relative, however, it is an error not to provide a target directory:

.. literalinclude:: file/mkdir-config.yaml
:language: yaml
.. literalinclude:: file/mkdir-exec-no-target-dir-err.cmd
:emphasize-lines: 1
.. literalinclude:: file/mkdir-exec-no-target-dir-err.out
:language: text
2 changes: 2 additions & 0 deletions docs/sections/user_guide/cli/tools/file/help.out
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@ Positional arguments:
Copy files
link
Link files
mkdir
Make directories
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
config:
mkdir:
- foo/{{ yyyymmdd }}/{{ hh }}/{{ nnn }}/bar
- baz/{{ yyyymmdd }}/{{ hh }}/{{ nnn }}/qux
yyyymmdd: "{{ cycle.strftime('%Y%m%d') }}"
hh: "{{ cycle.strftime('%H') }}"
nnn: "{{ '%03d' % (leadtime.total_seconds() // 3600) }}"
validtime: "{{ (cycle + leadtime).strftime('%Y-%m-%dT%H') }}"
4 changes: 4 additions & 0 deletions docs/sections/user_guide/cli/tools/file/mkdir-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
config:
mkdir:
- foo
- bar
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
uw file mkdir --config-file mkdir-config.yaml config
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[2024-08-12T04:35:49] INFO Validating config against internal schema: mkdir
[2024-08-12T04:35:49] INFO 0 UW schema-validation errors found
[2024-08-12T04:35:49] ERROR Relative path 'foo' requires the target directory to be specified
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
rm -rf mkdir-parent-timedep
uw file mkdir --target-dir mkdir-parent-timedep --config-file mkdir-config-timedep.yaml --cycle 2024-05-29T12 --leadtime 6 config
echo
tree -F mkdir-parent-timedep
29 changes: 29 additions & 0 deletions docs/sections/user_guide/cli/tools/file/mkdir-exec-timedep.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
[2024-08-12T04:35:49] INFO Validating config against internal schema: mkdir
[2024-08-12T04:35:49] INFO 0 UW schema-validation errors found
[2024-08-12T04:35:49] INFO Directories: Initial state: Not Ready
[2024-08-12T04:35:49] INFO Directories: Checking requirements
[2024-08-12T04:35:49] INFO Directory mkdir-parent-timedep/foo/20240529/12/006/bar: Initial state: Not Ready
[2024-08-12T04:35:49] INFO Directory mkdir-parent-timedep/foo/20240529/12/006/bar: Checking requirements
[2024-08-12T04:35:49] INFO Directory mkdir-parent-timedep/foo/20240529/12/006/bar: Requirement(s) ready
[2024-08-12T04:35:49] INFO Directory mkdir-parent-timedep/foo/20240529/12/006/bar: Executing
[2024-08-12T04:35:49] INFO Directory mkdir-parent-timedep/foo/20240529/12/006/bar: Final state: Ready
[2024-08-12T04:35:49] INFO Directory mkdir-parent-timedep/baz/20240529/12/006/qux: Initial state: Not Ready
[2024-08-12T04:35:49] INFO Directory mkdir-parent-timedep/baz/20240529/12/006/qux: Checking requirements
[2024-08-12T04:35:49] INFO Directory mkdir-parent-timedep/baz/20240529/12/006/qux: Requirement(s) ready
[2024-08-12T04:35:49] INFO Directory mkdir-parent-timedep/baz/20240529/12/006/qux: Executing
[2024-08-12T04:35:49] INFO Directory mkdir-parent-timedep/baz/20240529/12/006/qux: Final state: Ready
[2024-08-12T04:35:49] INFO Directories: Final state: Ready

mkdir-parent-timedep/
├── baz/
│   └── 20240529/
│   └── 12/
│   └── 006/
│   └── qux/
└── foo/
└── 20240529/
└── 12/
└── 006/
└── bar/

11 directories, 0 files
4 changes: 4 additions & 0 deletions docs/sections/user_guide/cli/tools/file/mkdir-exec.cmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
rm -rf mkdir-parent
uw file mkdir --target-dir mkdir-parent --config-file mkdir-config.yaml config
echo
tree -F mkdir-parent
21 changes: 21 additions & 0 deletions docs/sections/user_guide/cli/tools/file/mkdir-exec.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[2024-08-12T04:35:49] INFO Validating config against internal schema: mkdir
[2024-08-12T04:35:49] INFO 0 UW schema-validation errors found
[2024-08-12T04:35:49] INFO Directories: Initial state: Not Ready
[2024-08-12T04:35:49] INFO Directories: Checking requirements
[2024-08-12T04:35:49] INFO Directory mkdir-parent/foo: Initial state: Not Ready
[2024-08-12T04:35:49] INFO Directory mkdir-parent/foo: Checking requirements
[2024-08-12T04:35:49] INFO Directory mkdir-parent/foo: Requirement(s) ready
[2024-08-12T04:35:49] INFO Directory mkdir-parent/foo: Executing
[2024-08-12T04:35:49] INFO Directory mkdir-parent/foo: Final state: Ready
[2024-08-12T04:35:49] INFO Directory mkdir-parent/bar: Initial state: Not Ready
[2024-08-12T04:35:49] INFO Directory mkdir-parent/bar: Checking requirements
[2024-08-12T04:35:49] INFO Directory mkdir-parent/bar: Requirement(s) ready
[2024-08-12T04:35:49] INFO Directory mkdir-parent/bar: Executing
[2024-08-12T04:35:49] INFO Directory mkdir-parent/bar: Final state: Ready
[2024-08-12T04:35:49] INFO Directories: Final state: Ready

mkdir-parent/
├── bar/
└── foo/

3 directories, 0 files
1 change: 1 addition & 0 deletions docs/sections/user_guide/cli/tools/file/mkdir-help.cmd
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
uw file mkdir --help
28 changes: 28 additions & 0 deletions docs/sections/user_guide/cli/tools/file/mkdir-help.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
usage: uw file mkdir [-h] [--version] [--config-file PATH] [--target-dir PATH]
[--cycle CYCLE] [--leadtime LEADTIME] [--dry-run]
[--quiet] [--verbose]
[KEY ...]

Make directories

Optional arguments:
-h, --help
Show help and exit
--version
Show version info and exit
--config-file PATH, -c PATH
Path to UW YAML config file (default: read from stdin)
--target-dir PATH
Root directory for relative destination paths
--cycle CYCLE
The cycle in ISO8601 format (e.g. 2024-08-12T00)
--leadtime LEADTIME
The leadtime as hours[:minutes[:seconds]]
--dry-run
Only log info, making no changes
--quiet, -q
Print no logging messages
--verbose, -v
Print all logging messages
KEY
YAML key leading to file dst/src block
2 changes: 1 addition & 1 deletion docs/sections/user_guide/yaml/files.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
File Blocks
===========

File blocks define files to be staged in a target directory as copies or symbolic links. Keys in such blocks specify destination paths relative to the target directory, and values specify source paths.
File blocks define files to be staged in a target directory as copies or symbolic links. Keys in such blocks specify either absolute destination paths, or destination paths relative to the target directory. Values specify source paths.

Example block:

Expand Down
5 changes: 3 additions & 2 deletions docs/sections/user_guide/yaml/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ UW YAML
:maxdepth: 1

components/index
platform
execution
files
updating_values
mkdir
platform
rocoto
tags
updating_values
22 changes: 22 additions & 0 deletions docs/sections/user_guide/yaml/mkdir.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
.. _mkdir_yaml:

Directory Blocks
================

Directory blocks define a sequence of one or more directories to be created, nested under a ``mkdir:`` key. Each value is either an absolute path, or a path relative to the target directory, specified either via the CLI or an API call.

Example block with aboslute paths:
maddenp-noaa marked this conversation as resolved.
Show resolved Hide resolved

.. code-block:: yaml

mkdir:
- /path/to/dir1
- /path/to/dir2

Example block with relative paths:

.. code-block:: yaml

mkdir:
- /subdir/dir1
- ../../dir2
45 changes: 39 additions & 6 deletions src/uwtools/api/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

from iotaa import Asset

from uwtools.file import Copier, Linker
from uwtools.file import Copier, Linker, MkDir
from uwtools.utils.api import ensure_data_source as _ensure_data_source


Expand All @@ -33,15 +33,15 @@ def copy(
:param stdin_ok: OK to read from ``stdin``?
:return: ``True`` if all copies were created.
"""
copier = Copier(
stager = Copier(
target_dir=Path(target_dir) if target_dir else None,
config=_ensure_data_source(config, stdin_ok),
cycle=cycle,
leadtime=leadtime,
keys=keys,
dry_run=dry_run,
)
assets: list[Asset] = copier.go() # type: ignore
assets: list[Asset] = stager.go() # type: ignore
return all(asset.ready() for asset in assets)


Expand All @@ -66,16 +66,49 @@ def link(
:param stdin_ok: OK to read from ``stdin``?
:return: ``True`` if all links were created.
"""
linker = Linker(
stager = Linker(
target_dir=Path(target_dir) if target_dir else None,
config=_ensure_data_source(config, stdin_ok),
cycle=cycle,
leadtime=leadtime,
keys=keys,
dry_run=dry_run,
)
assets: list[Asset] = linker.go() # type: ignore
assets: list[Asset] = stager.go() # type: ignore
return all(asset.ready() for asset in assets)


__all__ = ["Copier", "Linker", "copy", "link"]
def mkdir(
config: Optional[Union[Path, dict, str]] = None,
target_dir: Optional[Union[Path, str]] = None,
cycle: Optional[dt.datetime] = None,
leadtime: Optional[dt.timedelta] = None,
keys: Optional[list[str]] = None,
dry_run: bool = False,
stdin_ok: bool = False,
) -> bool:
"""
Make directories.

:param config: YAML-file path, or ``dict`` (read ``stdin`` if missing or ``None``).
:param target_dir: Path to target directory.
:param cycle: A datetime object to make available for use in the config.
:param leadtime: A timedelta object to make available for use in the config.
:param keys: YAML keys leading to file dst/src block.
:param dry_run: Do not link files.
:param stdin_ok: OK to read from ``stdin``?
:return: ``True`` if all directories were made.
"""
stager = MkDir(
target_dir=Path(target_dir) if target_dir else None,
config=_ensure_data_source(config, stdin_ok),
cycle=cycle,
leadtime=leadtime,
keys=keys,
dry_run=dry_run,
)
assets: list[Asset] = stager.go() # type: ignore
return all(asset.ready() for asset in assets)


__all__ = ["Copier", "Linker", "MkDir", "copy", "link", "mkdir"]
Loading
Loading