diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 197df08c..8e9bf6e1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -56,6 +56,10 @@ jobs: python -c 'from geouned.GEOReverse import reverse' python -m pip install .[tests] + - name: testing package version + run: | + python -m pytest -v tests/test_version.py + - name: testing GEOUNED functionality run: | python -m pytest -v tests/test_convert.py diff --git a/.gitignore b/.gitignore index 72c1f57c..c5cb4161 100644 --- a/.gitignore +++ b/.gitignore @@ -180,3 +180,6 @@ docs/source/_build/** docs/build/** docs/source/_autosummary/* docs/jupyter_execute + +# setuptools_scm dynamic version file +src/_version.py diff --git a/docs/install/install_linux.rst b/docs/install/install_linux.rst index 446b65e5..c8dfb5db 100644 --- a/docs/install/install_linux.rst +++ b/docs/install/install_linux.rst @@ -53,7 +53,7 @@ Install GEOUNED with pip, we also prefix this with "python -m" to ensure that pi .. code-block:: sh - python -m pip install git+https://github.com/GEOUNED-code/GEOUNED.git@dev + python -m pip install geouned Then you will be able to run import GEOUNED from within Python @@ -119,7 +119,7 @@ Install GEOUNED with pip, we also prefix this with "python -m" to ensure that pi .. code-block:: sh - python -m pip install git+https://github.com/GEOUNED-code/GEOUNED.git@dev + python -m pip install geouned Then you will be able to run import GEOUNED from within Python diff --git a/docs/install/install_windows.rst b/docs/install/install_windows.rst index a8199578..a318a39b 100644 --- a/docs/install/install_windows.rst +++ b/docs/install/install_windows.rst @@ -7,7 +7,7 @@ User install with Mamba (recommended) First we need to install a Mamba distribution. There are a few options but here we opt for Miniforge3 as it includes Mamba. -You can follow the install instructions for `Miniforge3 here `_ or follows the commands below. +You can follow the install instructions for `Miniforge3 here `_ . Download and execute the Miniforge3 Windows installer @@ -19,7 +19,6 @@ Follow the prompts and complete the installation process Open "Miniforge Prompt" which will now be available on your start menu. - It is recommended to create a new environment .. code-block:: sh @@ -40,6 +39,59 @@ Install FreeCAD which is the main dependency mamba install -c conda-forge freecad +Install GEOUNED with pip, we also prefix this with "python -m" to ensure that pip install uses the correct Python interpreter. + +.. code-block:: sh + + python -m pip install geouned + +Then you will be able to run import GEOUNED from within Python + +.. code-block:: python + + import geouned + +You will also be able to use the GEOUNED command line tool + +.. code-block:: bash + + geouned_cadtocsg --help + +User install with Conda +~~~~~~~~~~~~~~~~~~~~~~~ + +First we need to install a Conda distribution. There are a few options but we here we opt for `MiniConda3 `_ as it downloads quicker than the fuller `AnaConda `_. + +You can follow the install instructions for `MiniConda3 `_ + +Download and execute the Miniforge3 Windows installer + +You can get it from the Miniforge3 GitHub repository `here `_ or from the link below + +`https://repo.anaconda.com/miniconda/Miniconda3-latest-Windows-x86_64.exe `_ + +Open "Anaconda Prompt (miniconda3)" which will now be available on your start menu. + +It is recommended to create a new environment + +.. code-block:: sh + + conda create --name new_env python=3.11 + +Activate the new environment + +.. code-block:: sh + + conda activate new_env + +We have aspirations to create a conda-forge package which will combine these final two steps, but for now FreeCAD and GEOUNED can be installed in two commands. +Install FreeCAD which is the main dependency + +.. code-block:: sh + + conda install -c conda-forge freecad + + Install GEOUNED with pip, we also prefix this with "python -m" to ensure that pip install uses the correct Python interpreter. .. code-block:: sh diff --git a/pyproject.toml b/pyproject.toml index fb8ab327..ea4bbfd9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,11 @@ +[build-system] +requires = ["setuptools >= 69.5.1", "setuptools_scm[toml]>=8.1.0"] +build-backend = "setuptools.build_meta" + [project] name = "geouned" -version = "1.0.1" +license = {file = "LICENSE.txt"} +dynamic = ["version"] authors = [ { name="Juan-Pablo Catalan", email="jpcatalan@ind.uned.es" }, { name="Patrick Sauvan", email="psauvan@ind.uned.es" }, @@ -12,9 +17,10 @@ maintainers = [ { name="Francisco Ogando", email="fogando@ind.uned.es" }, { name="Javier Alguacil", email="jalguacil@ind.uned.es" }, ] -description = "Conversion tool from CAD to CGS/CGS to CAD for Monte Carlo particle transport codes (MCNP & OpenMC)" +description = "Conversion tool from CAD to CGS/CGS to CAD for Monte Carlo particle transport codes (OpenMC, Phits, Serpent, MCNP)" readme = "README.md" requires-python = ">=3.8" +keywords = ["csg", "cad", "openmc", "serpent", "phits", "mcnp", "geometry"] classifiers = [ "Programming Language :: Python :: 3", "License :: OSI Approved :: European Union Public Licence 1.2 (EUPL 1.2)", @@ -28,7 +34,7 @@ dependencies = [ [project.urls] Homepage = "https://github.com/GEOUNED-org" Repository = "https://github.com/GEOUNED-org/GEOUNED" -Documentation = "https://github.com/GEOUNED-org/GEOUNED/docs" +Documentation = "https://geouned-org.github.io/GEOUNED/index.html" [project.optional-dependencies] tests = [ @@ -47,3 +53,9 @@ geouned_cadtocsg = "geouned.GEOUNED.scripts.geouned_cadtocsg:main" [tool.black] line-length = 128 + +[tool.setuptools_scm] +write_to = "src/_version.py" + +[tool.setuptools] +package-dir = {"" = "src"} diff --git a/src/geouned/GEOUNED/code_version.py b/src/geouned/GEOUNED/code_version.py index d02c2595..d4e697aa 100644 --- a/src/geouned/GEOUNED/code_version.py +++ b/src/geouned/GEOUNED/code_version.py @@ -59,6 +59,3 @@ - fix some bugs with Torus (not all) - implementation of the geometry conversion to PHITS code input file (by T. Okano Nissin High Voltage Corporation (NHVC)) """ - -GEOUNED_Version = "1.0.1" -GEOUNED_ReleaseDate = "19/03/2024" diff --git a/src/geouned/GEOUNED/core.py b/src/geouned/GEOUNED/core.py index f1e01320..8d0399b0 100644 --- a/src/geouned/GEOUNED/core.py +++ b/src/geouned/GEOUNED/core.py @@ -6,6 +6,7 @@ from os import mkdir, path from pathlib import Path from typing import get_type_hints +from importlib.metadata import version import FreeCAD import Part @@ -64,6 +65,58 @@ def __init__( self.numeric_format = numeric_format self.settings = settings + @property + def stepFile(self): + return self._stepFile + + @stepFile.setter + def stepFile(self, value: str): + if not isinstance(value, str): + raise TypeError(f"geouned.CadToCsg.stepFile should be a str, not a {type(value)}") + self._stepFile = value + + @property + def options(self): + return self._options + + @options.setter + def options(self, value: Options): + if not isinstance(value, Options): + raise TypeError(f"geouned.CadToCsg.options should be an instance of geouned.Options, not a {type(value)}") + self._options = value + + @property + def tolerances(self): + return self._tolerances + + @tolerances.setter + def tolerances(self, value: tolerances): + if not isinstance(value, Tolerances): + raise TypeError(f"geouned.CadToCsg.tolerances should be an instance of geouned.Tolerances, not a {type(value)}") + self._tolerances = value + + @property + def numeric_format(self): + return self._numeric_format + + @numeric_format.setter + def numeric_format(self, value: numeric_format): + if not isinstance(value, NumericFormat): + raise TypeError( + f"geouned.CadToCsg.numeric_format should be an instance of geouned.NumericFormat, not a {type(value)}" + ) + self._numeric_format = value + + @property + def settings(self): + return self._settings + + @settings.setter + def settings(self, value: settings): + if not isinstance(value, Settings): + raise TypeError(f"geouned.CadToCsg.settings should be an instance of geouned.Settings, not a {type(value)}") + self._settings = value + def export_csg( self, title: str = "Converted with GEOUNED", @@ -385,7 +438,7 @@ def start(self): logger.info("start") freecad_version = ".".join(FreeCAD.Version()[:3]) - logger.info(f"GEOUNED version {GEOUNED_Version} {GEOUNED_ReleaseDate} \nFreeCAD version {freecad_version}") + logger.info(f"GEOUNED version {version('geouned')} \nFreeCAD version {freecad_version}") if self.stepFile == "": raise ValueError("Cannot run the code. Step file name is missing") diff --git a/src/geouned/GEOUNED/write/mcnp_format.py b/src/geouned/GEOUNED/write/mcnp_format.py index a53d020a..240026f0 100644 --- a/src/geouned/GEOUNED/write/mcnp_format.py +++ b/src/geouned/GEOUNED/write/mcnp_format.py @@ -5,10 +5,10 @@ import math from datetime import datetime from pathlib import Path +from importlib.metadata import version import FreeCAD -from ..code_version import * from ..utils.basic_functions_part1 import is_opposite, points_to_coeffs from ..utils.functions import SurfacesDict from .functions import CardLine, change_surf_sign, mcnp_surface, write_mcnp_cell_def @@ -107,15 +107,13 @@ def write_input(self, filename): def __write_header__(self): - version = GEOUNED_Version - releaseDate = GEOUNED_ReleaseDate freeCAD_Version = "{V[0]:}.{V[1]:}.{V[2]:}".format(V=FreeCAD.Version()) Header = f"""{self.Title} C ______ _______ _____ _ _ __ _ _______ ______ C | ____ |______ | | ___ | | | \\ | |______ | \\ C |_____| |______ |_____| |_____| | \\_| |______ |_____/ -C Version : {version} {releaseDate} +C Version : {version('geouned')} C FreeCAD Version : {freeCAD_Version} """ diff --git a/src/geouned/GEOUNED/write/phits_format.py b/src/geouned/GEOUNED/write/phits_format.py index 34e3077f..98352137 100644 --- a/src/geouned/GEOUNED/write/phits_format.py +++ b/src/geouned/GEOUNED/write/phits_format.py @@ -15,10 +15,10 @@ import re from datetime import datetime from pathlib import Path +from importlib.metadata import version import FreeCAD -from ..code_version import * from ..utils.basic_functions_part1 import is_opposite, points_to_coeffs from ..utils.functions import SurfacesDict from .functions import ( @@ -143,8 +143,6 @@ def write_phits(self, filename): def __write_phits_header__(self): - version = GEOUNED_Version - releaseDate = GEOUNED_ReleaseDate freeCAD_Version = "{V[0]:}.{V[1]:}.{V[2]:}".format(V=FreeCAD.Version()) Header = ( @@ -153,10 +151,10 @@ def __write_phits_header__(self): $ ______ _______ _____ _ _ __ _ _______ ______ $ | ____ |______ | | ___ | | | \ | |______ | \ $ |_____| |______ |_____| |_____| | \_| |______ |_____/ -$ Version : {} {} +$ Version : {} $ FreeCAD Version : {} $ PHITSFormat Version : 0.0.2.3 06/03/2024\n""".format( - self.Title, version, releaseDate, freeCAD_Version + self.Title, version("geouned"), freeCAD_Version ) ) diff --git a/src/geouned/GEOUNED/write/serpent_format.py b/src/geouned/GEOUNED/write/serpent_format.py index edd14e6d..bb5b1eb2 100644 --- a/src/geouned/GEOUNED/write/serpent_format.py +++ b/src/geouned/GEOUNED/write/serpent_format.py @@ -4,10 +4,10 @@ import logging from datetime import datetime from pathlib import Path +from importlib.metadata import version import FreeCAD -from ..code_version import * from ..utils.basic_functions_part1 import is_opposite, points_to_coeffs from ..utils.functions import SurfacesDict from .functions import change_surf_sign, serpent_surface, write_serpent_cell_def @@ -101,15 +101,13 @@ def write_input(self, filename): def __write_header__(self): - version = GEOUNED_Version - releaseDate = GEOUNED_ReleaseDate freeCAD_Version = "{V[0]:}.{V[1]:}.{V[2]:}".format(V=FreeCAD.Version()) Header = f"""{self.Title} % ______ _______ _____ _ _ __ _ _______ ______ % | ____ |______ | | ___ | | | \\ | |______ | \\ % |_____| |______ |_____| |_____| | \\_| |______ |_____/ -% Version : {version} {releaseDate} +% Version : {version('geouned')} % FreeCAD Version : {freeCAD_Version} """ diff --git a/src/geouned/__init__.py b/src/geouned/__init__.py index 296fc72a..6b65aa64 100644 --- a/src/geouned/__init__.py +++ b/src/geouned/__init__.py @@ -1,4 +1,5 @@ import logging +from importlib.metadata import version # this try except attempts to import freecad (lowercase) which is the conda # package name for FreeCAD (mixed case) upon import the conda package appends @@ -16,3 +17,8 @@ setup_logger("general_logger", "geouned_general_log.log") setup_logger("fuzzy_logger", "geouned_fuzzy_log.log") setup_logger("solids_logger", "geouned_solids_log.log") + + +__version__ = version("geouned") + +__all__ = ["__version__"] diff --git a/tests/test_version.py b/tests/test_version.py new file mode 100644 index 00000000..7e459ab2 --- /dev/null +++ b/tests/test_version.py @@ -0,0 +1,17 @@ +import geouned + + +def test_version(): + """Check that __version__ exists and is correctly formatted""" + version = geouned.__version__ + # Ensure it is given as a string + assert isinstance(version, str) + + # develop is used as the default version name in the dockerfile + if version != "develop": + version_bits = version.split(".") + assert len(version_bits) >= 2, f"Version number is {version}" + # Ensure both of the first two parts is convertable to int + # (The third/fourth part, if it exists, may be a development version) + for bit in version_bits[:2]: + assert bit.isdigit(), f"Version number is {version}"