Ensure that your Johnny Decimal system is neat and clean.
- jdlint [N14.0001]
Install a fairly recent version of
Python 3; jdlint is tested to work on
Python 3.11 and up.
That's it! There are no other dependencies.
jdlint should work on Linux, macOS, or Windows.
The script itself is executable (you should be able to just run ./jdlint.py),
or you can explicitly point python at it, like python3 jdlint.py.
You'll need to provide it wit a config file. By default, it looks for
jdlint.toml in the working directory; you may specify a different config file
with the -c flag, e.g.
./jdlint.py -c ~/my_jdlint_config.tomlEverything the script needs is specified in the config file.
Several config files are provided in this repository, demonstrating the various JDex/JD standards. You can of course customize it to your liking.
You must read the Config README for information on the format, and check out the provided example configs in that folder, which are (hopefully) well-documented. If you have questions/need help, please feel free to poke me on the JD Discord.
If you wish to ignore files/folders, patterns can be added globally to
linter.ignore, to a single root's .ignore, or to system.jdex.ignore.
Additionally, you can ignore them just for one run with:
./jdlint.py --ignore .st*This option may be specified more than once.
This option supports some basic glob-style patterns. (It uses
PurePath.match().)
If you wish to disable a specific rule, it can be added globally to
linter.disable_rules.
Additionally, you can ignore them just for one run with:
./jdlint.py --disable DUPLICATE_IDThis option may be specified more than once.
Either set linter.json_output = true in the config file, or force JSON output
just once with the flag:
./jdlint.py --jsonNote that these JSON results additionally contain complete information about the structure of your system that jdlint had to scan, if that information is of use to you. This structure only returns portions of the system that are possibly valid; it will not return forbidden files/folders, or files where folders are required, for example, nor will it return JDex entries that are orphans.
These are errors that can be generated for your files; some of them may require the JDex to determine.
A file or folder was found that didn't match you specified format, e.g.
.
├── 10-19 Life
│ ├── 11 Me, Myself, & I
│ │ ├── 11.11 Me
│ │ ├── 11.12 Myself
│ │ └── Not An Id <-- These don't belong here
│ └── 21 You <-- These don't belong here
└── Stuff <-- These don't belong here
An ID that has been used multiple times, e.g.
.
├── 00-09 System <-- 00-09 has been used twice!
│ ├── 01 System Stuff <-- 01 has been used twice!
│ │ ├── 01.11 An ID <-- 01.11 has been used twice!
│ │ └── 01.11 A Reuse <-- 01.11 has been used twice!
│ └── 01 A Reuse <-- 01 has been used twice!
│ └── 01.02 Another ID
└── 00-09 A Reuse <-- 00-09 has been used twice!
└── 02 Another Category
└── 02.00 An ID
A completely empty folder was found; you shouldn't have folders that clutter things up if they aren't actually serving a purpose.
.
├── 00-09 System
│ ├── 01 System Stuff
│ │ └── 01.11 Empty <-- These are all empty folders (just suppose there's no content it here)
│ └── 02 Empty Category <-- These are all empty folders
└── 10-19 Empty Area <-- These are all empty folders
A folder that was specified as forbidden in the config was encountered. (These can be used to ensure that naming schemes are followed.)
.
└── 10-19 Life
└── 11 Me, Myself, & I
├── 11.01 Meh <-- This should be called AC.01 Inbox
└── 11.11 Me
A file was found with the name of something that should have been a folder.
.
└── 10-19 Life
├── 11 Me, Myself, & I
│ ├── 11.11 Me
│ ├── 11.12 Myself
│ └── 11.13 I
└── 12 You <-- This is a file that looks like a category folder
A folder that should be empty per the config (e.g. inboxes and headers) wasn't.
.
└── 10-19 Life
└── 11 Me, Myself, & I
├── 11.01 Inbox <-- These shouldn't have files in them
│ └── Some file
├── 11.10 ■ The Me's <-- These shouldn't have files in them
│ └── Some file
└── 11.11 Me
An ID with a differently-named JDex entry, e.g.
├── files
│ └── 00-09 Systm <-- This is a typo, oops!
│ └── 01 System Stuf <-- This is a typo, oops!
│ ├── 01.02 A Naem <-- This is a typo, oops!
│ ├── 01.03 Another ID
│ └── 01.04 An ID
└── jdex
├── 00.00 System.md
├── 01.00 System Stuff.md
├── 01.02 A Name.md
├── 01.03 Another ID.md
└── 01.04 An ID.md
An ID without a corresponding JDex entry, e.g.
.
├── files
│ └── 00-09 System <-- This Area has no corresponding entry in the JDex
│ └── 01 System Stuff <-- This Category has no corresponding entry in the JDex
│ ├── 01.02 Missing ID <-- This ID has no corresponding entry in the JDex
│ └── 01.03 Another ID
└── jdex
└── 01.03 Another ID.md
These are errors that are only generated about the state of your JDex, not your files.
An ID in the JDex was used multiple times with a different parent each time.
This typically occurs if you've duplicated an ID by accident but changed the
parent, for example if you have work package W1234~23.65 My Logo and
W1234~15.43 My Website.
IDs in the JDex formed a cycle of ancestry. This cannot happen with a "normal"
system, but if you for instance allow work packages to relate to other work
packages, you should not have circular dependency, e.g. you should not have
W0001~W0002 First.md and W0002~W0001 Second.md.
A file or folder was found that didn't match you specified format, e.g.
.
├── 10-19 Life
│ ├── 11 Me, Myself, & I
│ │ ├── 11.11 Me.md
│ │ ├── 11.12 Myself.md
│ │ └── Not An Id.md <-- These don't belong here
│ └── 21 You <-- These don't belong here
└── Stuff <-- These don't belong here
An ID that has been used multiple times, e.g.
.
├── 01.11 An ID.md <-- 01.11 has been used twice!
└── 01.11 A Reuse.md <-- 01.11 has been used twice!
A completely empty folder was found; you shouldn't have folders that clutter things up if they aren't actually serving a purpose.
.
├── 00-09 System
│ ├── 01 System Stuff
│ │ └── 01.11 Me.md
│ └── 02 Empty Category <-- These are all empty folders
└── 10-19 Empty Area <-- These are all empty folders
A folder that was specified as forbidden in the config was encountered. (These can be used to ensure that naming schemes are followed.)
.
└── 10-19 Life
└── 11 Me, Myself, & I
└── 11.00 Meh <-- This should be called AC.00 Index
└── 11.11 Me.md
A note that was specified as forbidden in the config was encountered. (These can be used to ensure that naming schemes are followed.)
.
└── 10-19 Life
└── 11 Me, Myself, & I
├── 11.01 Meh.md <-- This should be called AC.01 Inbox
└── 11.11 Me.md
A file was found with the name of something that should have been a folder.
.
└── 10-19 Life
├── 11 Me, Myself, & I
│ ├── 11.11 Me.md
│ ├── 11.12 Myself.md
│ └── 11.13 I.md
└── 12 You <-- This is a file that looks like a category folder
A folder was found with the name of something that should have been a file.
.
└── 10-19 Life
├── 11 Me, Myself, & I
├── 11.11 Me.md
├── 11.12 Myself.md
└── 11.13 I.md <-- This is a file that looks like a category folder
└── Some file
An entry in a single file (JSON or plaintext) JDex did not match the appropriate
"canonical" form. For example, the ID 11.011, or the area 10-9. Refer to the
spec
here.
An entry in the JDex specified a parent that doesn't exist. For example, is you
have the work package W1234~23.65 My Logo, but no ID 23.65 exists, or if you
have an ID 12.33 with no category 12.
No. jdlint makes no changes to your files; you have to fix the problems it finds yourself. We also think that's a good thing.
Because we didn't think of it. Open an issue and maybe it will get added.
Open an issue, and if it's reasonable, we can try to support it.
This project has no formal affiliation with the Johnny Decimal system. The license for said system may be found here.