Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 1206d11

Browse files
authoredMay 16, 2025··
Merge pull request #32 from adafruit/use_ruff
change to ruff
2 parents d2a64df + 2eab49d commit 1206d11

11 files changed

+175
-523
lines changed
 

‎.gitattributes

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# SPDX-FileCopyrightText: 2024 Justin Myers for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: Unlicense
4+
5+
.py text eol=lf
6+
.rst text eol=lf
7+
.txt text eol=lf
8+
.yaml text eol=lf
9+
.toml text eol=lf
10+
.license text eol=lf
11+
.md text eol=lf

‎.pre-commit-config.yaml

Lines changed: 11 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,21 @@
1-
# SPDX-FileCopyrightText: 2020 Diego Elio Pettenò
1+
# SPDX-FileCopyrightText: 2024 Justin Myers for Adafruit Industries
22
#
33
# SPDX-License-Identifier: Unlicense
44

55
repos:
6-
- repo: https://github.com/python/black
7-
rev: 23.3.0
8-
hooks:
9-
- id: black
10-
- repo: https://github.com/fsfe/reuse-tool
11-
rev: v1.1.2
12-
hooks:
13-
- id: reuse
146
- repo: https://github.com/pre-commit/pre-commit-hooks
15-
rev: v4.4.0
7+
rev: v4.5.0
168
hooks:
179
- id: check-yaml
1810
- id: end-of-file-fixer
1911
- id: trailing-whitespace
20-
- repo: https://github.com/pycqa/pylint
21-
rev: v2.17.4
12+
- repo: https://github.com/astral-sh/ruff-pre-commit
13+
rev: v0.3.4
2214
hooks:
23-
- id: pylint
24-
name: pylint (library code)
25-
types: [python]
26-
args:
27-
- --disable=consider-using-f-string
28-
exclude: "^(docs/|examples/|tests/|setup.py$)"
29-
- id: pylint
30-
name: pylint (example code)
31-
description: Run pylint rules on "examples/*.py" files
32-
types: [python]
33-
files: "^examples/"
34-
args:
35-
- --disable=missing-docstring,invalid-name,consider-using-f-string,duplicate-code
36-
- id: pylint
37-
name: pylint (test code)
38-
description: Run pylint rules on "tests/*.py" files
39-
types: [python]
40-
files: "^tests/"
41-
args:
42-
- --disable=missing-docstring,consider-using-f-string,duplicate-code
15+
- id: ruff-format
16+
- id: ruff
17+
args: ["--fix"]
18+
- repo: https://github.com/fsfe/reuse-tool
19+
rev: v3.0.1
20+
hooks:
21+
- id: reuse

‎.pylintrc

Lines changed: 0 additions & 399 deletions
This file was deleted.

‎README.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ Introduction
1717
:alt: Build Status
1818

1919

20-
.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
21-
:target: https://github.com/psf/black
22-
:alt: Code Style: Black
20+
.. image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json
21+
:target: https://github.com/astral-sh/ruff
22+
:alt: Code Style: Ruff
2323

2424
Simple BLE Service for reading and writing files over BLE. This BLE service is geared towards file
2525
transfer to and from a device running the service. A core part of the protocol is free space

‎adafruit_ble_file_transfer.py

Lines changed: 13 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,18 @@
1414

1515
import struct
1616
import time
17-
import _bleio
1817

18+
import _bleio
1919
from adafruit_ble.attributes import Attribute
2020
from adafruit_ble.characteristics import Characteristic, ComplexCharacteristic
2121
from adafruit_ble.characteristics.int import Uint32Characteristic
22-
from adafruit_ble.uuid import VendorUUID, StandardUUID
2322
from adafruit_ble.services import Service
23+
from adafruit_ble.uuid import StandardUUID, VendorUUID
2424

2525
try:
26-
from typing import Optional, List
27-
from circuitpython_typing import WriteableBuffer, ReadableBuffer
26+
from typing import List, Optional
27+
28+
from circuitpython_typing import ReadableBuffer, WriteableBuffer
2829
except ImportError:
2930
pass
3031

@@ -37,10 +38,8 @@
3738
class FileTransferUUID(VendorUUID):
3839
"""UUIDs with the CircuitPython base UUID."""
3940

40-
# pylint: disable=too-few-public-methods
41-
4241
def __init__(self, uuid16: int) -> None:
43-
uuid128 = bytearray("refsnarTeliF".encode("utf-8") + b"\x00\x00\xaf\xad")
42+
uuid128 = bytearray(b"refsnarTeliF" + b"\x00\x00\xaf\xad")
4443
uuid128[-3] = uuid16 >> 8
4544
uuid128[-4] = uuid16 & 0xFF
4645
super().__init__(uuid128)
@@ -50,8 +49,6 @@ class _TransferCharacteristic(ComplexCharacteristic):
5049
"""Endpoint for sending commands to a media player. The value read will list all available
5150
commands."""
5251

53-
# pylint: disable=too-few-public-methods
54-
5552
uuid = FileTransferUUID(0x0200)
5653

5754
def __init__(self) -> None:
@@ -68,9 +65,7 @@ def __init__(self) -> None:
6865
def bind(self, service: "FileTransferService") -> _bleio.PacketBuffer:
6966
"""Binds the characteristic to the given Service."""
7067
bound_characteristic = super().bind(service)
71-
return _bleio.PacketBuffer(
72-
bound_characteristic, buffer_size=4, max_packet_size=512
73-
)
68+
return _bleio.PacketBuffer(bound_characteristic, buffer_size=4, max_packet_size=512)
7469

7570

7671
class FileTransferService(Service):
@@ -79,14 +74,10 @@ class FileTransferService(Service):
7974
The server dictates data transfer chunk sizes so it can minimize buffer sizes on its end.
8075
"""
8176

82-
# pylint: disable=too-few-public-methods
83-
8477
uuid = StandardUUID(0xFEBB)
8578
version = Uint32Characteristic(uuid=FileTransferUUID(0x0100), initial_value=4)
8679
raw = _TransferCharacteristic()
87-
# _raw gets shadowed for each MIDIService instance by a PacketBuffer. PyLint doesn't know this
88-
# so it complains about missing members.
89-
# pylint: disable=no-member
80+
# _raw gets shadowed for each MIDIService instance by a PacketBuffer.
9081

9182
# Commands
9283
INVALID = 0x00
@@ -107,7 +98,7 @@ class FileTransferService(Service):
10798

10899
# Responses
109100
# 0x00 is INVALID
110-
OK = 0x01 # pylint: disable=invalid-name
101+
OK = 0x01
111102
ERROR = 0x02
112103
ERROR_NO_FILE = 0x03
113104
ERROR_PROTOCOL = 0x04
@@ -152,23 +143,18 @@ def _readinto(self, buffer: WriteableBuffer) -> bytearray:
152143

153144
def read(self, path: str, *, offset: int = 0) -> bytearray:
154145
"""Returns the contents of the file at the given path starting at the given offset"""
155-
# pylint: disable=too-many-locals
156146
path = path.encode("utf-8")
157147
chunk_size = CHUNK_SIZE
158148
start_offset = offset
159149
encoded = (
160-
struct.pack(
161-
"<BxHII", FileTransferService.READ, len(path), offset, chunk_size
162-
)
163-
+ path
150+
struct.pack("<BxHII", FileTransferService.READ, len(path), offset, chunk_size) + path
164151
)
165152
self._write(encoded)
166153
b = bytearray(struct.calcsize("<BBxxIII") + chunk_size)
167154
current_offset = start_offset
168155
chunk_done = True
169156
content_length = None
170157
chunk_end = 0
171-
# pylint: disable=unsupported-assignment-operation
172158
buf = []
173159
data_header_size = struct.calcsize("<BBxxIII")
174160
while content_length is None or current_offset < content_length:
@@ -190,9 +176,7 @@ def read(self, path: str, *, offset: int = 0) -> bytearray:
190176
if not buf:
191177
buf = bytearray(content_length - start_offset)
192178
out_offset = current_offset - start_offset
193-
buf[out_offset : out_offset + (read - data_header_size)] = b[
194-
data_header_size:read
195-
]
179+
buf[out_offset : out_offset + (read - data_header_size)] = b[data_header_size:read]
196180
current_offset += read - data_header_size
197181
else:
198182
out_offset = current_offset - start_offset
@@ -252,10 +236,7 @@ def write(
252236
if status != FileTransferService.OK:
253237
print("write error", status)
254238
raise RuntimeError()
255-
if (
256-
cmd != FileTransferService.WRITE_PACING
257-
or current_offset != written + offset
258-
):
239+
if cmd != FileTransferService.WRITE_PACING or current_offset != written + offset:
259240
self._write(
260241
struct.pack(
261242
"<BBxxII",
@@ -292,10 +273,7 @@ def mkdir(self, path: str, modification_time: Optional[int] = None) -> int:
292273
if modification_time is None:
293274
modification_time = int(time.time() * 1_000_000_000)
294275
encoded = (
295-
struct.pack(
296-
"<BxHxxxxQ", FileTransferService.MKDIR, len(path), modification_time
297-
)
298-
+ path
276+
struct.pack("<BxHxxxxQ", FileTransferService.MKDIR, len(path), modification_time) + path
299277
)
300278
self._write(encoded)
301279

@@ -310,7 +288,6 @@ def mkdir(self, path: str, modification_time: Optional[int] = None) -> int:
310288

311289
def listdir(self, path: str) -> List[tuple]:
312290
"""Returns a list of tuples, one tuple for each file or directory in the given path"""
313-
# pylint: disable=too-many-locals
314291
paths = []
315292
path = path.encode("utf-8")
316293
encoded = struct.pack("<BxH", FileTransferService.LISTDIR, len(path)) + path

‎docs/api.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,8 @@
44
.. If your library file(s) are nested in a directory (e.g. /adafruit_foo/foo.py)
55
.. use this format as the module name: "adafruit_foo.foo"
66
7+
API Reference
8+
#############
9+
710
.. automodule:: adafruit_ble_file_transfer
811
:members:

‎docs/conf.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
# -*- coding: utf-8 -*-
2-
31
# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries
42
#
53
# SPDX-License-Identifier: MIT

‎examples/ble_file_transfer_listdirs.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,17 @@
99

1010
from adafruit_ble import BLERadio
1111
from adafruit_ble.advertising.standard import (
12-
ProvideServicesAdvertisement,
1312
Advertisement,
13+
ProvideServicesAdvertisement,
1414
)
15+
1516
import adafruit_ble_file_transfer
1617

1718
# Connect to a file transfer device
1819
ble = BLERadio()
1920
connection = None
2021
print("disconnected, scanning")
21-
for advertisement in ble.start_scan(
22-
ProvideServicesAdvertisement, Advertisement, timeout=1
23-
):
22+
for advertisement in ble.start_scan(ProvideServicesAdvertisement, Advertisement, timeout=1):
2423
# print(advertisement.address, advertisement.address.type)
2524
if (
2625
not hasattr(advertisement, "services")

‎examples/ble_file_transfer_simpletest.py

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@
1111

1212
from adafruit_ble import BLERadio
1313
from adafruit_ble.advertising.standard import (
14-
ProvideServicesAdvertisement,
1514
Advertisement,
15+
ProvideServicesAdvertisement,
1616
)
17+
1718
import adafruit_ble_file_transfer
1819

1920

2021
def _write(client, filename, contents, *, offset=0):
21-
# pylint: disable=redefined-outer-name
2222
start = time.monotonic()
2323
try:
2424
client.write(filename, contents, offset=offset)
@@ -32,7 +32,6 @@ def _write(client, filename, contents, *, offset=0):
3232

3333

3434
def _read(client, filename, *, offset=0):
35-
# pylint: disable=redefined-outer-name
3635
start = time.monotonic()
3736
try:
3837
contents = client.read(filename, offset=offset)
@@ -73,7 +72,6 @@ def wait_for_reconnect():
7372
try:
7473
while ble.connected:
7574
for connection in ble.connections:
76-
# pylint: disable=redefined-outer-name
7775
if adafruit_ble_file_transfer.FileTransferService not in connection:
7876
continue
7977
if not connection.paired:
@@ -85,7 +83,7 @@ def wait_for_reconnect():
8583
client = adafruit_ble_file_transfer.FileTransferClient(service)
8684

8785
print("Testing write")
88-
client = _write(client, "/hello.txt", "Hello world".encode("utf-8"))
86+
client = _write(client, "/hello.txt", b"Hello world")
8987
time.sleep(1)
9088
c = _read(client, "/hello.txt")
9189
print(len(c), c)
@@ -101,23 +99,21 @@ def wait_for_reconnect():
10199
print()
102100

103101
print("Test writing within dir")
104-
client = _write(client, "/world/hi.txt", "Hi world".encode("utf-8"))
102+
client = _write(client, "/world/hi.txt", b"Hi world")
105103

106-
hello_world = "Hello world".encode("utf-8")
104+
hello_world = b"Hello world"
107105
client = _write(client, "/world/hello.txt", hello_world)
108106
c = _read(client, "/world/hello.txt")
109107
print(c)
110108
print()
111109

112110
# Test offsets
113111
print("Testing offsets")
114-
hello = len("Hello ".encode("utf-8"))
112+
hello = len(b"Hello ")
115113
c = _read(client, "/world/hello.txt", offset=hello)
116114
print(c)
117115

118-
client = _write(
119-
client, "/world/hello.txt", "offsets!".encode("utf-8"), offset=hello
120-
)
116+
client = _write(client, "/world/hello.txt", b"offsets!", offset=hello)
121117
c = _read(client, "/world/hello.txt", offset=0)
122118
print(c)
123119
print()
@@ -174,18 +170,15 @@ def wait_for_reconnect():
174170
raise RuntimeError("large contents don't match!")
175171
print()
176172
time.sleep(20)
177-
except ConnectionError as e:
173+
except ConnectionError:
178174
pass
179175

180176
print("disconnected, scanning")
181-
for advertisement in ble.start_scan(
182-
ProvideServicesAdvertisement, Advertisement, timeout=1
183-
):
177+
for advertisement in ble.start_scan(ProvideServicesAdvertisement, Advertisement, timeout=1):
184178
# print(advertisement.address, advertisement.address.type)
185179
if (
186180
not hasattr(advertisement, "services")
187-
or adafruit_ble_file_transfer.FileTransferService
188-
not in advertisement.services
181+
or adafruit_ble_file_transfer.FileTransferService not in advertisement.services
189182
):
190183
continue
191184
ble.connect(advertisement)

‎examples/ble_file_transfer_stub_server.py

Lines changed: 12 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
# SPDX-License-Identifier: Unlicense
44

55
"""This example broadcasts out the creation id based on the CircuitPython machine
6-
string and provides a stub FileTransferService."""
6+
string and provides a stub FileTransferService."""
77

88
import binascii
9-
import struct
109
import os
10+
import struct
1111
import time
1212

1313
import adafruit_ble
@@ -68,7 +68,7 @@ def write_packets(buf):
6868
sent = 0
6969
while offset < len(buf):
7070
this_packet = full_packet[: len(buf) - sent]
71-
for k in range(len(this_packet)): # pylint: disable=consider-using-enumerate
71+
for k in range(len(this_packet)):
7272
this_packet[k] = buf[sent + k]
7373
sent += len(this_packet)
7474
service.raw.write(this_packet)
@@ -80,9 +80,7 @@ def read_complete_path(starting_path, total_length):
8080
remaining_path = total_length - current_path_length
8181
complete_path[:current_path_length] = starting_path
8282
if remaining_path > 0:
83-
read_packets(
84-
memoryview(complete_path)[current_path_length:], target_size=remaining_path
85-
)
83+
read_packets(memoryview(complete_path)[current_path_length:], target_size=remaining_path)
8684
return str(complete_path, "utf-8")
8785

8886

@@ -152,12 +150,8 @@ def read_complete_path(starting_path, total_length):
152150
next_amount,
153151
)
154152
write_packets(header)
155-
read = read_packets(
156-
packet_buffer, target_size=next_amount + write_data_header_size
157-
)
158-
cmd, status, offset, data_size = struct.unpack_from(
159-
"<BBxxII", packet_buffer
160-
)
153+
read = read_packets(packet_buffer, target_size=next_amount + write_data_header_size)
154+
cmd, status, offset, data_size = struct.unpack_from("<BBxxII", packet_buffer)
161155
if status != FileTransferService.OK:
162156
print("bad status, resetting")
163157
ok = False
@@ -226,20 +220,14 @@ def read_complete_path(starting_path, total_length):
226220
len(contents),
227221
next_amount,
228222
)
229-
write_packets(
230-
header + contents[contents_sent : contents_sent + next_amount]
231-
)
223+
write_packets(header + contents[contents_sent : contents_sent + next_amount])
232224
contents_sent += next_amount
233225

234226
if contents_sent == len(contents):
235227
break
236228

237-
read = read_packets(
238-
packet_buffer, target_size=struct.calcsize("<BBxxII")
239-
)
240-
cmd, status, offset, free_space = struct.unpack_from(
241-
"<BBxxII", packet_buffer
242-
)
229+
read = read_packets(packet_buffer, target_size=struct.calcsize("<BBxxII"))
230+
cmd, status, offset, free_space = struct.unpack_from("<BBxxII", packet_buffer)
243231
if cmd != FileTransferService.READ_PACING:
244232
write_packets(
245233
struct.pack(
@@ -390,17 +378,13 @@ def read_complete_path(starting_path, total_length):
390378
del stored_timestamps[path]
391379
del d[filename]
392380

393-
header = struct.pack(
394-
"<BB", FileTransferService.DELETE_STATUS, FileTransferService.OK
395-
)
381+
header = struct.pack("<BB", FileTransferService.DELETE_STATUS, FileTransferService.OK)
396382
write_packets(header)
397383
elif command == adafruit_ble_file_transfer.FileTransferService.MOVE:
398384
old_path_length, new_path_length = struct.unpack_from("<xHH", p, offset=1)
399385
path_start = struct.calcsize("<BxHH")
400386
# We read in one extra character and then discard it. We don't need it. (C does.)
401-
both_paths = read_complete_path(
402-
p[path_start:], old_path_length + 1 + new_path_length
403-
)
387+
both_paths = read_complete_path(p[path_start:], old_path_length + 1 + new_path_length)
404388
old_path = both_paths[:old_path_length]
405389
new_path = both_paths[old_path_length + 1 :]
406390

@@ -439,9 +423,7 @@ def read_complete_path(starting_path, total_length):
439423
stored_timestamps[new_path] = stored_timestamps[old_path]
440424
del stored_timestamps[old_path]
441425

442-
header = struct.pack(
443-
"<BB", FileTransferService.MOVE_STATUS, FileTransferService.OK
444-
)
426+
header = struct.pack("<BB", FileTransferService.MOVE_STATUS, FileTransferService.OK)
445427
write_packets(header)
446428
else:
447429
print("unknown command", hex(command))

‎ruff.toml

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
# SPDX-FileCopyrightText: 2024 Tim Cocks for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
target-version = "py38"
6+
line-length = 100
7+
8+
[lint]
9+
preview = true
10+
select = ["I", "PL", "UP"]
11+
12+
extend-select = [
13+
"D419", # empty-docstring
14+
"E501", # line-too-long
15+
"W291", # trailing-whitespace
16+
"PLC0414", # useless-import-alias
17+
"PLC2401", # non-ascii-name
18+
"PLC2801", # unnecessary-dunder-call
19+
"PLC3002", # unnecessary-direct-lambda-call
20+
"E999", # syntax-error
21+
"PLE0101", # return-in-init
22+
"F706", # return-outside-function
23+
"F704", # yield-outside-function
24+
"PLE0116", # continue-in-finally
25+
"PLE0117", # nonlocal-without-binding
26+
"PLE0241", # duplicate-bases
27+
"PLE0302", # unexpected-special-method-signature
28+
"PLE0604", # invalid-all-object
29+
"PLE0605", # invalid-all-format
30+
"PLE0643", # potential-index-error
31+
"PLE0704", # misplaced-bare-raise
32+
"PLE1141", # dict-iter-missing-items
33+
"PLE1142", # await-outside-async
34+
"PLE1205", # logging-too-many-args
35+
"PLE1206", # logging-too-few-args
36+
"PLE1307", # bad-string-format-type
37+
"PLE1310", # bad-str-strip-call
38+
"PLE1507", # invalid-envvar-value
39+
"PLE2502", # bidirectional-unicode
40+
"PLE2510", # invalid-character-backspace
41+
"PLE2512", # invalid-character-sub
42+
"PLE2513", # invalid-character-esc
43+
"PLE2514", # invalid-character-nul
44+
"PLE2515", # invalid-character-zero-width-space
45+
"PLR0124", # comparison-with-itself
46+
"PLR0202", # no-classmethod-decorator
47+
"PLR0203", # no-staticmethod-decorator
48+
"UP004", # useless-object-inheritance
49+
"PLR0206", # property-with-parameters
50+
"PLR0904", # too-many-public-methods
51+
"PLR0911", # too-many-return-statements
52+
"PLR0912", # too-many-branches
53+
"PLR0913", # too-many-arguments
54+
"PLR0914", # too-many-locals
55+
"PLR0915", # too-many-statements
56+
"PLR0916", # too-many-boolean-expressions
57+
"PLR1702", # too-many-nested-blocks
58+
"PLR1704", # redefined-argument-from-local
59+
"PLR1711", # useless-return
60+
"C416", # unnecessary-comprehension
61+
"PLR1733", # unnecessary-dict-index-lookup
62+
"PLR1736", # unnecessary-list-index-lookup
63+
64+
# ruff reports this rule is unstable
65+
#"PLR6301", # no-self-use
66+
67+
"PLW0108", # unnecessary-lambda
68+
"PLW0120", # useless-else-on-loop
69+
"PLW0127", # self-assigning-variable
70+
"PLW0129", # assert-on-string-literal
71+
"B033", # duplicate-value
72+
"PLW0131", # named-expr-without-context
73+
"PLW0245", # super-without-brackets
74+
"PLW0406", # import-self
75+
"PLW0602", # global-variable-not-assigned
76+
"PLW0603", # global-statement
77+
"PLW0604", # global-at-module-level
78+
79+
# fails on the try: import typing used by libraries
80+
#"F401", # unused-import
81+
82+
"F841", # unused-variable
83+
"E722", # bare-except
84+
"PLW0711", # binary-op-exception
85+
"PLW1501", # bad-open-mode
86+
"PLW1508", # invalid-envvar-default
87+
"PLW1509", # subprocess-popen-preexec-fn
88+
"PLW2101", # useless-with-lock
89+
"PLW3301", # nested-min-max
90+
]
91+
92+
ignore = [
93+
"PLR2004", # magic-value-comparison
94+
"UP030", # format literals
95+
"PLW1514", # unspecified-encoding
96+
"PLR0913", # too-many-arguments
97+
"PLR0915", # too-many-statements
98+
"PLR0917", # too-many-positional-arguments
99+
"PLR0904", # too-many-public-methods
100+
"PLR0912", # too-many-branches
101+
"PLR0916", # too-many-boolean-expressions
102+
"PLR6301", # could-be-static no-self-use
103+
"PLC0415", # import outside toplevel
104+
"PLC2701", # private import
105+
"PLR0914", # too many local vars
106+
]
107+
108+
[format]
109+
line-ending = "lf"

0 commit comments

Comments
 (0)
Please sign in to comment.