testtri 0.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- testtri-0.0.1/.github/workflows/publish.yaml +144 -0
- testtri-0.0.1/.gitignore +7 -0
- testtri-0.0.1/PKG-INFO +65 -0
- testtri-0.0.1/README.md +52 -0
- testtri-0.0.1/pyproject.toml +26 -0
- testtri-0.0.1/setup.cfg +4 -0
- testtri-0.0.1/src/testtri/__init__.py +10 -0
- testtri-0.0.1/src/testtri/fileops.py +29 -0
- testtri-0.0.1/src/testtri.egg-info/PKG-INFO +65 -0
- testtri-0.0.1/src/testtri.egg-info/SOURCES.txt +12 -0
- testtri-0.0.1/src/testtri.egg-info/dependency_links.txt +1 -0
- testtri-0.0.1/src/testtri.egg-info/top_level.txt +1 -0
- testtri-0.0.1/tests/__init__.py +0 -0
- testtri-0.0.1/tests/test_fileops.py +54 -0
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
name: Release and Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
inputs:
|
|
8
|
+
bump:
|
|
9
|
+
description: "Version bump type"
|
|
10
|
+
required: true
|
|
11
|
+
type: choice
|
|
12
|
+
options:
|
|
13
|
+
- patch
|
|
14
|
+
- minor
|
|
15
|
+
- major
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
version:
|
|
19
|
+
name: Calculate next version
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
outputs:
|
|
22
|
+
new_version: ${{ steps.calc.outputs.new_version }}
|
|
23
|
+
tag: ${{ steps.calc.outputs.tag }}
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@v4
|
|
26
|
+
with:
|
|
27
|
+
fetch-depth: 0
|
|
28
|
+
|
|
29
|
+
- name: Determine bump type
|
|
30
|
+
id: bump_type
|
|
31
|
+
run: |
|
|
32
|
+
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
|
33
|
+
echo "bump=${{ inputs.bump }}" >> $GITHUB_OUTPUT
|
|
34
|
+
else
|
|
35
|
+
# Read labels from the PR merged into main
|
|
36
|
+
PR_LABELS=$(gh api repos/${{ github.repository }}/commits/${{ github.sha }}/pulls \
|
|
37
|
+
--jq '.[0].labels[].name' 2>/dev/null || echo "")
|
|
38
|
+
echo "PR labels found: $PR_LABELS"
|
|
39
|
+
|
|
40
|
+
if echo "$PR_LABELS" | grep -qi "major"; then
|
|
41
|
+
echo "bump=major" >> $GITHUB_OUTPUT
|
|
42
|
+
elif echo "$PR_LABELS" | grep -qi "minor"; then
|
|
43
|
+
echo "bump=minor" >> $GITHUB_OUTPUT
|
|
44
|
+
else
|
|
45
|
+
echo "bump=patch" >> $GITHUB_OUTPUT
|
|
46
|
+
fi
|
|
47
|
+
fi
|
|
48
|
+
env:
|
|
49
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
50
|
+
|
|
51
|
+
- name: Calculate new version
|
|
52
|
+
id: calc
|
|
53
|
+
run: |
|
|
54
|
+
# Get latest semver tag; default to v0.0.0 if none exists
|
|
55
|
+
LATEST_TAG=$(git tag --sort=-v:refname | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | head -1)
|
|
56
|
+
LATEST_TAG=${LATEST_TAG:-v0.0.0}
|
|
57
|
+
VERSION=${LATEST_TAG#v}
|
|
58
|
+
echo "Current version: $VERSION"
|
|
59
|
+
|
|
60
|
+
MAJOR=$(echo $VERSION | cut -d. -f1)
|
|
61
|
+
MINOR=$(echo $VERSION | cut -d. -f2)
|
|
62
|
+
PATCH=$(echo $VERSION | cut -d. -f3)
|
|
63
|
+
BUMP=${{ steps.bump_type.outputs.bump }}
|
|
64
|
+
|
|
65
|
+
if [ "$BUMP" = "major" ]; then
|
|
66
|
+
MAJOR=$((MAJOR + 1)); MINOR=0; PATCH=0
|
|
67
|
+
elif [ "$BUMP" = "minor" ]; then
|
|
68
|
+
MINOR=$((MINOR + 1)); PATCH=0
|
|
69
|
+
else
|
|
70
|
+
PATCH=$((PATCH + 1))
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
NEW_VERSION="$MAJOR.$MINOR.$PATCH"
|
|
74
|
+
echo "New version: $NEW_VERSION (bump: $BUMP)"
|
|
75
|
+
echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT
|
|
76
|
+
echo "tag=v$NEW_VERSION" >> $GITHUB_OUTPUT
|
|
77
|
+
|
|
78
|
+
build:
|
|
79
|
+
name: Build package
|
|
80
|
+
runs-on: ubuntu-latest
|
|
81
|
+
needs: version
|
|
82
|
+
permissions:
|
|
83
|
+
contents: write
|
|
84
|
+
steps:
|
|
85
|
+
- uses: actions/checkout@v4
|
|
86
|
+
with:
|
|
87
|
+
fetch-depth: 0
|
|
88
|
+
|
|
89
|
+
- name: Create and push version tag
|
|
90
|
+
run: |
|
|
91
|
+
git config user.name "github-actions[bot]"
|
|
92
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
93
|
+
git tag ${{ needs.version.outputs.tag }}
|
|
94
|
+
git push origin ${{ needs.version.outputs.tag }}
|
|
95
|
+
env:
|
|
96
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
97
|
+
|
|
98
|
+
- name: Set up Python
|
|
99
|
+
uses: actions/setup-python@v5
|
|
100
|
+
with:
|
|
101
|
+
python-version: "3.12"
|
|
102
|
+
|
|
103
|
+
- name: Install build tools
|
|
104
|
+
run: pip install build setuptools-scm
|
|
105
|
+
|
|
106
|
+
- name: Build package
|
|
107
|
+
run: python -m build
|
|
108
|
+
|
|
109
|
+
- name: Upload build artifacts
|
|
110
|
+
uses: actions/upload-artifact@v4
|
|
111
|
+
with:
|
|
112
|
+
name: dist
|
|
113
|
+
path: dist/
|
|
114
|
+
|
|
115
|
+
release:
|
|
116
|
+
name: Create GitHub Release
|
|
117
|
+
runs-on: ubuntu-latest
|
|
118
|
+
needs: [version, build]
|
|
119
|
+
permissions:
|
|
120
|
+
contents: write
|
|
121
|
+
steps:
|
|
122
|
+
- name: Create GitHub Release
|
|
123
|
+
uses: softprops/action-gh-release@v2
|
|
124
|
+
with:
|
|
125
|
+
tag_name: ${{ needs.version.outputs.tag }}
|
|
126
|
+
name: v${{ needs.version.outputs.new_version }}
|
|
127
|
+
generate_release_notes: true
|
|
128
|
+
|
|
129
|
+
publish:
|
|
130
|
+
name: Publish to PyPI
|
|
131
|
+
runs-on: ubuntu-latest
|
|
132
|
+
needs: [build, release]
|
|
133
|
+
environment: self-publish
|
|
134
|
+
permissions:
|
|
135
|
+
id-token: write # required for OIDC trusted publishing
|
|
136
|
+
steps:
|
|
137
|
+
- name: Download build artifacts
|
|
138
|
+
uses: actions/download-artifact@v4
|
|
139
|
+
with:
|
|
140
|
+
name: dist
|
|
141
|
+
path: dist/
|
|
142
|
+
|
|
143
|
+
- name: Publish to PyPI
|
|
144
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
testtri-0.0.1/.gitignore
ADDED
testtri-0.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: testtri
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: A simple Python library for common file operations
|
|
5
|
+
License: MIT
|
|
6
|
+
Project-URL: Homepage, https://github.com/your-username/testTRI
|
|
7
|
+
Keywords: file,fileops,io
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.8
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
|
|
14
|
+
# testTRI
|
|
15
|
+
|
|
16
|
+
[](https://github.com/TRI-IE/testTRI/actions/workflows/publish.yaml)
|
|
17
|
+
|
|
18
|
+
A simple Python library for common file operations.
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pip install testtri
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Or install locally in development mode:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pip install -e .
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Usage
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
from testtri import read_file, write_file, append_file, delete_file
|
|
36
|
+
|
|
37
|
+
# Create / overwrite a file
|
|
38
|
+
write_file("hello.txt", "Hello, world!")
|
|
39
|
+
|
|
40
|
+
# Read a file
|
|
41
|
+
content = read_file("hello.txt")
|
|
42
|
+
print(content) # Hello, world!
|
|
43
|
+
|
|
44
|
+
# Append to a file
|
|
45
|
+
append_file("hello.txt", "\nA second line.")
|
|
46
|
+
|
|
47
|
+
# Delete a file
|
|
48
|
+
delete_file("hello.txt")
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## API
|
|
52
|
+
|
|
53
|
+
| Function | Description |
|
|
54
|
+
|---|---|
|
|
55
|
+
| `read_file(path)` | Read and return file contents as a string |
|
|
56
|
+
| `write_file(path, content)` | Create or overwrite a file with the given content |
|
|
57
|
+
| `append_file(path, content)` | Append content to a file (creates it if missing) |
|
|
58
|
+
| `delete_file(path)` | Delete a file (raises `FileNotFoundError` if missing) |
|
|
59
|
+
|
|
60
|
+
## Running Tests
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
pip install pytest
|
|
64
|
+
pytest tests/
|
|
65
|
+
```
|
testtri-0.0.1/README.md
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# testTRI
|
|
2
|
+
|
|
3
|
+
[](https://github.com/TRI-IE/testTRI/actions/workflows/publish.yaml)
|
|
4
|
+
|
|
5
|
+
A simple Python library for common file operations.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install testtri
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Or install locally in development mode:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pip install -e .
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
```python
|
|
22
|
+
from testtri import read_file, write_file, append_file, delete_file
|
|
23
|
+
|
|
24
|
+
# Create / overwrite a file
|
|
25
|
+
write_file("hello.txt", "Hello, world!")
|
|
26
|
+
|
|
27
|
+
# Read a file
|
|
28
|
+
content = read_file("hello.txt")
|
|
29
|
+
print(content) # Hello, world!
|
|
30
|
+
|
|
31
|
+
# Append to a file
|
|
32
|
+
append_file("hello.txt", "\nA second line.")
|
|
33
|
+
|
|
34
|
+
# Delete a file
|
|
35
|
+
delete_file("hello.txt")
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## API
|
|
39
|
+
|
|
40
|
+
| Function | Description |
|
|
41
|
+
|---|---|
|
|
42
|
+
| `read_file(path)` | Read and return file contents as a string |
|
|
43
|
+
| `write_file(path, content)` | Create or overwrite a file with the given content |
|
|
44
|
+
| `append_file(path, content)` | Append content to a file (creates it if missing) |
|
|
45
|
+
| `delete_file(path)` | Delete a file (raises `FileNotFoundError` if missing) |
|
|
46
|
+
|
|
47
|
+
## Running Tests
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pip install pytest
|
|
51
|
+
pytest tests/
|
|
52
|
+
```
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68", "wheel", "setuptools-scm>=8"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "testtri"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = "A simple Python library for common file operations"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.8"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
keywords = ["file", "fileops", "io"]
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Programming Language :: Python :: 3",
|
|
15
|
+
"License :: OSI Approved :: MIT License",
|
|
16
|
+
"Operating System :: OS Independent",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
[project.urls]
|
|
20
|
+
Homepage = "https://github.com/your-username/testTRI"
|
|
21
|
+
|
|
22
|
+
[tool.setuptools.packages.find]
|
|
23
|
+
where = ["src"]
|
|
24
|
+
|
|
25
|
+
[tool.setuptools_scm]
|
|
26
|
+
# version is derived from git tags (e.g. v0.0.1 → 0.0.1)
|
testtri-0.0.1/setup.cfg
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
2
|
+
|
|
3
|
+
from .fileops import append_file, delete_file, read_file, write_file
|
|
4
|
+
|
|
5
|
+
__all__ = ["read_file", "write_file", "append_file", "delete_file"]
|
|
6
|
+
|
|
7
|
+
try:
|
|
8
|
+
__version__ = version("testtri")
|
|
9
|
+
except PackageNotFoundError:
|
|
10
|
+
__version__ = "unknown"
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def read_file(path: str) -> str:
|
|
5
|
+
"""Read and return the contents of a file as a string."""
|
|
6
|
+
return Path(path).read_text(encoding="utf-8")
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def write_file(path: str, content: str) -> None:
|
|
10
|
+
"""Create a new file (or overwrite an existing one) with the given content."""
|
|
11
|
+
p = Path(path)
|
|
12
|
+
p.parent.mkdir(parents=True, exist_ok=True)
|
|
13
|
+
p.write_text(content, encoding="utf-8")
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def append_file(path: str, content: str) -> None:
|
|
17
|
+
"""Append content to a file. Creates the file if it does not exist."""
|
|
18
|
+
p = Path(path)
|
|
19
|
+
p.parent.mkdir(parents=True, exist_ok=True)
|
|
20
|
+
with p.open("a", encoding="utf-8") as f:
|
|
21
|
+
f.write(content)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def delete_file(path: str) -> None:
|
|
25
|
+
"""Delete a file. Raises FileNotFoundError if the file does not exist."""
|
|
26
|
+
p = Path(path)
|
|
27
|
+
if not p.exists():
|
|
28
|
+
raise FileNotFoundError(f"No such file: '{path}'")
|
|
29
|
+
p.unlink()
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: testtri
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: A simple Python library for common file operations
|
|
5
|
+
License: MIT
|
|
6
|
+
Project-URL: Homepage, https://github.com/your-username/testTRI
|
|
7
|
+
Keywords: file,fileops,io
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.8
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
|
|
14
|
+
# testTRI
|
|
15
|
+
|
|
16
|
+
[](https://github.com/TRI-IE/testTRI/actions/workflows/publish.yaml)
|
|
17
|
+
|
|
18
|
+
A simple Python library for common file operations.
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pip install testtri
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Or install locally in development mode:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pip install -e .
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Usage
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
from testtri import read_file, write_file, append_file, delete_file
|
|
36
|
+
|
|
37
|
+
# Create / overwrite a file
|
|
38
|
+
write_file("hello.txt", "Hello, world!")
|
|
39
|
+
|
|
40
|
+
# Read a file
|
|
41
|
+
content = read_file("hello.txt")
|
|
42
|
+
print(content) # Hello, world!
|
|
43
|
+
|
|
44
|
+
# Append to a file
|
|
45
|
+
append_file("hello.txt", "\nA second line.")
|
|
46
|
+
|
|
47
|
+
# Delete a file
|
|
48
|
+
delete_file("hello.txt")
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## API
|
|
52
|
+
|
|
53
|
+
| Function | Description |
|
|
54
|
+
|---|---|
|
|
55
|
+
| `read_file(path)` | Read and return file contents as a string |
|
|
56
|
+
| `write_file(path, content)` | Create or overwrite a file with the given content |
|
|
57
|
+
| `append_file(path, content)` | Append content to a file (creates it if missing) |
|
|
58
|
+
| `delete_file(path)` | Delete a file (raises `FileNotFoundError` if missing) |
|
|
59
|
+
|
|
60
|
+
## Running Tests
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
pip install pytest
|
|
64
|
+
pytest tests/
|
|
65
|
+
```
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
.gitignore
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
.github/workflows/publish.yaml
|
|
5
|
+
src/testtri/__init__.py
|
|
6
|
+
src/testtri/fileops.py
|
|
7
|
+
src/testtri.egg-info/PKG-INFO
|
|
8
|
+
src/testtri.egg-info/SOURCES.txt
|
|
9
|
+
src/testtri.egg-info/dependency_links.txt
|
|
10
|
+
src/testtri.egg-info/top_level.txt
|
|
11
|
+
tests/__init__.py
|
|
12
|
+
tests/test_fileops.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
testtri
|
|
File without changes
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from testtri import append_file, delete_file, read_file, write_file
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def test_write_and_read_file(tmp_path):
|
|
7
|
+
target = tmp_path / "hello.txt"
|
|
8
|
+
write_file(str(target), "Hello, world!")
|
|
9
|
+
assert read_file(str(target)) == "Hello, world!"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def test_write_overwrites_existing_file(tmp_path):
|
|
13
|
+
target = tmp_path / "data.txt"
|
|
14
|
+
write_file(str(target), "first")
|
|
15
|
+
write_file(str(target), "second")
|
|
16
|
+
assert read_file(str(target)) == "second"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def test_write_creates_parent_directories(tmp_path):
|
|
20
|
+
target = tmp_path / "a" / "b" / "file.txt"
|
|
21
|
+
write_file(str(target), "nested")
|
|
22
|
+
assert read_file(str(target)) == "nested"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def test_append_file(tmp_path):
|
|
26
|
+
target = tmp_path / "log.txt"
|
|
27
|
+
append_file(str(target), "line1\n")
|
|
28
|
+
append_file(str(target), "line2\n")
|
|
29
|
+
assert read_file(str(target)) == "line1\nline2\n"
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def test_append_creates_file_if_missing(tmp_path):
|
|
33
|
+
target = tmp_path / "new.txt"
|
|
34
|
+
append_file(str(target), "data")
|
|
35
|
+
assert read_file(str(target)) == "data"
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def test_delete_file(tmp_path):
|
|
39
|
+
target = tmp_path / "todelete.txt"
|
|
40
|
+
write_file(str(target), "bye")
|
|
41
|
+
delete_file(str(target))
|
|
42
|
+
assert not target.exists()
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def test_delete_file_raises_if_missing(tmp_path):
|
|
46
|
+
target = tmp_path / "ghost.txt"
|
|
47
|
+
with pytest.raises(FileNotFoundError):
|
|
48
|
+
delete_file(str(target))
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def test_read_file_raises_if_missing(tmp_path):
|
|
52
|
+
target = tmp_path / "missing.txt"
|
|
53
|
+
with pytest.raises(FileNotFoundError):
|
|
54
|
+
read_file(str(target))
|