Use Cases
Identify Project Types
Identify the project types contained in a directory with
dirmagic.identify_project():
In [1]: from dirmagic import identify_project
In [2]: identify_project(".")
Out[2]:
[('IDE', 'Visual Studio Code project'),
('packaging', 'python package'),
('version control', 'git'),
('version control', 'repository')]
Find Projects
Find all directories containing a python package with
dirmagic.find_projects() and the python package criterion provided by
dirmagic.project_types:
In [1]: from dirmagic import find_projects, project_types
In [2]: find_projects("/Users/achim/Code", project_types.is_python_project)
Out[2]:
[PosixPath('/Users/achim/Code/python-dirmagic'),
PosixPath('/Users/achim/Code/nbconvert'),
PosixPath('/Users/achim/Code/py-aws-vault')]
Use Criterion Result as Boolean
In [1]: from dirmagic import project_types
In [2]: if project_types.is_git_root.test("."):
...: print(open(".git/HEAD").read())
...:
ref: refs/heads/main
Find the Project Root
Find the project root directory in the parent directories with
dirmagic.find_root() and a criterion from
dirmagic.project_types:
In [1]: from dirmagic import find_root, project_types
In [2]: find_root("build/html", project_types.is_python_project)
Out[2]: PosixPath('/Users/achim/Code/python-dirmagic')
In [3]: find_root("build/html")
Out[3]: PosixPath('/Users/achim/Code/python-dirmagic')
In [4]: find_root("build/html", return_reason=True)
Out[4]:
(PosixPath('/Users/achim/Code/python-dirmagic'),
'contains the directory `.git`')
Commands 3 and 4 are using a default list of criteria similar to
pyprojroot’s default criteria.
Check Criterion Result
Display a result of a criterion match rendered with rich:
In [1]: import dirmagic
In [2]: dirmagic.project_types.is_git_root.test(".").rich_tree()
Out[2]:
✔ `git` project type
└── ✔ OR (1 untested criteria not listed)
└── ✔ contains the directory `.git`
In [3]: dirmagic.project_types.is_dvc_root.test(".").rich_tree()
Out[3]:
❌ `DVC project` project type
└── ❌ contains the directory `.dvc`
In [4]: print(dirmagic.project_types.is_dvc_root.test(".").simple_tree())
FALSE: `DVC project` project type
FALSE: contains the directory `.dvc`
The method dirmagic.core_criteria.CriterionResult.simple_tree()
returns a string displaying the result tree using indentation only, no rich
package required here.
Custom Criteria
Build up a custom criterion using the generic criteria classes in
dirmagic.generic_criteria and the logical operators
| (or), & (and) and ~ (not).
In [1]: from dirmagic.generic_criteria import HasDir, HasFile, HasFileGlob
In [2]: is_my_data_dir = (
...: HasDir("data") &
...: HasFileGlob("data/*.hdf") &
...: HasFile("metadata.json") &
...: ~ HasFile(".ignore")
...: )
In [3]: is_my_data_dir.rich_tree()
Out[3]:
AND
├── contains the directory `data`
├── has a file matching `data/*.hdf`
├── has a file `metadata.json`
└── NOT
└── has a file `.ignore`
The criterion can be used with dirmagic.find_projects() or
dirmagic.find_root().
Display a Criterion
Display a criterion rendered with rich:
In [1]: import dirmagic
In [2]: dirmagic.project_types.is_vcs_root.rich_tree()
Out[2]:
`repository` project type
└── OR
├── `git` project type
│ └── OR
│ ├── contains the directory `.git`
│ └── has a file `.git` and file contains a line matching the regular expression `^gitdir: `
└── `subversion` project type
└── contains the directory `.svn`
Pattern Criteria
This is an example of a criterion checking the contents of two directories
using AllMatchCriterion based on their filenames.
It asserts that:
classes.txtexists,images/contains onlypngandjpgfiles,labels/contains onlytxtfiles, andeach
txtfile has a corresponding file inimages/
The pattern based criteria are documented at Pattern Criteria.
(NB: this is not an official YOLO v? definition, but rather what I ended up using. The confusion about image dataset directory structures is highlighting the need for coded criteria.)
In [1]: import dirmagic
In [2]: yolo_data = (
...: dirmagic.generic_criteria.HasFile("classes.txt")
...: & dirmagic.pattern_criteria.AllMatchCriterion(
...: r"^images/.*$",
...: dirmagic.pattern_criteria.SuffixIsIn("{0[0]}", [".png", ".jpg"]),
...: )
...: & dirmagic.pattern_criteria.AllMatchCriterion(
...: r"^labels/(.*)\.[^\.]*$",
...: dirmagic.pattern_criteria.MatchesPattern("{0[0]}", r".*\.txt$")
...: & (
...: dirmagic.generic_criteria.HasFile("images/{0[1]}.png")
...: | dirmagic.generic_criteria.HasFile("images/{0[1]}.jpg")
...: ),
...: )
...: )
In [3]]: yolo_data.rich_tree()
Out[3]:
AND
├── has a file `classes.txt`
├── for all files matching `^images/.*$`
│ └── the suffix of `{0[0]}` is in ['.png', '.jpg']
└── for all files matching `^labels/(.*)\.[^\.]*$`
└── AND
├── `{0[0]}` matches `.*\.txt$`
└── OR
├── has a file `images/{0[1]}.png`
└── has a file `images/{0[1]}.jpg`
In [4]: yolo_data.test("augmented_yolo_data/").rich_tree()
Out[4]:
✔ AND
├── ✔ has a file `classes.txt`
├── ✔ true for all entries matching ^images/.*$
│ ├── ✔ the suffix of `images/ee24d90d-Neill_Forks_Hut_augmented_3.jpg` is in ['.png', '.jpg']
│ ├── ✔ the suffix of `images/9d2727d1-Tutuwai_Hut_augmented_3.jpg` is in ['.png', '.jpg']
│ ├── ✔ the suffix of `images/6045c6fd-Mcgregor_Bivvy_augmented_3.jpg` is in ['.png', '.jpg']
...
│ └── ✔ the suffix of `images/3d20cb82-Waiorongomai_Hut_augmented_5.jpg` is in ['.png', '.jpg']
└── ✔ true for all entries matching ^labels/(.*)\.[^\.]*$
├── ✔ AND
│ ├── ✔ `labels/b55b7e80-Waitewaewae_Hut_augmented_5.txt` matches `.*\.txt$`
│ └── ✔ OR
│ ├── ❌ has a file `images/b55b7e80-Waitewaewae_Hut_augmented_5.png`
│ └── ✔ has a file `images/b55b7e80-Waitewaewae_Hut_augmented_5.jpg`
├── ✔ AND
│ ├── ✔ `labels/5032deda-Dorset_Ridge_Hut_augmented_5.txt` matches `.*\.txt$`
│ └── ✔ OR
│ ├── ❌ has a file `images/5032deda-Dorset_Ridge_Hut_augmented_5.png`
│ └── ✔ has a file `images/5032deda-Dorset_Ridge_Hut_augmented_5.jpg`
├── ✔ AND
│ ├── ✔ `labels/62a5984d-Kime_Hut_augmented_3.txt` matches `.*\.txt$`
│ └── ✔ OR
│ ├── ❌ has a file `images/62a5984d-Kime_Hut_augmented_3.png`
│ └── ✔ has a file `images/62a5984d-Kime_Hut_augmented_3.jpg`
...
└── ✔ AND
├── ✔ `labels/fbacad57-Carkeek_Hut_augmented_6.txt` matches `.*\.txt$`
└── ✔ OR
├── ❌ has a file `images/fbacad57-Carkeek_Hut_augmented_6.png`
└── ✔ has a file `images/fbacad57-Carkeek_Hut_augmented_6.jpg`