Coder Social home page Coder Social logo

pappasam / toml-sort Goto Github PK

View Code? Open in Web Editor NEW
87.0 4.0 15.0 418 KB

Toml sorting library

Home Page: https://toml-sort.readthedocs.io/en/latest/

License: MIT License

Makefile 2.35% Python 97.65%
python3 python-library toml toml-sort cli command-line-tool command-line-parser sorting formatter

toml-sort's Introduction

toml-sort

pypi-version license image-python-versions image-pypi-downloads readthedocs-status

A command line utility to sort and format your toml files.

Read the latest documentation here: https://toml-sort.readthedocs.io/en/latest/

Installation

pip install toml-sort

Motivation

This library sorts TOML files, providing the following features:

  • Sort tables and Arrays of Tables (AoT)
  • Option to sort non-tables / non-AoT's, or not
  • Preserve comments, where possible
  • Standardize whitespace and indentation

I wrote this library/application because I couldn't find any "good" sorting utilities for TOML files. Now, I use this as part of my daily workflow. Hopefully it helps you too!

Command line usage

This project can be used as either a command line utility or a Python library. Read the docs for an overview of its library capabilities. For command line usage, see below:

$ toml-sort --help
usage: toml-sort [-h] [--version] [-o OUTPUT] [-i] [-I] [-a] [--no-sort-tables] [--sort-table-keys]
                 [--sort-inline-tables] [--sort-inline-arrays] [--sort-first KEYS] [--no-header] [--no-comments]
                 [--no-header-comments] [--no-footer-comments] [--no-inline-comments] [--no-block-comments]
                 [--spaces-before-inline-comment {1,2,3,4}] [--spaces-indent-inline-array {2,4,6,8}]
                 [--trailing-comma-inline-array] [--check]
                 [F ...]

Toml sort: a sorting utility for toml files.

positional arguments:
  F                     filename(s) to be processed by toml-sort (default: -)

optional arguments:
  -h, --help            show this help message and exit
  --version             display version information and exit
  -o OUTPUT, --output OUTPUT
                        output filepath (default: '-')
  -i, --in-place        overwrite the original input file with changes
  --check               silently check if an original file would be changed by the formatter

sort:
  change sorting behavior

  -I, --ignore-case     ignore case when sorting
  -a, --all             sort ALL keys. This implies sort table-keys, inline-tables and inline arrays. (default: only
                        sort non-inline 'tables and arrays of tables')
  --no-sort-tables      Disables the default behavior of sorting tables and arrays of tables by their header value.
                        Setting this option will keep the order of tables in the toml file the same.
  --sort-table-keys     Sort the keys in tables and arrays of tables (excluding inline tables and arrays).
  --sort-inline-tables  Sort inline tables.
  --sort-inline-arrays  Sort inline arrays.
  --sort-first KEYS     Table keys that will be sorted first in the output. Multiple keys can be given separated by a
                        comma.

comments:
  exclude comments from output

  --no-header           Deprecated. See --no-header-comments
  --no-comments         remove all comments. Implies no header, footer, inline, or block comments
  --no-header-comments  remove a document's leading comments
  --no-footer-comments  remove a document's trailing comments
  --no-inline-comments  remove a document's inline comments
  --no-block-comments   remove a document's block comments

formatting:
  options to change output formatting

  --spaces-before-inline-comment {1,2,3,4}
                        the number of spaces before an inline comment (default: 1)
  --spaces-indent-inline-array {2,4,6,8}
                        the number of spaces to indent a multiline inline array (default: 2)
  --trailing-comma-inline-array
                        add trailing comma to the last item in a multiline inline array

Examples:

  - **Stdin -> Stdout**: cat input.toml | toml-sort
  - **Disk -> Disk**: toml-sort -o output.toml input.toml
  - **Linting**: toml-sort --check input.toml input2.toml input3.toml
  - **Inplace Disk**: toml-sort --in-place input.toml input2.toml

Return codes:

  - 0 : success.
  - 1 : errors were found

Notes:

  - You cannot redirect from a file to itself in Bash. POSIX shells process
    redirections first, then execute commands. --in-place exists for this
    reason

Configuration file

toml-sort can also be configured by using the pyproject.toml file. If the file exists and has a tool.tomlsort section, the configuration is used. If both command line arguments and the configuration are used, the options are merged. In the case of conflicts, the command line option is used.

In short, the names are the same as on the command line (and have the same meaning), but - is replaced with _. Please note, that only the below options are supported:

[tool.tomlsort]
all = true
in_place = true
no_comments = true
no_header_comments = true
no_footer_comments = true
no_inline_comments = true
no_block_comments = true
no_sort_tables = true
sort_first = ["key1", "key2"]
sort_table_keys = true
sort_inline_tables = true
sort_inline_arrays = true
spaces_before_inline_comment = 2
spaces_indent_inline_array = 4
trailing_comma_inline_array = true
check = true
ignore_case = true

Configuration Overrides

The pyproject.toml configuration file also supports configuration overrides, which are not available as command-line arguments. These overrides allow for fine-grained control of sort options for particular keys.

Only the following options can be included in an override:

[tool.tomlsort.overrides."path.to.key"]
first = ["key1", "key2"]
table_keys = true
inline_tables = true
inline_arrays = true

In the example configuration, path.to.key is the key to match. Keys are matched using the Python fnmatch function, so glob-style wildcards are supported.

For instance, to disable sorting the table in the following TOML file:

[servers.beta]
ip = "10.0.0.2"
dc = "eqdc10"
country = "**"

You can use any of the following overrides:

# Overrides in own table
[tool.tomlsort.overrides."servers.beta"]
table_keys = false

# Overrides in the tomlsort table
[tool.tomlsort]
overrides."servers.beta".table_keys = false

# Override using a wildcard if config should be applied to all servers keys
[tool.tomlsort]
overrides."servers.*".table_keys = false

Comments

Due to the free form nature of comments, it is hard to include them in a sort in a generic way that will work for everyone. toml-sort deals with four different types of comments. They are all enabled by default, but can be disabled using CLI switches, in which case comments of that type will be removed from the output.

Header

The first comments in a document, that are followed by a blank line, are treated as a header, and will always remain at the top of the document. If there is no blank line, the comment will be treated as a block comment instead.

# This is a header
# it can be multiple lines, as long as it is followed with a blank line
# it will always stay at the top of the sorted document

title = "The example"

Footer

Any comments at the end of the document, after the last item in the toml, will be treated as a footer, and will always remain at the bottom of the document.

title = "The example"

# this is a footer comment

Inline

Inline comments are comments that are at the end of a line where the start of the line is a toml item.

title = "The example" # This is a inline comment

Block

Block comments, are any comments that are on their own line. These comments are treated as attached to the item in the toml that is directly below them, not separated by whitespace. These comments can be multiple lines. Inline comments will appear in the sorted output above the item they were attached to in the input toml.

# Comment attached to title
title = "The example"

# This comment is an orphan because it
# is separated from a-section by whitespace

# This comment is attached to a-section
# attached comments can be multiple lines
[a-section]
# This comment is attached to date
date = "2019"

Orphan

Orphan comments are any comments that don't fall into the above categories, they will be removed from the output document.

# Header comment

# Orphan comment, not attached to any item
# because there is whitespace before title

title = "The example"

# This comment is an orphan because it
# is separated from a-section by whitespace

# This comment is attached to a-section
[a-section]

Example

The following example shows the input, and output, from the CLI with default options.

Unformatted, unsorted input

# My great TOML example

  title = "The example"

[[a-section.hello]]
ports = [ 8001, 8001, 8002 ]
dob = 1979-05-27T07:32:00Z # First class dates? Why not?


     # Attached to b-section
  [b-section]
  date = "2018"
  name = "Richard Stallman"

[[a-section.hello]]
ports = [ 80 ]
    #Attached to dob
dob = 1920-05-27T07:32:00Z # Another date!

                          [a-section]
                          date = "2019"
                          name = "Samuel Roeca"

Formatted, sorted output

# My great TOML example

title = "The example"

[a-section]
date = "2019"
name = "Samuel Roeca"

[[a-section.hello]]
ports = [ 8001, 8001, 8002 ]
dob = 1979-05-27T07:32:00Z # First class dates? Why not?

[[a-section.hello]]
ports = [ 80 ]
# Attached to dob
dob = 1920-05-27T07:32:00Z # Another date!

# Attached to b-section
[b-section]
date = "2018"
name = "Richard Stallman"

Local Development

Local development for this project is quite simple.

Dependencies

Install the following tools manually.

Recommended

Set up development environment

make setup

Run Tests

make test

Written by

Samuel Roeca, [email protected]

toml-sort's People

Contributors

atugushev avatar jayman2000 avatar jonathangreen avatar karpelcevs avatar kasium avatar kianmeng avatar kolanich avatar pappasam avatar sobolevn avatar wwuck avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

toml-sort's Issues

Files that only contain comments are doubled

If you give toml-sort a file that only contains comments, then it will print the contents of that file followed by a newline followed by the contents of the file again:

$ cat just-a-comment.toml 
# This TOML file only contains a comment.
$ toml-sort just-a-comment.toml 
# This TOML file only contains a comment.

# This TOML file only contains a comment.
$

Sorter fails with boolean values in file

If I try to sort a TOML file with boolean values, the sorter fails.

Traceback (most recent call last):
  File "/pythonpath/bin/toml-sort", line 8, in <module>
    sys.exit(cli())
  File "/pythonpath/lib/python3.8/site-packages/toml_sort/cli.py", line 226, in cli
    sorted_toml = TomlSort(
  File "/pythonpath/lib/python3.8/site-packages/toml_sort/tomlsort.py", line 161, in sorted
    sorted_toml = self.toml_doc_sorted(toml_doc)
  File "/pythonpath/lib/python3.8/site-packages/toml_sort/tomlsort.py", line 153, in toml_doc_sorted
    for key, value in self.sorted_children_table(original):
  File "/pythonpath/lib/python3.8/site-packages/toml_sort/tomlsort.py", line 100, in sorted_children_table
    table_items = [
  File "/pythonpath/lib/python3.8/site-packages/toml_sort/tomlsort.py", line 101, in <listcomp>
    (key, convert_tomlkit_buggy_types(parent[key], parent, key))
  File "/pythonpath/lib/python3.8/site-packages/toml_sort/tomlsort.py", line 49, in convert_tomlkit_buggy_types
    return parent.value.item(key)
AttributeError: 'dict' object has no attribute 'item'

Here are the contents of the test file:

bool1 = true

Support checking multiple filenames at the time

Currently with this pre-commit config below toml-sort will fail because it doesn't support checking multiple files at the time, see:

Sample of .pre-commit-config.yaml

repos:
  - repo: local
    hooks:
      - id: toml-sort
        name: toml-sort
        entry: toml-sort --check
        language: system
        types: [toml]

Actual result

$ touch foo.toml

$ pre-commit run --all-files toml-sort
toml-sort................................................................Failed
- hook id: toml-sort
- exit code: 2

Usage: toml-sort [OPTIONS] [FILENAME]
Try 'toml-sort --help' for help.
Error: Got unexpected extra arguments (pyproject.toml foo.toml)
Usage: toml-sort [OPTIONS] [FILENAME]
Try 'toml-sort --help' for help.

Would you be interested in this feature? If it a yes I could send a PR shortly. Thanks for the awesome linter!

Github Action fails with v0.22.0

When running github action pre-commit hook I get

Pretty format TOML............................................................Failed
- hook id: pretty-format-toml
- exit code: 1
Input File pyproject.toml is not a valid TOML file: TomlSort.__init__() got an unexpected keyword argument 'only_sort_tables'

This is the GH action

      - uses: pre-commit/[email protected]
        env:
          # yamllint disable-line rule:line-length
          SKIP: detect-aws-credentials,protect-first-parent,terraform_docs,terraform_providers_lock,terraform_tflint,terraform_tfsec,terraform_checkov,terrascan

Rename '--check' to '--check-only' or make changes to '--help' message

As is, --check doesn't change the file that is supposed to be sorted, despite --help explicitly stating:

"Check if an original file is changed by the formatter."

which suggests changes are being made to the original file (they aren't).

Proposed solution: either rename option to indicate it only checks if the file is considered sorted or not - --check-only or --is-sorted, with the latter suggesting no changes and just true/false return value explicitly.

Alternatively, I'd suggest changing the --help message to be more clear:

"Check if an original file would be changed by the formatter."

in_place = true doesn't work in pre-commit

I'm going through moving any config from .pre-commit-config.yaml into other config files wherever possible to make sure that running tools from terminal has the same result as running in the pre-commit hook.

So I changed from having:

  - repo: https://github.com/pappasam/toml-sort
    rev: v0.22.1
    hooks:
      - id: toml-sort
        args:
          - --all
          - --in-place

to:

  - repo: https://github.com/pappasam/toml-sort
    rev: v0.22.1
    hooks:
      - id: toml-sort

And adding the following to pyproject.toml

[tool.tomlsort]
all = true
in_place = true

This then works fine when running something like toml-sort pyproject.toml and that fixes the file in-place.
However, when I run the pre-commit hook it doesn't run the files in-place, it just uses the --check argument from https://github.com/pappasam/toml-sort/blob/main/.pre-commit-hooks.yaml instead as command line arguments take precedence over pyproject.toml arguments. This means that both check and in_place are True and as args.check is checked first (line 357 of cli.py) so my setting in_place = true basically has no effect.

I'm not sure of the best way to fix this.
Having a standard args of --check for the pre-commit does make sense as either --check or --in-place needs to be defined when running multiple files. And defaulting to an option that doesn't result in overwritten files is best. But it would also be good if it was possible for the in_place setting in pyproject.toml to work when running toml-sort from pre-commit.
Maybe the easiest way is to change the tool behaviour so that if both in-place and check are true then it runs in-place, rather than check.
That would just mean swapping

        if args.check:
            if original_toml != sorted_toml:
                check_failures.append(filename)
        elif args.in_place:
            write_file(filename, sorted_toml)

to:

        if args.in_place:
            write_file(filename, sorted_toml)
        elif args.check:
            if original_toml != sorted_toml:
                check_failures.append(filename)

Obviously that is a fairly large change in behaviour, though I imagine very few people would have both --check and --in-place set other than in my scenario where in_place is set in pyproject.toml and --check is only being set as the default pre-commit args.
Obviously for now I can workaround this easily enough by changing the pre-commit args to define --in-place and not --check, but I would prefer not having to set the same setting twice.

Is it possible to silence `jinja2` templating warning?

I'm working on a cookiecutter template where we have something like this

[project]
classifiers = [
    "Programming Language :: Python :: 3",
    "Programming Language :: Python :: 3 :: Only",
    {%- for python_version in range(
       cookiecutter.min_python_version | replace('3.', '') | int,
       cookiecutter.max_python_version | replace('3.', '') | int + 1
    ) %}
    "Programming Language :: Python :: 3.{{ python_version }}",
    {%- endfor %}
]

[tool.tomlsort]
all = true
spaces_indent_inline_array = 4
trailing_comma_inline_array = true
overrides."project.classifiers".inline_arrays = false

This works fine but toml-sort panics (understandably so). For now, I'm excluding the templated pyproject.toml from the pre-commit hooks at the top level and creating a dummy project inside that and linting in there, i.e. https://github.com/UCL-ARC/python-template/blob/paddys-improvement/.github/workflows/linting.yml. Is there a way for this to work nicely?

IndexError exception on an empty array

TOML file:

# foo.toml

[tool.foo]
bar = []

Exception:

$ python -V
Python 3.11.0

$ toml-sort --version
0.22.0

$ toml-sort foo.toml
Traceback (most recent call last):
  File "/private/tmp/foo/.venv/bin/toml-sort", line 8, in <module>
    sys.exit(cli())
             ^^^^^
  File "/private/tmp/foo/.venv/lib/python3.11/site-packages/toml_sort/cli.py", line 356, in cli
    ).sorted()
      ^^^^^^^^
  File "/private/tmp/foo/.venv/lib/python3.11/site-packages/toml_sort/tomlsort.py", line 634, in sorted
    sorted_toml = self.toml_doc_sorted(toml_doc)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/private/tmp/foo/.venv/lib/python3.11/site-packages/toml_sort/tomlsort.py", line 620, in toml_doc_sorted
    item.key, self.toml_elements_sorted(item, sorted_document)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/private/tmp/foo/.venv/lib/python3.11/site-packages/toml_sort/tomlsort.py", line 439, in toml_elements_sorted
    item.key, self.toml_elements_sorted(item, previous_item)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/private/tmp/foo/.venv/lib/python3.11/site-packages/toml_sort/tomlsort.py", line 435, in toml_elements_sorted
    for item in self.sorted_children_table(original.children):
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/private/tmp/foo/.venv/lib/python3.11/site-packages/toml_sort/tomlsort.py", line 387, in sorted_children_table
    non_tables = self.sort_items(
                 ^^^^^^^^^^^^^^^^
  File "/private/tmp/foo/.venv/lib/python3.11/site-packages/toml_sort/tomlsort.py", line 359, in sort_items
    item.value = self.sort_item(item.value)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/private/tmp/foo/.venv/lib/python3.11/site-packages/toml_sort/tomlsort.py", line 306, in sort_item
    return self.sort_array(item, indent_depth=indent_depth)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/private/tmp/foo/.venv/lib/python3.11/site-packages/toml_sort/tomlsort.py", line 284, in sort_array
    new_array_value[-1].comma = Whitespace("")
    ~~~~~~~~~~~~~~~^^^^
IndexError: list index out of range

Trailing whitespace is added to blank comment lines

If a TOML file contains a blank comment line, then toml-lint will add a trailing whitespace to that line:

$ sed 's/ /␠/g' space-on-blank-comment.toml 
#␠This␠next␠comment␠line␠has␠no␠whitespace␠(other␠than␠the␠line
#␠terminator):
#

foo␠=␠"bar"

$ toml-sort space-on-blank-comment.toml | sed 's/ /␠/g'
#␠This␠next␠comment␠line␠has␠no␠whitespace␠(other␠than␠the␠line
#␠terminator):
#␠

foo␠=␠"bar"

In order to make the difference easier to see, I used sed to replace the spaces with ␠ characters.

How to exclude/skip a file (e.g. `poetry.lock`)?

I am using toml-sort==0.23.1 with the below pyproject.toml config:

[tool.tomlsort]
all = true
in_place = true
trailing_comma_inline_array = true

I integrate toml-sort into my pre-commit like so:

  - repo: https://github.com/pappasam/toml-sort
    rev: v0.23.1
    hooks:
      - id: toml-sort-fix

Running identify to see the associations on poetry.lock:

> identify-cli poetry.lock
["file", "non-executable", "text", "toml"]

We can see it's considered TOML, so toml-sort will pick it up. However, poetry.lock is made programmatically, so it should not be touched by toml-sort.

How can one skip a particular file? I don't see anything in toml-sort --help that will exclude or skip files.

Is the only route right now to use an exclude within pre-commit?

Configuration file

Hey,
first thanks a lot for creating this awesome tool.

I have a feature request and I'm happy to to provide a PR for it. If the tool is used in CI but also locally, you might want to have common options in addition to context sensitive options. For example, in the CI you use --check while locally you use -i. But in both cases the toml files are the same but you need to specify them twice.

I would suggest to offer configuration in the toml file

[tool.toml_sort]
files = ["foo.toml"]
no_header = true

Basically, the tool will first check if there is a pyproject.toml with a toml_sort configuration and load the configuration if applicable. Second, the CLI is used and will override any value if specified there

Option to not sort non-table keys

If a key's value is not a table, it would be nice if we didn't need to sort it. For example:

[b]
name = "B great day"
info = "Some great info about b"

[a]
name = "A great day"
info = "Some great info about a"

currently sorts to

[a]
info = "Some great info about a"
name = "A great day"

[b]
info = "Some great info about b"
name = "B great day"

This is fine, but it would be nice to have the option to sort it to:

[a]
name = "A great day"
info = "Some great info about a"

[b]
name = "B great day"
info = "Some great info about b"

Option to prevent deletion of orphan comments

Hi, in the context of pretty-format-toml I was recently surprised by the disappearance of a multi-paragraph comment. After investigation I discovered that it was interpreted by toml-sort as an orphan comment.

For example,

# paragraph 1

# paragraph 2
[a-section]

and then # paragraph 1 vanishes.

I ended up solving this with

# paragraph 1
#
# paragraph 2
[a-section]

Would it make sense to add an option which changes the behavior so that orphan comments are added to the next section rather than deleted?

more line spacing (optional)?

I was hoping I could use toml-sort to maintain & preserve formatting of something like this:

[a.config]
list1 = [
    "abc",
    "def",
    "ghi",
]

value1 = 123 # abc


[b.config]
value2 = 456

list2 = [
    7, # def
    8,
    # ghi
    9,
]

context: I can use toml-sort as a TOML formatting tool with the --no-sort-tables option, haven't found anything better for Python so far. Just have to find a way to work this issue, and avoid orphaned comments like I described in: #59 (comment)


Possible workaround solution though ugly with some more comments added (with --spaces-indent-inline-array & --trailing-comma-inline-array options, of course):

# configure some things

[a.config]
list1 = [
    "abc",
    "def",
    "ghi",
]
# ---
value1 = 123 # abc

# ---
# configure specific things for b
[b.config]
value2 = 456
# ---
list2 = [
    7, # def
    8,
    # ghi
    9,
]

I may try to develop & propose a better solution, time permitting.

Maintain literal quotes for keys

Hey,

Great tool, one slight improvement I would suggest if it isn't too hard is around quoted keys.

Firstly, I think it is great that if you have something like:

'key1' = 'value1'
"key2" = "value2"

It will get changed to:

'key1' = 'value1'
"key2" = "value2"

That is great, given that there is no need to put those keys in quotes.
However, I have a case where I do require a . within a key.
So for that I define it as a literal quote (single quotes), i.e.,

'namespace.package' = 'my_value'

And currently toml-sort changes that to:

"namespace.package" = 'my_value'

So it changes the quoted key from a literal string to a basic string. This isn't the end of the world, but some others I work with have a strong preference for using literal strings in toml rather than basic strings so it looks a bit odd having a file full of single quotes and one string with double quotes.

Also, toml-sort changes the following (one dumb example, and one string from the quoted keys section of the toml spec:

'C:\Users\nodejs\templates' = true
'quoted "value"' = "value"

to:

"C:\Users\nodejs\templates" = true
"quoted \"value\"" = "value"

One would argue that changing 'quoted "value"' to "quoted "value"" has decreased the readability of that string which is not ideal.
The other string (I accept, no one should ever have a path as a key... but technically it is still valid toml) is more problematic. After toml-sort has changed that from single to double quotes then tomlkit can no longer parse the file.
Interestingly, even if I set that key to "C:\\Users\\nodejs\\templates" then toml-sort changes it back to "C:\Users\nodejs\templates" which then can't be parsed.

Again, no one should have such a stupid key, and I don't have anything like that (I just have one key with a . in it).
But toml-sort also shouldn't take a parsable input and end up with a non-parsable output.
And it would also be great if toml-sort preserved the string type of the key if a quoted key is required.

Sort uppercase and lowercase together

Currently Uppercase are grouped and sorted differently from lowercases.

e.g.

[tool.poetry.dependencies]
Django = "^2.2"
Jinja2 = "2.11"
Markdown = "^3.2"
arrow = "^0.15"
django-filter = "^2.3"

expected

[tool.poetry.dependencies]
arrow = "^0.15"
Django = "^2.2"
django-filter = "^2.3"
Jinja2 = "2.11"
Markdown = "^3.2"

Don't write file if nothing was changed

Currently, the toml file is always written independently if anything was changed during sorting/formatting. It would be nice if this is only done if something changed.

Docs request: "default" config

pylint provides an examples module that has several example configs (pylintrc, pyproject.toml). I use these to speed up adding new config options (and it promotes awareness of the available config options).

A huge benefit of this is also revealing the default behavior of all config options.

I think it would be cool if toml-sort had something similar. Fwiw, https://github.com/pappasam/toml-sort/tree/b9b6210da457c38122995e434b314f4c4a4a923e#configuration-file has an example config, but it doesn't document if it's the "default" config.

Proposal

The request here is to add example config(s) somewhere to docs/

Option to selectively disable sorting for an entry in an array or whole array

It would be great to have the ability to selectively disable sorting for an array (via a comment or a flag in the config). I think the sorting feature is great, but I can only solve this by disabling it for all files, like in #37.

[tool.tomlsort]
all = false
sort_inline_arrays = false

For example, with Coverage for the following to work src must appear before the .tox line, but sorting will change it.

[tool.coverage]
paths.source = [
    "src",
    ".tox*/*/lib/python*/site-packages",
]

Not compatible with tomlkit 0.8.0

Hi! thanks for creating great tool :)
I think I have encountered an issue whiling upgrading version 0.20.1 -> 0.22.2

image

it seems it is not compatible with tomlkit 0.8.0 and poetry doesn't upgrade it

Leading spaces in comments should be preserved

The comment

# init_command = [
#     'python',
#     'examples/pytorch/s3_init.py',
#     '--config-json=examples/pytorch/s3_init_config.json',
#     '--linter=clang-format',
#     '--dry-run={{DRYRUN}}',
#     '--output-dir=.lintbin',
#     '--output-name=clang-format',
# ]

is formatted as

# init_command = [
# 'python',
# 'examples/pytorch/s3_init.py',
# '--config-json=examples/pytorch/s3_init_config.json',
# '--linter=clang-format',
# '--dry-run={{DRYRUN}}',
# '--output-dir=.lintbin',
# '--output-name=clang-format',
# ]

It would be great if the leading spaces are preserved.

Keep comments above a key-value pair as is

I tried out your library and it is really helpful. Thank you for your contribution.

Question: Do you think it is worthwhile to add an option to preserve (multi-line) comments that precede a key-value pair?

Example (from a pyproject.toml in one of my projects):

[tool.poetry.dependencies]
click = "^7.1.2"
coverage = {extras = ["toml"], optional = true, version = "^5.1"}
pytest = {optional = true, version = "^5.4.3"}
pytest-cov = {optional = true, version = "^2.10.0"}
pytest-xdist = {optional = true, version = "^1.32.0"}
python = "^3.8"
tox = {optional = true, version = "^3.16.1"}

[tool.poetry.extras]
# line1
# line2
# line3
develop = "..."
testing = "..."

[tool.poetry.scripts]
version = "..."

Better error message for not using tables.

Taking an example from the PEP documentation.

[project]
urls.homepage = "https://example.com"
urls.documentation = "https://readthedocs.org"}

Running toml-sort results in

Traceback (most recent call last):
  File "/Users/paddy/mambaforge/bin/toml-sort", line 8, in <module>
    sys.exit(cli())
             ^^^^^
  File "/Users/paddy/mambaforge/lib/python3.11/site-packages/toml_sort/cli.py", line 297, in cli
    args = get_parser().parse_args(args=arguments)  # strip command itself
           ^^^^^^^^^^^^
  File "/Users/paddy/mambaforge/lib/python3.11/site-packages/toml_sort/cli.py", line 289, in get_parser
    parser.set_defaults(**load_config_file())
                          ^^^^^^^^^^^^^^^^^^
  File "/Users/paddy/mambaforge/lib/python3.11/site-packages/toml_sort/cli.py", line 89, in load_config_file
    document = tomlkit.parse(content)
               ^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/paddy/mambaforge/lib/python3.11/site-packages/tomlkit/api.py", line 83, in parse
    return Parser(string).parse()
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/paddy/mambaforge/lib/python3.11/site-packages/tomlkit/parser.py", line 158, in parse
    key, value = self._parse_table()
                 ^^^^^^^^^^^^^^^^^^^
  File "/Users/paddy/mambaforge/lib/python3.11/site-packages/tomlkit/parser.py", line 999, in _parse_table
    item = self._parse_item()
           ^^^^^^^^^^^^^^^^^^
  File "/Users/paddy/mambaforge/lib/python3.11/site-packages/tomlkit/parser.py", line 242, in _parse_item
    return self._parse_key_value(True)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/paddy/mambaforge/lib/python3.11/site-packages/tomlkit/parser.py", line 338, in _parse_key_value
    cws, comment, trail = self._parse_comment_trail()
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/paddy/mambaforge/lib/python3.11/site-packages/tomlkit/parser.py", line 284, in _parse_comment_trail
    raise self.parse_error(UnexpectedCharError, c)
tomlkit.exceptions.UnexpectedCharError: Unexpected character: '}' at line 3 col 46

This can be modified to

[project]
urls = {homepage = "https://example.com", documentation = "https://readthedocs.org"}

and now toml-sort will work as expected. However, from the error message, it is not at all obvious that this is what is required.

Python as first item in "tool.poetry.dependencies"

I would like to use the --all option, but it reorders "python", which is first by convention for poetry packages.

> poetry new tmp
> cd tmp
> poetry add antigravity
> cat pyproject.toml
[tool.poetry]
name = "tmp"
version = "0.1.0"
description = ""
authors = ["Kyle King <[email protected]>"]
readme = "README.md"

[tool.poetry.dependencies]
python = "^3.11"
antigravity = "^0.1"


[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
> toml-sort pyproject.toml -i -a
> cat pyproject.toml
[build-system]
build-backend = "poetry.core.masonry.api"
requires = ["poetry-core"]

[tool.poetry]
authors = ["Kyle King <[email protected]>"]
description = ""
name = "tmp"
readme = "README.md"
version = "0.1.0"

[tool.poetry.dependencies]
antigravity = "^0.1"
python = "^3.11"

Where, if sorted manually or by poetry-plugin-sort, I would expect the dependencies to be sorted as:

[tool.poetry.dependencies]
python = "^3.11"
antigravity = "^0.1"

Would you be interested in a feature that would recognize tool.poetry.dependencies in pyproject.toml and keep the python dependency first? If so, I would be happy to try to contribute and if so, would probably add some sort of generic hook to override the sort order for edge cases like these

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.