Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/python-style.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
python-version: ${{ matrix.python-version }}
- name: Install Dependencies
run: |
pip install black
- name: Lint with Black
run: black --check .
continue-on-error: true
pip install ruff
- name: Lint with Ruff
run: ruff check .
continue-on-error: true
56 changes: 11 additions & 45 deletions .github/workflows/python-tests.yml
Original file line number Diff line number Diff line change
@@ -1,76 +1,42 @@
# Source: https://jacobian.org/til/github-actions-poetry/
# Run this job on pushes to `main`, and for pull requests. If you don't specify
# `branches: [main], then this actions runs _twice_ on pull requests, which is
# annoying.

name: Python Unit Tests with Poetry
name: Python Unit Tests with uv

on:
push:
branches: [main]
pull_request:

jobs:
poetry-run-pytest:
uv-run-pytest:
runs-on: ubuntu-latest
strategy:
fail-fast: false # This ensures all matrix jobs run even if some fail
fail-fast: false
matrix:
python-version: ['3.10', '3.11', '3.12', '3.13'] # Adjust these as per available versions
python-version: ['3.10', '3.11', '3.12', '3.13']

# Use Docker container to handle the GDAL dependencies
container:
image: osgeo/gdal:ubuntu-small-3.6.3

steps:
- uses: actions/checkout@v2

# Setup Python version specified in matrix
- uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}

# Install essential build tools required for compiling Python packages
- name: Install build tools
run: |
apt-get update
apt-get install -y \
python3 python3-pip python3-venv \
build-essential \
libgeos-dev \
libproj-dev

# Cache the installation of Poetry
- name: cache poetry install
uses: actions/cache@v2
with:
path: ~/.local
key: poetry-1.6.1-${{ matrix.python-version }}

# Install Poetry using snok/install-poetry action
- uses: snok/install-poetry@v1
with:
version: 1.6.1
virtualenvs-create: true
virtualenvs-in-project: true

# Configure Poetry: virtualenvs will be created in the project's folder
- name: Configure Poetry
run: poetry config virtualenvs.in-project true

# Cache your project dependencies
- name: cache deps
id: cache-deps
uses: actions/cache@v2
with:
path: ./.venv
key: ${{ runner.os }}-venv-${{ matrix.python-version }}-${{ hashFiles('**/poetry.lock') }}

# Install dependencies with Poetry, avoiding caching of the project itself
- run: poetry install --no-interaction --no-root
if: steps.cache-deps.outputs.cache-hit != 'true'
- name: Install uv
run: pip3 install uv

# Install the project using Poetry to fully-exercise pyproject.toml
- run: poetry install --no-interaction
- name: Sync environment with uv
run: uv sync --extra dev

# Run tests with pytest as configured in pyproject.toml
- run: poetry run pytest
- name: Run tests with pytest
run: uv run pytest
910 changes: 0 additions & 910 deletions poetry.lock

This file was deleted.

2 changes: 0 additions & 2 deletions poetry.toml

This file was deleted.

57 changes: 22 additions & 35 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,46 +6,33 @@ authors = [
{ name = "Philip Orlando", email = "phlp.orlando@gmail.com" },
{ name = "Brandon Istenes", email = "bistenes@gmail.com" },
]
requires-python = "~=3.10"
readme = "README.md"
dependencies = [
"fiona>=1.10.1",
"geodatasets>=2024.8.0",
"geopandas==1.1.1",
"pyogrio>=0.11.1",
"pytest>=7.4.4",
"tqdm>=4.67.1",
]

[project.urls]
Repository = "https://github.com/philiporlando/fgdb_to_gpkg"
Issues = "https://github.com/philiporlando/fgdb_to_gpkg/issues"

[project.dependencies]
fiona = "1.10.b2"
geopandas = "0.12.2"
[tool.poetry]
name = "fgdb-to-gpkg"
version = "0.3.2"
description = "A lightweight Python package that converts Esri File GeoDataBases into OGC GeoPackages"
authors = [
"Philip Orlando <phlp.orlando@gmail.com>",
"Brandon Istenes <bistenes@gmail.com>",
]
readme = "README.md"

[tool.poetry.dependencies]
python = "^3.10"
geopandas = "1.0"
shapely = "^2.0.1"
tqdm = "^4.65.0"
argparse = "^1.4.0"
fiona = "1.10b2"
gdal = "3.6.3"
numpy = "^1.26.0"
geodatasets = "^2024.7.0"
pyogrio = "^0.10.0"
pandas = "^2.2.3"
[project.scripts]
fgdb-to-gpkg = "fgdb_to_gpkg:main"

[tool.poetry.group.dev.dependencies]
pytest = "^7.2.2"
pytest-cov = "^4.0.0"
pytest-mock = "^3.12.0"
geodatasets = "^2024.7.0"
[project.optional-dependencies]
dev = [
"pytest>=7.2.2,<8",
"pytest-cov>=4.0.0,<5",
"pytest-mock>=3.12.0,<4",
"geodatasets>=2024.7.0,<2025",
"pyogrio",
]

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

[tool.poetry.scripts]
fgdb-to-gpkg = "fgdb_to_gpkg:main"
requires = ["hatchling"]
build-backend = "hatchling.build"
56 changes: 32 additions & 24 deletions tests/test_fgdb_to_gpkg.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def setup_fgdb_gpkg(naturalearth_land) -> tuple[str, str, list[str]]:
gdf["layer_name"] = layer
gdf.to_file(fgdb_path, layer=layer, driver="OpenFileGDB")

yield fgdb_path, gpkg_path, layer
yield fgdb_path, gpkg_path, layers


def test_remove_gpkg_if_overwrite(setup_fgdb_gpkg: tuple[str, str, list[str]]):
Expand All @@ -65,53 +65,61 @@ def test_remove_gpkg_if_overwrite(setup_fgdb_gpkg: tuple[str, str, list[str]]):

# Test for get_layer_lists function
def test_get_layer_lists(setup_fgdb_gpkg: tuple[str, str, list[str]]):
fgdb_path, gpkg_path, _ = setup_fgdb_gpkg
fc_list, layer_list = get_layer_lists(fgdb_path, gpkg_path, False)
fgdb_path, gpkg_path, layers = setup_fgdb_gpkg
fc_list, _layer_list = get_layer_lists(fgdb_path, gpkg_path, False)
# Check the returned lists as per your expectations
assert set(fc_list) == set(layers)


# Test for convert_layer function
def test_convert_layer(setup_fgdb_gpkg: tuple[str, str, list[str]]):
fgdb_path, gpkg_path, layer = setup_fgdb_gpkg
convert_layer(layer, fgdb_path, gpkg_path, False, [])
# Read and check if the layer was added to the GeoPackage
fgdb_path, gpkg_path, layers = setup_fgdb_gpkg
for layer in layers:
convert_layer(layer, fgdb_path, gpkg_path, False, [])
# Read and check if the layer was added to the GeoPackage
gdf = gpd.read_file(gpkg_path, layer=layer)
assert not gdf.empty, f"Layer {layer} should not be empty after conversion."


def test_fgdb_to_gpkg(setup_fgdb_gpkg: tuple[str, str, Literal["test_fc"]]):
# Test basic functionality of fgdb_to_gpkg
fgdb_path, gpkg_path, layer = setup_fgdb_gpkg
fgdb_path, gpkg_path, layers = setup_fgdb_gpkg

fgdb_to_gpkg(fgdb_path, gpkg_path)

# Read and compare data from File GeoDatabase and GeoPackage
gdf_fgdb = gpd.read_file(fgdb_path, layer=layer)
gdf_gpkg = gpd.read_file(gpkg_path, layer=layer)
assert gdf_fgdb.equals(gdf_gpkg)
for layer in layers:
gdf_fgdb = gpd.read_file(fgdb_path, layer=layer)
gdf_gpkg = gpd.read_file(gpkg_path, layer=layer)
assert gdf_fgdb.equals(gdf_gpkg)


def test_fgdb_to_gpkg_overwrite(setup_fgdb_gpkg: tuple[str, str, Literal["test_fc"]]):
# Test the overwrite functionality of fgdb_to_gpkg
fgdb_path, gpkg_path, layer = setup_fgdb_gpkg
def test_fgdb_to_gpkg_overwrite(setup_fgdb_gpkg: tuple[str, str, list[str]]):
# Test the overwrite functionality of fgdb_to_gpkg for all layers
fgdb_path, gpkg_path, layers = setup_fgdb_gpkg

# Convert the File GeoDatabase to a GeoPackage
# Convert the File GeoDatabase to a GeoPackage (initial conversion)
fgdb_to_gpkg(fgdb_path, gpkg_path, overwrite=True)

# Modify the original GeoDataFrame
gdf_modified = gpd.read_file(fgdb_path, layer=layer)
gdf_modified["new_column"] = "test"
for layer in layers:
# Modify the original GeoDataFrame for this layer
gdf_modified = gpd.read_file(fgdb_path, layer=layer)
gdf_modified["new_column"] = "test"

# Write the modified GeoDataFrame to File GeoDatabase
gdf_modified.to_file(fgdb_path, layer=layer, driver="OpenFileGDB")
# Write the modified GeoDataFrame to File GeoDatabase
gdf_modified.to_file(fgdb_path, layer=layer, driver="OpenFileGDB")

# Convert the modified File GeoDatabase to GeoPackage with overwrite=False
fgdb_to_gpkg(fgdb_path, gpkg_path, overwrite=False)
gdf_gpkg_no_overwrite = gpd.read_file(gpkg_path, layer=layer)
assert "new_column" not in gdf_gpkg_no_overwrite.columns
for layer in layers:
gdf_gpkg_no_overwrite = gpd.read_file(gpkg_path, layer=layer)
assert "new_column" not in gdf_gpkg_no_overwrite.columns

# Convert the modified File GeoDatabase to GeoPackage with overwrite=True
fgdb_to_gpkg(fgdb_path, gpkg_path, overwrite=True)
gdf_gpkg_overwrite = gpd.read_file(gpkg_path, layer=layer)
assert "new_column" in gdf_gpkg_overwrite.columns
for layer in layers:
gdf_gpkg_overwrite = gpd.read_file(gpkg_path, layer=layer)
assert "new_column" in gdf_gpkg_overwrite.columns


def test_nonexistent_fgdb(setup_fgdb_gpkg: tuple[str, str, Literal["test_fc"]]):
Expand All @@ -133,7 +141,7 @@ def test_layer_already_exists(setup_fgdb_gpkg: tuple[str, str, Literal["test_fc"

# Try converting again with overwrite=False
# This should raise a warning because the layers already exists
with pytest.warns(UserWarning) as record:
with pytest.warns(UserWarning):
fgdb_to_gpkg(fgdb_path, gpkg_path, overwrite=False)


Expand Down
Loading