From: Shane Jaroch Date: Sat, 24 Jan 2026 07:12:21 +0000 (-0500) Subject: a few more name tweaks and config changes X-Git-Url: https://git.nutra.tk/v2?a=commitdiff_plain;h=8b42aca88492d089fa2d4cb9aaaf9c0ec2a93066;p=gamesguru%2Fgetmyancestors.git a few more name tweaks and config changes --- diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b25f1d4..4a5bffd 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -51,6 +51,9 @@ jobs: run: make lint if: runner.os == 'Linux' + - name: Test [Install] + run: make test/install + - name: Test [Unit] run: make test/unit diff --git a/Makefile b/Makefile index f9f5e37..d60754a 100644 --- a/Makefile +++ b/Makefile @@ -11,46 +11,6 @@ _help: # @grep -Eh '\s##\s' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}' -# -include .env - - -.PHONY: test/unit -test/unit: ##H@@ Run Unit tests only - $(PYTHON) -m coverage run -p -m pytest getmyancestors/tests - -# Installation -.PHONY: deps -deps: ##H@@ Install dependencies - $(PYTHON) -m pip install --no-user ".[dev]" - -# Installation tests -.PHONY: test/install -test/install: ##H@@ Run installation tests - $(PYTHON) -m coverage run -p -m pytest tests/test_installation.py - -.PHONY: test/offline -test/offline: ##H@@ Run offline verification (requires fixtures) - $(PYTHON) -m pytest tests/offline_test.py - - -# Generate targets for all test files (enables autocomplete) -TEST_FILES := $(wildcard getmyancestors/tests/test_*.py) -TEST_TARGETS := $(patsubst getmyancestors/tests/%.py,test/unit/%,$(TEST_FILES)) - -.PHONY: $(TEST_TARGETS) -$(TEST_TARGETS): test/unit/%: - pytest getmyancestors/tests/$*.py -v - -.PHONY: test/ -test/: ##H@@ Run unit & E2E tests -test/: test/unit test/offline test/cov - -.PHONY: test/cov -test/cov: ##H@@ Combine all coverage data and show report - -$(PYTHON) -m coverage combine - $(PYTHON) -m coverage report - - REMOTE_HEAD ?= origin/master PY_CHANGED_FILES ?= $(shell git diff --name-only --diff-filter=MACU $(REMOTE_HEAD) '*.py') PY_CHANGED_FILES_FLAG ?= $(if $(PY_CHANGED_FILES),1,) @@ -122,6 +82,51 @@ mypy: fi +# -include .env + +# Installation +.PHONY: deps +deps: ##H@@ Install dependencies + $(PYTHON) -m pip install --no-user ".[dev]" + + +.PHONY: test/unit +test/unit: ##H@@ Run Unit tests only + $(PYTHON) -m coverage run -p -m pytest getmyancestors/tests + + +# Generate targets for all test files (enables autocomplete) +TEST_FILES := $(wildcard getmyancestors/tests/test_*.py) +TEST_TARGETS := $(patsubst getmyancestors/tests/%.py,test/unit/%,$(TEST_FILES)) + +.PHONY: $(TEST_TARGETS) +$(TEST_TARGETS): test/unit/%: + pytest getmyancestors/tests/$*.py -v + + +.PHONY: test +test: ##H@@ Run unit & E2E tests +test: test/unit test/offline test/install test/cov + +.PHONY:test/ +test/:test + +.PHONY: test/cov +test/cov: ##H@@ Combine all coverage data and show report + -$(PYTHON) -m coverage combine + $(PYTHON) -m coverage report + + +.PHONY: test/install +test/install: ##H@@ Run installation tests + $(PYTHON) -m coverage run -p -m pytest tests/test_installation.py + + +.PHONY: test/offline +test/offline: ##H@@ Run offline verification (requires fixtures) + $(PYTHON) -m pytest tests/offline_test.py + + .PHONY: clean clean: ##H@@ Clean up build files/cache rm -rf *.egg-info build dist .coverage .coverage.* diff --git a/getmyancestors/classes/gedcom.py b/getmyancestors/classes/gedcom.py index 7b7b17e..fd0b8c0 100644 --- a/getmyancestors/classes/gedcom.py +++ b/getmyancestors/classes/gedcom.py @@ -1,5 +1,3 @@ -import os -import sys from typing import Optional from getmyancestors.classes.constants import FACT_TYPES, ORDINANCES @@ -13,15 +11,7 @@ from getmyancestors.classes.tree import ( Ordinance, Source, ) - - -def _warn(msg: str): - """Write a warning message to stderr with optional color (if TTY).""" - use_color = sys.stderr.isatty() or os.environ.get("FORCE_COLOR", "") - if use_color: - sys.stderr.write(f"\033[33m{msg}\033[0m\n") - else: - sys.stderr.write(f"{msg}\n") +from getmyancestors.utils import _error, _warn class Gedcom: @@ -359,6 +349,11 @@ class Gedcom: f"Warning: Family @F{num}@ ({husb_name} & {wife_name}) missing _FSFTID tag, " f"using GEDCOM pointer as fallback." ) + if husb_name != "Unknown" and wife_name != "Unknown": + _error( + f"Error: Family @F{num}@ ({husb_name} & {wife_name}) has NO _FSFTID tag! " + "This may imply a problem with the FamilySearch data. You may need to investigate it." + ) fam.fid = num # Use GEDCOM pointer ID as fallback for _num, fam in self.fam.items(): diff --git a/getmyancestors/classes/tree/core.py b/getmyancestors/classes/tree/core.py index 718cc72..c3aa0d4 100644 --- a/getmyancestors/classes/tree/core.py +++ b/getmyancestors/classes/tree/core.py @@ -375,8 +375,10 @@ class Indi: def print(self, file=sys.stdout): """print individual in GEDCOM format""" file.write("0 @I%s@ INDI\n" % self.id) + printed_names = set() if self.name: self.name.print(file) + printed_names.add(self.name) for nick in sorted( self.nicknames, key=lambda x: ( @@ -390,6 +392,7 @@ class Indi: ), ): file.write(cont("2 NICK %s %s" % (nick.given, nick.surname))) + printed_names.add(nick) for birthname in sorted( self.birthnames, key=lambda x: ( @@ -402,7 +405,9 @@ class Indi: x.note.text if x.note else "", ), ): - birthname.print(file) + if birthname not in printed_names: + birthname.print(file) + printed_names.add(birthname) for aka in sorted( self.aka, key=lambda x: ( @@ -415,7 +420,9 @@ class Indi: x.note.text if x.note else "", ), ): - aka.print(file, "aka") + if aka not in printed_names: + aka.print(file, "aka") + printed_names.add(aka) for married_name in sorted( self.married, key=lambda x: ( @@ -428,7 +435,9 @@ class Indi: x.note.text if x.note else "", ), ): - married_name.print(file, "married") + if married_name not in printed_names: + married_name.print(file, "married") + printed_names.add(married_name) if self.gender: file.write("1 SEX %s\n" % self.gender) for fact in sorted( diff --git a/getmyancestors/mergemyanc.py b/getmyancestors/mergemyanc.py index e3e9e86..d0e273f 100755 --- a/getmyancestors/mergemyanc.py +++ b/getmyancestors/mergemyanc.py @@ -26,15 +26,6 @@ app = typer.Typer( ) -def _warn(msg: str): - """Write a warning message to stderr with optional color (if TTY).""" - use_color = sys.stderr.isatty() or os.environ.get("FORCE_COLOR", "") - if use_color: - sys.stderr.write(f"\033[33m{msg}\033[0m\n") - else: - sys.stderr.write(f"{msg}\n") - - @app.command() def main( files: Annotated[ @@ -129,10 +120,20 @@ def main( target_set.clear() seen = set() for n in all_names: - s = str(n) - if s not in seen: + # Use all relevant fields for deduplication key, similar to sort key + # but using the object's hash/eq properties if possible, or a tuple representation + key = ( + n.given, + n.surname, + n.prefix, + n.suffix, + n.kind, + n.alternative, + n.note.text if hasattr(n, "note") and n.note else None, + ) + if key not in seen: target_set.add(n) - seen.add(s) + seen.add(key) # Helper for whitespace normalization in quotes def norm_space(s): diff --git a/getmyancestors/tests/test_indi_name.py b/getmyancestors/tests/test_indi_name.py index ee9924d..1c6a30c 100644 --- a/getmyancestors/tests/test_indi_name.py +++ b/getmyancestors/tests/test_indi_name.py @@ -1,5 +1,3 @@ - - from getmyancestors.classes.tree.core import Indi, Tree diff --git a/getmyancestors/utils.py b/getmyancestors/utils.py new file mode 100644 index 0000000..25208d6 --- /dev/null +++ b/getmyancestors/utils.py @@ -0,0 +1,20 @@ +import os +import sys + + +def _warn(msg: str): + """Write a yellow warning message to stderr with optional color (if TTY).""" + use_color = sys.stderr.isatty() or os.environ.get("FORCE_COLOR", "") + if use_color: + sys.stderr.write(f"\033[33m{msg}\033[0m\n") + else: + sys.stderr.write(f"{msg}\n") + + +def _error(msg: str): + """Write a red error message to stderr with optional color (if TTY).""" + use_color = sys.stderr.isatty() or os.environ.get("FORCE_COLOR", "") + if use_color: + sys.stderr.write(f"\033[31m{msg}\033[0m\n") + else: + sys.stderr.write(f"{msg}\n") diff --git a/pyproject.toml b/pyproject.toml index b0f6009..9aa0fa8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -148,7 +148,7 @@ source = ["getmyancestors"] data_file = ".tmp/.coverage" [tool.coverage.report] -fail_under = 67.98 +fail_under = 68.55 precision = 2 show_missing = true diff --git a/res/testdata b/res/testdata index 741c02c..8166780 160000 --- a/res/testdata +++ b/res/testdata @@ -1 +1 @@ -Subproject commit 741c02ced0efd708044045e855cb7fafd6eb6aa8 +Subproject commit 8166780fe62343decac53b265364e2576cdbf195