diff --git a/.github/actions/invariance_tests/action.yml b/.github/actions/invariance_tests/action.yml index fdef8871..171cf7d3 100644 --- a/.github/actions/invariance_tests/action.yml +++ b/.github/actions/invariance_tests/action.yml @@ -5,17 +5,21 @@ inputs: description: 'Name of the uploaded artifact' required: false default: 'invariance-test-results' + library-path: + description: 'Path to the InChI library under test' + required: false + default: 'CMake_build/full_build/INCHI-1-SRC/INCHI_API/libinchi/src/lib/libinchi.so' runs: using: "composite" steps: - name: Run invariance tests - run: run-tests --test-config=INCHI-1-TEST/tests/test_library/config/config.invariance.py --data-config=INCHI-1-TEST/tests/test_library/config/config.ci.py + run: python INCHI-1-TEST/tests/test_library/inchi_tests/run_tests.py --test=invariance --lib-path=${{ inputs.library-path}} --data-config=INCHI-1-TEST/tests/test_library/config/config_ci.py shell: bash - name: Write invariance summary if: '!cancelled()' - run: parse-log --test-config=INCHI-1-TEST/tests/test_library/config/config.invariance.py --data-config=INCHI-1-TEST/tests/test_library/config/config.ci.py + run: python INCHI-1-TEST/tests/test_library/inchi_tests/parse_log.py --test=invariance --lib-path=${{ inputs.library-path}} --data-config=INCHI-1-TEST/tests/test_library/config/config_ci.py shell: bash - name: Upload invariance test results diff --git a/.github/actions/regression_tests/action.yml b/.github/actions/regression_tests/action.yml index fd163700..ada9a518 100644 --- a/.github/actions/regression_tests/action.yml +++ b/.github/actions/regression_tests/action.yml @@ -5,18 +5,26 @@ inputs: description: 'Name of the uploaded artifact' required: false default: 'regression-test-results' + library-path: + description: 'Path to the InChI library under test' + required: false + default: 'CMake_build/full_build/INCHI-1-SRC/INCHI_API/libinchi/src/lib/libinchi.so' + shell: + description: 'Shell for running the tests' + required: false + default: 'bash' runs: using: "composite" steps: - name: Run regression tests - run: run-tests --test-config=INCHI-1-TEST/tests/test_library/config/config.regression.py --data-config=INCHI-1-TEST/tests/test_library/config/config.ci.py - shell: bash + run: python INCHI-1-TEST/tests/test_library/inchi_tests/run_tests.py --test=regression --lib-path=${{ inputs.library-path}} --data-config=INCHI-1-TEST/tests/test_library/config/config_ci.py + shell: ${{ inputs.shell }} - name: Write regression summary if: '!cancelled()' - run: parse-log --test-config=INCHI-1-TEST/tests/test_library/config/config.regression.py --data-config=INCHI-1-TEST/tests/test_library/config/config.ci.py - shell: bash + run: python INCHI-1-TEST/tests/test_library/inchi_tests/parse_log.py --test=regression --lib-path=${{ inputs.library-path}} --data-config=INCHI-1-TEST/tests/test_library/config/config_ci.py + shell: ${{ inputs.shell }} - name: Upload regression test results if: '!cancelled()' diff --git a/.github/workflows/build_matrix.json b/.github/workflows/build_matrix.json new file mode 100644 index 00000000..d5a7aae7 --- /dev/null +++ b/.github/workflows/build_matrix.json @@ -0,0 +1,36 @@ +[ + { + "os": "ubuntu-22.04", + "slug": "linux", + "name": "Ubuntu 22.04", + "pre_build": "sudo apt update && sudo apt install -y cmake && python3 -m pip install -e INCHI-1-TEST[invariance-tests]", + "build_exe": "cmake --build CMake_build/cli_build", + "build_lib": "cmake --build CMake_build/libinchi_build", + "exe_path": "CMake_build/cli_build/bin/inchi-1", + "lib_path": "CMake_build/libinchi_build/bin/libinchi.so", + "main_path": "CMake_build/libinchi_build/bin/inchi_main" + }, + { + "os": "windows-2022", + "slug": "windows", + "name": "Windows Server 2022", + "pre_build": "python -m pip install -e INCHI-1-TEST[invariance-tests]", + "build_exe": "cmake --build CMake_build/cli_build --config Release", + "build_lib": "cmake --build CMake_build/libinchi_build --config Release", + "exe_path": "CMake_build/cli_build/bin/Release/inchi-1.exe", + "lib_path": "CMake_build/libinchi_build/bin/Release/libinchi.dll", + "main_path": "CMake_build/libinchi_build/bin/Release/inchi_main.exe" + + }, + { + "os": "macos-14", + "slug": "macos", + "name": "MacOS 14", + "pre_build": "python -m pip install -e INCHI-1-TEST[invariance-tests]", + "build_exe": "cmake --build CMake_build/cli_build", + "build_lib": "cmake --build CMake_build/libinchi_build", + "exe_path": "CMake_build/cli_build/bin/inchi-1", + "lib_path": "CMake_build/libinchi_build/bin/libinchi.dylib", + "main_path": "CMake_build/libinchi_build/bin/inchi_main" + } +] \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1e8a1a56..1af789cb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,38 +1,150 @@ -# Trigger this workflow by pushing a release tag. -# Make sure that `HEAD` is pointing to the commit you want to release. -# Then run `git tag -a v -m "Release version (--
)" && git push && git push --tags`. -# For example `git tag -a v1.06 -m "Release version 1.06 (2020-12-20)" && git push && git push --tags`. -name: InChI Release +name: Release on: + workflow_dispatch: push: + # TODO: Remove branches trigger. + branches: [ release-automation ] + # Trigger this workflow by pushing a release tag. + # Make sure that `HEAD` is pointing to the commit you want to release. + # Then run `git tag -a v -m "Release version (--
)" && git push && git push --tags`. + # For example `git tag -a v1.06 -m "Release version 1.06 (2020-12-20)" && git push && git push --tags`. tags: - v1.* jobs: - release: - runs-on: ubuntu-latest + define_matrix: + runs-on: ubuntu-22.04 + outputs: + matrix: ${{ steps.define_matrix.outputs.matrix }} + steps: + - uses: actions/checkout@v4 + + - name: Define build matrix + id: define_matrix + # The build matrix is used to interpolate commands and inputs throughout the remainder of the workflow. + # Since those interpolations are potentially security-sensitive, we verify the hash of the build matrix. + if: ${{ hashFiles('.github/workflows/build_matrix.json') == 'ae87ded543b131908cf5aed1502d0e39b2cb9374693598ef7f09c5c5a8be4e52' }} + run: | + echo "matrix=$(cat .github/workflows/build_matrix.json| jq -c .)" >> $GITHUB_OUTPUT + + build_and_test: + needs: define_matrix + strategy: + matrix: + include: + ${{ fromJson(needs.define_matrix.outputs.matrix) }} + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + env: + RELEASE_DIR: inchi-${{ matrix.slug }}-${{ github.sha }} permissions: contents: write steps: - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - name: Install dependencies + run: ${{ matrix.pre_build }} + + - name: Set up Visual Studio shell + if: runner.os == 'Windows' + uses: egor-tensin/vs-shell@9a932a62d05192eae18ca370155cf877eecc2202 with: - fetch-depth: 0 + arch: x64 + + - name: Build executable + run: | + cmake -B CMake_build/cli_build -S INCHI-1-SRC/INCHI_EXE/inchi-1/src + ${{ matrix.build_exe }} - - name: Checkout release - # `ref_name` is triggering tag. - run: git checkout ${{ github.ref_name }} + - name: Test executable + run: pytest INCHI-1-TEST/tests/test_executable --exe-path ${{ matrix.exe_path }} + + - name: Build library + run: | + cmake -B CMake_build/libinchi_build -S INCHI-1-SRC/INCHI_API/demos/inchi_main/src + ${{ matrix.build_lib }} + + - name: Test library + uses: ./.github/actions/regression_tests + with: + artifact-name: regression-test-results-${{ matrix.slug }}-${{ github.sha }} + library-path: ${{ matrix.lib_path }} + shell: ${{ runner.os == 'Windows' && 'pwsh' || 'bash' }} + + - name: Upload CMake configurations + uses: actions/upload-artifact@v4 + with: + name: CMake-configurations-${{ matrix.slug }}-${{ github.sha }} + path: | + CMake_build/libinchi_build/CMakeCache.txt + CMake_build/cli_build/CMakeCache.txt - - name: Build release artifacts + - name: Collect artifacts run: | - zip -r INCHI-1-BIN.zip INCHI-1-BIN - zip -r INCHI-1-DOC.zip INCHI-1-DOC - zip -r INCHI-1-SRC.zip INCHI-1-SRC - zip -r INCHI-1-TEST.zip INCHI-1-TEST + mkdir -p ${{ env.RELEASE_DIR }} + cp ${{ matrix.exe_path }} ${{ env.RELEASE_DIR }} + cp ${{ matrix.lib_path }} ${{ env.RELEASE_DIR }} + cp ${{ matrix.main_path }} ${{ env.RELEASE_DIR }} + + - id: upload-unsigned-artifacts + uses: actions/upload-artifact@v4 + with: + name: ${{ env.RELEASE_DIR }} + path: ${{ env.RELEASE_DIR }} + + - name: Sign artifacts + if: runner.os == 'Windows' + uses: signpath/github-action-submit-signing-request@ced31329c0317e779dad2eec2a7c3bb46ea1343e + with: + api-token: ${{ secrets.SIGNPATH_API_TOKEN }} + organization-id: 656f8204-f8c5-4028-bd48-f832f5f89b31 + project-slug: InChI + signing-policy-slug: test-signing + github-artifact-id: ${{ steps.upload-unsigned-artifacts.outputs.artifact-id }} + wait-for-completion: true + output-artifact-directory: ${{ env.RELEASE_DIR }}-signed + + - uses: actions/upload-artifact@v4 + if: runner.os == 'Windows' + with: + name: ${{ env.RELEASE_DIR }}-signed + path: ${{ env.RELEASE_DIR }}-signed + + release: + needs: build_and_test + runs-on: ubuntu-22.04 + permissions: + contents: write + + steps: + - name: Download artifacts + uses: actions/download-artifact@v4 + with: + path: release_artifacts + pattern: inchi-* + + - name: Package artifacts + run: zip -r release_artifacts.zip release_artifacts + + - name: Download CMake configurations + uses: actions/download-artifact@v4 + with: + path: cmake_configurations + pattern: CMake-configurations-* + + - name: Package CMake configurations + run: zip -r cmake_configurations.zip cmake_configurations - name: Create release + # TODO: lift this guard to release job level + if: github.ref_type == 'tag' shell: bash env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -42,4 +154,4 @@ jobs: --verify-tag \ --title "${{ github.ref_name }}" \ --notes "For details about this release have a look at the [CHANGELOG](INCHI-1-DOC/CHANGELOG.md)." \ - INCHI-1-BIN.zip INCHI-1-DOC.zip INCHI-1-SRC.zip INCHI-1-TEST.zip + release_artifacts.zip cmake_configurations.zip diff --git a/INCHI-1-BIN/linux/32bit/inchi-1 b/INCHI-1-BIN/linux/32bit/inchi-1 deleted file mode 100644 index adc0f6cc..00000000 Binary files a/INCHI-1-BIN/linux/32bit/inchi-1 and /dev/null differ diff --git a/INCHI-1-BIN/linux/32bit/inchi-1.gz b/INCHI-1-BIN/linux/32bit/inchi-1.gz deleted file mode 100644 index 4abec9e5..00000000 Binary files a/INCHI-1-BIN/linux/32bit/inchi-1.gz and /dev/null differ diff --git a/INCHI-1-BIN/linux/32bit/so/inchi_main b/INCHI-1-BIN/linux/32bit/so/inchi_main deleted file mode 100644 index c8314d5c..00000000 Binary files a/INCHI-1-BIN/linux/32bit/so/inchi_main and /dev/null differ diff --git a/INCHI-1-BIN/linux/32bit/so/inchi_main.gz b/INCHI-1-BIN/linux/32bit/so/inchi_main.gz deleted file mode 100644 index a3670454..00000000 Binary files a/INCHI-1-BIN/linux/32bit/so/inchi_main.gz and /dev/null differ diff --git a/INCHI-1-BIN/linux/32bit/so/libinchi.so b/INCHI-1-BIN/linux/32bit/so/libinchi.so deleted file mode 100644 index e7c4cbad..00000000 Binary files a/INCHI-1-BIN/linux/32bit/so/libinchi.so and /dev/null differ diff --git a/INCHI-1-BIN/linux/32bit/so/libinchi.so.gz b/INCHI-1-BIN/linux/32bit/so/libinchi.so.gz deleted file mode 100644 index f3f01ff7..00000000 Binary files a/INCHI-1-BIN/linux/32bit/so/libinchi.so.gz and /dev/null differ diff --git a/INCHI-1-BIN/linux/64bit/inchi-1 b/INCHI-1-BIN/linux/64bit/inchi-1 deleted file mode 100755 index 95f2353d..00000000 Binary files a/INCHI-1-BIN/linux/64bit/inchi-1 and /dev/null differ diff --git a/INCHI-1-BIN/linux/64bit/inchi-1.gz b/INCHI-1-BIN/linux/64bit/inchi-1.gz deleted file mode 100644 index d44314e3..00000000 Binary files a/INCHI-1-BIN/linux/64bit/inchi-1.gz and /dev/null differ diff --git a/INCHI-1-BIN/linux/64bit/so/inchi_main b/INCHI-1-BIN/linux/64bit/so/inchi_main deleted file mode 100644 index a90656c9..00000000 Binary files a/INCHI-1-BIN/linux/64bit/so/inchi_main and /dev/null differ diff --git a/INCHI-1-BIN/linux/64bit/so/inchi_main.gz b/INCHI-1-BIN/linux/64bit/so/inchi_main.gz deleted file mode 100644 index c00dd40d..00000000 Binary files a/INCHI-1-BIN/linux/64bit/so/inchi_main.gz and /dev/null differ diff --git a/INCHI-1-BIN/linux/64bit/so/libinchi.so b/INCHI-1-BIN/linux/64bit/so/libinchi.so deleted file mode 100644 index 54c802ce..00000000 Binary files a/INCHI-1-BIN/linux/64bit/so/libinchi.so and /dev/null differ diff --git a/INCHI-1-BIN/linux/64bit/so/libinchi.so.gz b/INCHI-1-BIN/linux/64bit/so/libinchi.so.gz deleted file mode 100644 index 8a425628..00000000 Binary files a/INCHI-1-BIN/linux/64bit/so/libinchi.so.gz and /dev/null differ diff --git a/INCHI-1-BIN/readme.md b/INCHI-1-BIN/readme.md deleted file mode 100644 index 35e17d9f..00000000 --- a/INCHI-1-BIN/readme.md +++ /dev/null @@ -1,49 +0,0 @@ -/* -

-International Chemical Identifier (InChI)
-Version 1
-Software version 1.07
-April 30, 2024
-

- -

MIT License

- -

Copyright ©2024 IUPAC and InChI Trust

- -

Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions:

- -

The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software.

- -

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE.

- -

The InChI library and programs are free software developed under the -auspices of the International Union of Pure and Applied Chemistry (IUPAC). -Originally developed at NIST.
-Modifications and additions by IUPAC and the InChI Trust.
-Some portions of code were developed/changed by external contributors -(either contractor or volunteer) which are listed in the file -'External-contributors' included in this distribution.

- -

info@inchi-trust.org

-*/ -

 

-

This directory contains binaries of command line `InChI` executable (inchi-1) and InChI API library (libinchi). The 64-bit and 32-bit versions are supplied for both Microsoft® Windows, Linux and MacOS® .

- -

Please note that InChI stand-alone executable inchi-1[.exe] does not require .dll/.so libraries.

- -

To use the shared library, you may wish to create libinchi.so.1 as a symbolic link to libinchi.so.1.07.

- -

Also included is a legacy 1.06 version of winchi-1.exe, a graphical Microsoft® Windows application (located in directory windows; it is a 32-bit version which will also run under 64-bit Microsoft® Windows).

- diff --git a/INCHI-1-BIN/windows/32bit/dll/inchi_main.exe b/INCHI-1-BIN/windows/32bit/dll/inchi_main.exe deleted file mode 100644 index 9fdec718..00000000 Binary files a/INCHI-1-BIN/windows/32bit/dll/inchi_main.exe and /dev/null differ diff --git a/INCHI-1-BIN/windows/32bit/dll/inchi_main.zip b/INCHI-1-BIN/windows/32bit/dll/inchi_main.zip deleted file mode 100644 index cd8cac18..00000000 Binary files a/INCHI-1-BIN/windows/32bit/dll/inchi_main.zip and /dev/null differ diff --git a/INCHI-1-BIN/windows/32bit/dll/libgcc_s_dw2-1.dll b/INCHI-1-BIN/windows/32bit/dll/libgcc_s_dw2-1.dll deleted file mode 100644 index b2c6a7e9..00000000 Binary files a/INCHI-1-BIN/windows/32bit/dll/libgcc_s_dw2-1.dll and /dev/null differ diff --git a/INCHI-1-BIN/windows/32bit/dll/libinchi.dll b/INCHI-1-BIN/windows/32bit/dll/libinchi.dll deleted file mode 100644 index 181425fa..00000000 Binary files a/INCHI-1-BIN/windows/32bit/dll/libinchi.dll and /dev/null differ diff --git a/INCHI-1-BIN/windows/32bit/dll/libinchi.zip b/INCHI-1-BIN/windows/32bit/dll/libinchi.zip deleted file mode 100644 index d9fd37d4..00000000 Binary files a/INCHI-1-BIN/windows/32bit/dll/libinchi.zip and /dev/null differ diff --git a/INCHI-1-BIN/windows/32bit/inchi-1.exe b/INCHI-1-BIN/windows/32bit/inchi-1.exe deleted file mode 100644 index 363a29ae..00000000 Binary files a/INCHI-1-BIN/windows/32bit/inchi-1.exe and /dev/null differ diff --git a/INCHI-1-BIN/windows/32bit/inchi-1.zip b/INCHI-1-BIN/windows/32bit/inchi-1.zip deleted file mode 100644 index e71c6db2..00000000 Binary files a/INCHI-1-BIN/windows/32bit/inchi-1.zip and /dev/null differ diff --git a/INCHI-1-BIN/windows/32bit/libgcc_s_dw2-1.dll b/INCHI-1-BIN/windows/32bit/libgcc_s_dw2-1.dll deleted file mode 100644 index b2c6a7e9..00000000 Binary files a/INCHI-1-BIN/windows/32bit/libgcc_s_dw2-1.dll and /dev/null differ diff --git a/INCHI-1-BIN/windows/64bit/dll/inchi_main.exe b/INCHI-1-BIN/windows/64bit/dll/inchi_main.exe deleted file mode 100644 index 08a04f31..00000000 Binary files a/INCHI-1-BIN/windows/64bit/dll/inchi_main.exe and /dev/null differ diff --git a/INCHI-1-BIN/windows/64bit/dll/inchi_main.zip b/INCHI-1-BIN/windows/64bit/dll/inchi_main.zip deleted file mode 100644 index 67420351..00000000 Binary files a/INCHI-1-BIN/windows/64bit/dll/inchi_main.zip and /dev/null differ diff --git a/INCHI-1-BIN/windows/64bit/dll/libinchi.dll b/INCHI-1-BIN/windows/64bit/dll/libinchi.dll deleted file mode 100644 index 71a4bdff..00000000 Binary files a/INCHI-1-BIN/windows/64bit/dll/libinchi.dll and /dev/null differ diff --git a/INCHI-1-BIN/windows/64bit/dll/libinchi.zip b/INCHI-1-BIN/windows/64bit/dll/libinchi.zip deleted file mode 100644 index b8d28f28..00000000 Binary files a/INCHI-1-BIN/windows/64bit/dll/libinchi.zip and /dev/null differ diff --git a/INCHI-1-BIN/windows/64bit/inchi-1.exe b/INCHI-1-BIN/windows/64bit/inchi-1.exe deleted file mode 100644 index ff1800af..00000000 Binary files a/INCHI-1-BIN/windows/64bit/inchi-1.exe and /dev/null differ diff --git a/INCHI-1-BIN/windows/64bit/inchi-1.zip b/INCHI-1-BIN/windows/64bit/inchi-1.zip deleted file mode 100644 index 0d943aa5..00000000 Binary files a/INCHI-1-BIN/windows/64bit/inchi-1.zip and /dev/null differ diff --git a/INCHI-1-DOC/CHANGELOG.md b/INCHI-1-DOC/CHANGELOG.md index 563c96bd..b8ecda7d 100644 --- a/INCHI-1-DOC/CHANGELOG.md +++ b/INCHI-1-DOC/CHANGELOG.md @@ -1,6 +1,11 @@ # Change log -## v1.07.5 2026-02-04 +## v1.07.5 2025-??-?? + +### Changed + +- The build artifacts are no longer shipped in `INCHI-1-BIN` (the latter directory has been removed). Instead, the build artifacts are distributed under . +- 32-bit artifacts are no longer shipped. ### Fixed diff --git a/INCHI-1-DOC/FAQ/html/inchi-faq.html b/INCHI-1-DOC/FAQ/html/inchi-faq.html index 70b30a78..9ee68273 100644 --- a/INCHI-1-DOC/FAQ/html/inchi-faq.html +++ b/INCHI-1-DOC/FAQ/html/inchi-faq.html @@ -1781,9 +1781,8 @@

15.4. Standard vs. Non-standard InChI generation

15.5. How do I install the InChI Software?

-

To use the software, first extract (preserving the folder structure) the contents of the zip files of distribution package to a directory of your choice. There are four archive files (INCHI-1-API.ZIP, INCHI-1-BIN.ZIP, INCHI-1-DOC.ZIP, INCHI-1-TEST.ZIP); each is unpacked into a separate subdirectory with the name corresponding to the archive name.

-

InChI executables and library are located in INCHI-1-BIN subdirectory (in lower-level subdirectories for different platforms, Windows/Linux and 32/64 bit).

-

The executables are ready to use (e.g., no special installation/accessing registry is necessary under Windows). Installing dynamic libraries may require appropriate placement and setting up necessary access paths; please consult your system manual.

+

Ready to use artifacts for Windows, Linux, and macOS are distributed on https://github.com/IUPAC-InChI/InChI/releases.

+

Installing dynamic libraries may require appropriate placement and setting up necessary access paths; please consult your system manual.

For additional details, you may check with software release notes and user guide (files RelNotes.pfd and InChI_UserGuide.pdf, resp.), which are available in the distribution package).

diff --git a/INCHI-1-DOC/UserGuide/InChI_UserGuide.md b/INCHI-1-DOC/UserGuide/InChI_UserGuide.md index 5503c30a..ca6e1fce 100644 --- a/INCHI-1-DOC/UserGuide/InChI_UserGuide.md +++ b/INCHI-1-DOC/UserGuide/InChI_UserGuide.md @@ -184,8 +184,6 @@ The InChI API calls are documented in the separate “InChI API Reference” doc **Introduction** -Windows graphical program of InChI generation is provided in a ‘zip’ file INCHI-1-BIN.zip. To - To start the program, run the file winchi-1.exe that was extracted from the zip file. Generating an InChI begins with the selection of an input structure file. The simplest way is to drag the input structure file from Windows Explorer directory list into the InChI window. Structures also may be copied from certain chemical structure editors (ISIS/Draw with “Copy Mol/Rxnfile to the Clipboard” option or from ACD/ChemSketch) and pasted into the InChI window (Select Edit -> Paste from winchi-1 menu). The input structure file pathname may be provided as a command line option when you start winchi-1. Selection of the input structure file may also be done by first clicking on the ‘Open’ button (top left corner) and then, in the dialog box that appears selecting a structure file using the ‘…’ button on the right of the ‘Input Structure File’ field. You may select any of the sample .mol or .sdf files for initial testing. In this dialog you may also enter “Text Header for ID”; this will simply add to the InChI header a structure ID if it is present in an input SDfile (from other input formats the header and ID are extracted automatically). diff --git a/INCHI-1-SRC/INCHI_API/libinchi/src/CMakeLists.txt b/INCHI-1-SRC/INCHI_API/libinchi/src/CMakeLists.txt index 33648da5..60f769ed 100644 --- a/INCHI-1-SRC/INCHI_API/libinchi/src/CMakeLists.txt +++ b/INCHI-1-SRC/INCHI_API/libinchi/src/CMakeLists.txt @@ -151,7 +151,7 @@ if(MATH_LIBRARY) target_link_libraries(libinchi PUBLIC ${MATH_LIBRARY}) endif() -target_compile_definitions(libinchi PRIVATE +target_compile_definitions(libinchi PRIVATE fPIC COMPILE_ANSI_ONLY TARGET_API_LIB @@ -163,10 +163,9 @@ string(REGEX REPLACE "/RTC(su|[1su])" "" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DE string(REGEX REPLACE "/RTC(su|[1su])" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") set_target_properties(libinchi PROPERTIES PREFIX "") -# set_target_properties(libinchi PROPERTIES SOVERSION 1.07 PREFIX "") + if(UNIX AND NOT APPLE) - # set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--version-script=${P_LIBINCHI_MAP}/libinchi.map,-z,relro") target_link_options(libinchi PRIVATE "LINKER:--version-script=${P_LIBINCHI_MAP}/libinchi.map,-z,relro") elseif(WIN32 AND NOT MSVC) target_link_options(libinchi PRIVATE "LINKER:--version-script=${P_LIBINCHI_MAP}/libinchi.map") diff --git a/INCHI-1-SRC/INCHI_EXE/inchi-1/readme.txt b/INCHI-1-SRC/INCHI_EXE/inchi-1/readme.txt index 24a9d005..b3027509 100644 --- a/INCHI-1-SRC/INCHI_EXE/inchi-1/readme.txt +++ b/INCHI-1-SRC/INCHI_EXE/inchi-1/readme.txt @@ -63,12 +63,6 @@ inchi-1 SUB-DIRECTORY Contains Microsoft Visual Studio 2015 project to create inchi-1.exe - -Precompiled inchi-1.exe created with Microsoft Visual Studio 2015 is in INCHI-1-BIN -section of this distribution. - - - ========= LINKS ========= diff --git a/INCHI-1-TEST/Dockerfile b/INCHI-1-TEST/Dockerfile index eebc7f7d..d11c6d1a 100644 --- a/INCHI-1-TEST/Dockerfile +++ b/INCHI-1-TEST/Dockerfile @@ -40,15 +40,4 @@ ENV lib_legacy_dir='/inchi/CMake_build/libinchi_build/lib/v1_6_0' RUN mkdir -p $lib_legacy_dir RUN ./INCHI-1-TEST/build_with_makefile.sh v1.06 $lib_legacy_dir lib || exit 1; -FROM python:3.12 AS inchi_test - -WORKDIR /inchi - -# Include only what's necessary for running the tests. -COPY --from=inchi_compilation /inchi/CMake_build /inchi/CMake_build -COPY --from=inchi_compilation /inchi/INCHI-1-TEST/src /inchi/INCHI-1-TEST/src -COPY --from=inchi_compilation /inchi/INCHI-1-TEST/tests /inchi/INCHI-1-TEST/tests -COPY --from=inchi_compilation /inchi/INCHI-1-TEST/pyproject.toml /inchi/INCHI-1-TEST/pyproject.toml -COPY --from=inchi_compilation /inchi/INCHI-1-TEST/install_test_dependencies.sh /inchi/INCHI-1-TEST/install_test_dependencies.sh - RUN cd INCHI-1-TEST && ./install_test_dependencies.sh diff --git a/INCHI-1-TEST/README.md b/INCHI-1-TEST/README.md index 408524ab..18f3a917 100644 --- a/INCHI-1-TEST/README.md +++ b/INCHI-1-TEST/README.md @@ -59,7 +59,7 @@ Build the tests with and subsequently run them with ```shell -cd CMake_build/full_build/INCHI-1-TEST/test/test_unit && ctest --output-on-failure +cd CMake_build/full_build/INCHI-1-TEST/tests/test_unit && ctest --output-on-failure ``` ## Meta tests @@ -122,11 +122,10 @@ During an invariance test, the atom indices of a structure are permuted repeated schematic ```Shell -run-tests --test-config=INCHI-1-TEST/tests/test_library/config/config.invariance.py --data-config=INCHI-1-TEST/tests/test_library/config/config..py +python INCHI-1-TEST/tests/test_library/inchi_tests/run_tests.py --test=invariance --lib-path= --data-config=INCHI-1-TEST/tests/test_library/config/config_.py ``` -uses `libinchi.so`, the shared library specified with `--test-config`, -to compute the InChI output for multiple permutations of each molfile in each SDF under ``. +uses `` to compute the InChI output for multiple permutations of each molfile in each SDF under ``. If not all permutations produce the same InChI output, a test failure is logged under `.invariance_.log` (where `` reflects the start of the test run). @@ -144,21 +143,19 @@ The 2nd run results in a regression, since the output no longer matches the refe #### Compute references ```Shell -run-tests --test-config=INCHI-1-TEST/tests/test_library/config/config.regression_reference.py --data-config=INCHI-1-TEST/tests/test_library/config/config..py +python INCHI-1-TEST/tests/test_library/inchi_tests/run_tests.py --test=regression_reference --lib-path= --data-config=INCHI-1-TEST/tests/test_library/config/config_.py ``` -uses `libinchi.so`, the shared library specified with `--test-config`, -and generates an `.regression_reference.sqlite` file for each SDF under `INCHI-1-TEST/tests/test_library/data/`. +uses `` to generate an `.regression_reference.sqlite` file for each SDF under `INCHI-1-TEST/tests/test_library/data/`. The `sqlite` file contains a table with the results for each molfile. #### Run tests against the references ```Shell -run-tests --test-config=INCHI-1-TEST/tests/test_library/config/config.regression.py --data-config=INCHI-1-TEST/tests/test_library/config/config..py +python INCHI-1-TEST/tests/test_library/inchi_tests/run_tests.py --test=regression --lib-path= --data-config=INCHI-1-TEST/tests/test_library/config/config_.py ``` -uses `libinchi.so`, the shared library specified with `--test-config`, -to compute the results (e.g., InChI strings and keys) for each molfile in each SDF under `INCHI-1-TEST/tests/test_library/data/`. +uses `` to compute the results (e.g., InChI strings and keys) for each molfile in each SDF under `INCHI-1-TEST/tests/test_library/data/`. Those results are compared with the corresponding reference. Failed comparisons are logged to `.regression_.log` (where `` reflects the start of the test run). @@ -171,7 +168,7 @@ The tests should now fail and indicate that the difference between the reference In addition to inspecting the raw logs, you can review the results by running ```Shell -parse-log --test-config=INCHI-1-TEST/tests/test_library/config/config..py --data-config=INCHI-1-TEST/tests/test_library/config/config..py +python INCHI-1-TEST/tests/test_library/inchi_tests/parse_log.py --test= --lib-path= --data-config=INCHI-1-TEST/tests/test_library/config/config_.py ``` where `` can be `regression` or `invariance`. @@ -260,27 +257,19 @@ services: #### Configuration files The tests can be configured with Python files (e.g., `config.py`). +The configuration files must have [valid Python module names](https://docs.python.org/dev/reference/lexical_analysis.html#identifiers). We're not using other configuration formats (e.g., `config.yaml`), since the configuration needs to be powerful enough to enable dynamic customization (e.g., parsing molfile ID). -We provide two [templates](tests/test_library/inchi_tests/config_models.py) under `config_models.py` that allow you to customize the configuration: - -##### `TestConfig` - -Lets you customize the test itself, e.g., -configuring what to run ("regression", "regression-reference", or "invariance"), -which InChI library to use, and which parameters to pass to the InChI API. -For details, have a look at the comments in the `TestConfig` class. -Your configuration file, e.g., `config/custom-regression.py` must contain an instance of `TestConfig` called `config`. -For an example of how to instantiate a `TestConfig` object, have a look at our [regression configuration](tests/test_library/config/config.regression.py). +We provide a[template](tests/test_library/inchi_tests/config_models.py) under `config_models.py` that allow you to customize the configuration: ##### `DataConfig` Lets you configure your custom data, e.g., location of the data. For details, have a look at the comments in the `DataConfig` class. Your configuration file, e.g., `config/custom-data.py` must contain an instance of `DataConfig` called `config`. -For an example of how to instantiate a `DataConfig` object, have a look at our [CI configuration](tests/test_library/config/config.ci.py). +For an example of how to instantiate a `DataConfig` object, have a look at our [CI configuration](tests/test_library/config/config_ci.py). Note that the `DataConfig` object must point to data that you've [mounted into the container](#your-own-dataset). -For an example of how to instantiate a `DataConfig` object, have a look at our the configuration of our [CI data](tests/test_library/config/config.ci.py). +For an example of how to instantiate a `DataConfig` object, have a look at our the configuration of our [CI data](tests/test_library/config/config_ci.py). #### Run your custom tests @@ -299,5 +288,7 @@ docker compose -f path/to/docker-compose.custom.yml run --rm inchi-custom-test b and run the test according to your configuration against your data ```Shell -run-tests --test-config=config/custom-regression.py --data-config=config/custom-data.py +python INCHI-1-TEST/tests/test_library/inchi_tests/run_tests.py --test= --lib-path= --data-config=config/custom-data.py ``` + +with `` being one of "regression", "regression-reference", or "invariance". diff --git a/INCHI-1-TEST/pyproject.toml b/INCHI-1-TEST/pyproject.toml index 5c8edd07..5e241212 100644 --- a/INCHI-1-TEST/pyproject.toml +++ b/INCHI-1-TEST/pyproject.toml @@ -8,15 +8,11 @@ dependencies = ["pydantic == 2.11.5", "pytest == 8.3.5"] # FIXME: Don't force numpy major version as soon as https://github.com/IUPAC-InChI/InChI/issues/35 is resolved. invariance-tests = ["rdkit == 2023.9.6", "numpy < 2.0.0"] -[project.scripts] -run-tests = "inchi_tests.run_tests:main" -parse-log = "inchi_tests.parse_log:main" - [tool.setuptools.packages.find] where = ["src", "tests/test_library"] include = ["sdf_pipeline", "inchi_tests"] namespaces = false [tool.pytest.ini_options] -testpaths = ["tests"] +testpaths = ["tests/test_executable", "tests/test_meta"] addopts = "-v" diff --git a/INCHI-1-TEST/tests/test_executable/conftest.py b/INCHI-1-TEST/tests/test_executable/conftest.py index 0cad6260..42288203 100644 --- a/INCHI-1-TEST/tests/test_executable/conftest.py +++ b/INCHI-1-TEST/tests/test_executable/conftest.py @@ -1,5 +1,6 @@ import pytest import subprocess +from sys import platform from typing import Callable from pathlib import Path from dataclasses import dataclass @@ -23,6 +24,16 @@ class InchiResult: problem: str +def adapt_args_to_platform(args: str) -> list[str]: + args_platform_agnostic = [ + arg[1:] if arg.startswith(("-", "/")) else arg for arg in args.split() + ] + if platform == "win32": + return [f"/{arg}" for arg in args_platform_agnostic] + + return [f"-{arg}" for arg in args_platform_agnostic] + + @pytest.fixture def run_inchi_exe(request, tmp_path: Path) -> Callable: def _run_inchi_exe(input: str, args: str = "") -> InchiResult: @@ -45,7 +56,7 @@ def _run_inchi_exe(input: str, args: str = "") -> InchiResult: [ exe_path, *[input_path, output_path, log_path, problem_path], - *args.split(), + *adapt_args_to_platform(args), ], capture_output=True, text=True, diff --git a/INCHI-1-TEST/tests/test_library/config/config.invariance.py b/INCHI-1-TEST/tests/test_library/config/config.invariance.py deleted file mode 100644 index 90cbf160..00000000 --- a/INCHI-1-TEST/tests/test_library/config/config.invariance.py +++ /dev/null @@ -1,8 +0,0 @@ -from inchi_tests.config_models import TestConfig -from pathlib import Path - - -config = TestConfig( - name="invariance", - inchi_library_path=Path("CMake_build/full_build/INCHI-1-SRC/INCHI_API/libinchi/src/lib/libinchi.so"), -) diff --git a/INCHI-1-TEST/tests/test_library/config/config.regression.py b/INCHI-1-TEST/tests/test_library/config/config.regression.py deleted file mode 100644 index cbca7e14..00000000 --- a/INCHI-1-TEST/tests/test_library/config/config.regression.py +++ /dev/null @@ -1,8 +0,0 @@ -from inchi_tests.config_models import TestConfig -from pathlib import Path - - -config = TestConfig( - name="regression", - inchi_library_path=Path("CMake_build/full_build/INCHI-1-SRC/INCHI_API/libinchi/src/lib/libinchi.so"), -) diff --git a/INCHI-1-TEST/tests/test_library/config/config.regression_reference.py b/INCHI-1-TEST/tests/test_library/config/config.regression_reference.py deleted file mode 100644 index 528be395..00000000 --- a/INCHI-1-TEST/tests/test_library/config/config.regression_reference.py +++ /dev/null @@ -1,8 +0,0 @@ -from inchi_tests.config_models import TestConfig -from pathlib import Path - - -config = TestConfig( - name="regression-reference", - inchi_library_path=Path("CMake_build/libinchi_build/lib/v1_6_0/libinchi.so.v1.06"), -) diff --git a/INCHI-1-TEST/tests/test_library/config/config.ci.py b/INCHI-1-TEST/tests/test_library/config/config_ci.py similarity index 100% rename from INCHI-1-TEST/tests/test_library/config/config.ci.py rename to INCHI-1-TEST/tests/test_library/config/config_ci.py diff --git a/INCHI-1-TEST/tests/test_library/config/config.pubchem_compound.py b/INCHI-1-TEST/tests/test_library/config/config_pubchem_compound.py similarity index 100% rename from INCHI-1-TEST/tests/test_library/config/config.pubchem_compound.py rename to INCHI-1-TEST/tests/test_library/config/config_pubchem_compound.py diff --git a/INCHI-1-TEST/tests/test_library/config/config.pubchem_compound3d.py b/INCHI-1-TEST/tests/test_library/config/config_pubchem_compound3d.py similarity index 100% rename from INCHI-1-TEST/tests/test_library/config/config.pubchem_compound3d.py rename to INCHI-1-TEST/tests/test_library/config/config_pubchem_compound3d.py diff --git a/INCHI-1-TEST/tests/test_library/config/config.pubchem_substance.py b/INCHI-1-TEST/tests/test_library/config/config_pubchem_substance.py similarity index 100% rename from INCHI-1-TEST/tests/test_library/config/config.pubchem_substance.py rename to INCHI-1-TEST/tests/test_library/config/config_pubchem_substance.py diff --git a/INCHI-1-TEST/tests/test_library/inchi_tests/config_models.py b/INCHI-1-TEST/tests/test_library/inchi_tests/config_models.py index a86e185a..e1ff0d36 100644 --- a/INCHI-1-TEST/tests/test_library/inchi_tests/config_models.py +++ b/INCHI-1-TEST/tests/test_library/inchi_tests/config_models.py @@ -1,27 +1,7 @@ -import os -import sys -import importlib.util as importutil -from importlib.machinery import ModuleSpec -from pathlib import Path -from typing import Callable, Literal +from typing import Callable from pydantic import BaseModel, FilePath, DirectoryPath -class TestConfig(BaseModel): - # All paths are relative to the root of the repository. - - name: Literal["regression", "regression-reference", "invariance"] - # Path to the InChI shared library. - inchi_library_path: FilePath - # Parameters to pass to the InChI API. - inchi_api_parameters: str = "" - # Permute each structure N times. - n_invariance_runs: int = 10 - # Distribute the test over N separate processes. - # Default according to https://docs.python.org/3/library/multiprocessing.html#multiprocessing.cpu_count. - n_processes: int = len(os.sched_getaffinity(0)) - - class DataConfig(BaseModel): # All paths are relative to the root of the repository. @@ -36,14 +16,3 @@ class DataConfig(BaseModel): # The failures will be logged, but won't cause the test run to fail. # E.g., {"regression": {"foo", "bar"}, "invariance": {"baz"}}. expected_failures: dict[str, set[str]] = dict() - - -def load_config(config_name: str, config_path: Path) -> TestConfig | DataConfig: - spec: ModuleSpec | None = importutil.spec_from_file_location( - config_name, config_path - ) - module = importutil.module_from_spec(spec) - spec.loader.exec_module(module) - sys.modules[config_name] = module - - return module.config diff --git a/INCHI-1-TEST/tests/test_library/inchi_tests/consumers.py b/INCHI-1-TEST/tests/test_library/inchi_tests/consumers.py index 82e7d2a5..b57b2259 100644 --- a/INCHI-1-TEST/tests/test_library/inchi_tests/consumers.py +++ b/INCHI-1-TEST/tests/test_library/inchi_tests/consumers.py @@ -1,7 +1,6 @@ import ctypes import random from typing import Callable -from pathlib import Path from sdf_pipeline import drivers, utils from inchi_tests.inchi_api import make_inchi_from_molfile_text, get_inchi_key_from_inchi @@ -9,11 +8,10 @@ def regression_consumer( molfile: str, get_molfile_id: Callable, - inchi_lib_path: Path, + inchi_lib_path: str, inchi_api_parameters: str, ) -> drivers.ConsumerResult: - - inchi_lib = ctypes.CDLL(str(inchi_lib_path)) + inchi_lib = ctypes.CDLL(inchi_lib_path) exit_code, inchi_string, log, message, aux_info = make_inchi_from_molfile_text( inchi_lib, molfile, inchi_api_parameters ) @@ -38,12 +36,11 @@ def regression_consumer( def invariance_consumer( molfile: str, get_molfile_id: Callable, - inchi_lib_path: Path, + inchi_lib_path: str, inchi_api_parameters: str, n_invariance_runs: int, ) -> drivers.ConsumerResult: - - inchi_lib = ctypes.CDLL(str(inchi_lib_path)) + inchi_lib = ctypes.CDLL(inchi_lib_path) variants: list[dict[str, str | int]] = [] inchi_string_variants = set() inchi_key_variants = set() diff --git a/INCHI-1-TEST/tests/test_library/inchi_tests/parse_log.py b/INCHI-1-TEST/tests/test_library/inchi_tests/parse_log.py index a2539f1b..643bb4e9 100644 --- a/INCHI-1-TEST/tests/test_library/inchi_tests/parse_log.py +++ b/INCHI-1-TEST/tests/test_library/inchi_tests/parse_log.py @@ -1,12 +1,12 @@ import json import sys +import importlib from pathlib import Path from difflib import SequenceMatcher from collections import defaultdict from typing import Callable, Final, TextIO from sdf_pipeline.utils import select_records_from_gzipped_sdf from inchi_tests.utils import get_config_args -from inchi_tests.config_models import load_config def _get_html_diff(current: str, reference: str) -> str: @@ -170,13 +170,7 @@ def _write_html_log( return None -def main() -> None: - test_config_path, dataset_config_path = get_config_args() - - test_config = load_config("test_config", test_config_path) - data_config = load_config("data_config", dataset_config_path) - - test = test_config.name +def main(test, data_config) -> None: dataset = data_config.name data_path = data_config.path @@ -213,4 +207,11 @@ def main() -> None: if __name__ == "__main__": - main() + # Note that this file must be run as a script, i.e., `python parse_log.py`. + + test, _, dataset_config_path = get_config_args() + # https://docs.python.org/3/library/importlib.html#importing-a-source-file-directly + sys.path.append(str(Path(dataset_config_path).parent)) + data_config = importlib.import_module(str(Path(dataset_config_path).stem)) + + main(test, data_config.config) diff --git a/INCHI-1-TEST/tests/test_library/inchi_tests/run_tests.py b/INCHI-1-TEST/tests/test_library/inchi_tests/run_tests.py index f20b8496..36420681 100644 --- a/INCHI-1-TEST/tests/test_library/inchi_tests/run_tests.py +++ b/INCHI-1-TEST/tests/test_library/inchi_tests/run_tests.py @@ -1,31 +1,17 @@ +import os import logging +import multiprocessing +import sys +import importlib from functools import partial from datetime import datetime from pathlib import Path from sdf_pipeline import drivers -from typing import cast from inchi_tests.utils import get_current_time, get_progress, get_config_args -from inchi_tests.config_models import load_config, TestConfig, DataConfig from inchi_tests.consumers import regression_consumer, invariance_consumer -def main() -> None: - - test_config_path, dataset_config_path = get_config_args() - - test_config = load_config("test_config", Path(test_config_path)) - data_config = load_config("data_config", Path(dataset_config_path)) - - if not isinstance(test_config, TestConfig): - raise TypeError(f"Expected TestConfig, got {type(test_config)}.") - - if not isinstance(data_config, DataConfig): - raise TypeError(f"Expected DataConfig, got {type(data_config)}.") - - test_config = cast(TestConfig, test_config) - data_config = cast(DataConfig, data_config) - - test = test_config.name +def main(test, inchi_lib_path, data_config) -> None: dataset = data_config.name data_path = data_config.path @@ -36,9 +22,7 @@ def main() -> None: log_path = data_path.joinpath( f"{datetime.now().strftime('%Y%m%dT%H%M%S')}_{test}_{dataset}.log" ) - n_processes = test_config.n_processes - inchi_api_parameters = test_config.inchi_api_parameters - inchi_lib_path = test_config.inchi_library_path + n_processes = os.cpu_count() or 8 logging.basicConfig(filename=log_path, encoding="utf-8", level=logging.INFO) logging.info(f"{get_current_time()}: Using '{inchi_lib_path}'.") @@ -62,7 +46,7 @@ def main() -> None: consumer_function=partial( regression_consumer, inchi_lib_path=inchi_lib_path, - inchi_api_parameters=inchi_api_parameters, + inchi_api_parameters="", ), get_molfile_id=get_molfile_id, number_of_consumer_processes=n_processes, @@ -87,7 +71,7 @@ def main() -> None: consumer_function=partial( regression_consumer, inchi_lib_path=inchi_lib_path, - inchi_api_parameters=inchi_api_parameters, + inchi_api_parameters="", ), get_molfile_id=get_molfile_id, number_of_consumer_processes=n_processes, @@ -102,8 +86,8 @@ def main() -> None: consumer_function=partial( invariance_consumer, inchi_lib_path=inchi_lib_path, - inchi_api_parameters=inchi_api_parameters, - n_invariance_runs=test_config.n_invariance_runs, + inchi_api_parameters="", + n_invariance_runs=10, ), get_molfile_id=get_molfile_id, number_of_consumer_processes=n_processes, @@ -124,4 +108,16 @@ def main() -> None: if __name__ == "__main__": - main() + # Note that this file must be run as a script, i.e., `python run_tests.py`. + + # Initialize processes consistently across platforms. + # Otherwise, the default is "fork" on non-macOS-Unix and "spawn" on macOS and Windows. + # See https://docs.python.org/3/library/multiprocessing.html#contexts-and-start-methods. + multiprocessing.set_start_method("spawn") + + test, inchi_lib_path, dataset_config_path = get_config_args() + # https://docs.python.org/3/library/importlib.html#importing-a-source-file-directly + sys.path.append(str(Path(dataset_config_path).parent)) + data_config = importlib.import_module(str(Path(dataset_config_path).stem)) + + main(test, inchi_lib_path, data_config.config) diff --git a/INCHI-1-TEST/tests/test_library/inchi_tests/utils.py b/INCHI-1-TEST/tests/test_library/inchi_tests/utils.py index 1edff84c..6de2671b 100644 --- a/INCHI-1-TEST/tests/test_library/inchi_tests/utils.py +++ b/INCHI-1-TEST/tests/test_library/inchi_tests/utils.py @@ -1,5 +1,6 @@ import argparse from datetime import datetime +from pathlib import Path def get_current_time() -> str: @@ -14,22 +15,38 @@ def get_molfile_id_pubchem(molfile: str) -> str: return molfile.split()[0].strip() -def get_config_args() -> tuple[str, str]: +class PathValidator(argparse.Action): + def __call__(self, parser, namespace, values, option_string=None): + if not Path(values).is_file(): + parser.error(f"{option_string}: '{values}' is not a valid path.") + setattr(namespace, self.dest, values) + + +def get_config_args() -> tuple[str, str, str]: parser = argparse.ArgumentParser( - description="Choose a test and dataset.", + description="Choose a test, InChI library, and dataset.", + ) + parser.add_argument( + "--test", + type=str, + required=True, + choices=["regression", "regression-reference", "invariance"], + help="Specify the kind of test to run.", ) parser.add_argument( - "--test-config", + "--lib-path", type=str, required=True, - help="Specify the path to a test configuration file.", + action=PathValidator, + help="Specify the path to the InChI library.", ) parser.add_argument( "--data-config", type=str, required=True, + action=PathValidator, help="Specify the path to a dataset configuration file.", ) args = parser.parse_args() - return (args.test_config, args.data_config) + return (args.test, args.lib_path, args.data_config) diff --git a/INCHI-1-TEST/tests/test_library/test_multithreading.py b/INCHI-1-TEST/tests/test_library/test_multithreading.py index e4919417..0c96ded7 100644 --- a/INCHI-1-TEST/tests/test_library/test_multithreading.py +++ b/INCHI-1-TEST/tests/test_library/test_multithreading.py @@ -14,8 +14,10 @@ SDF_PATH = Path("INCHI-1-TEST/tests/test_library/data/ci/inchi.sdf.gz") -INCHI_LIB_PATH = Path("CMake_build/full_build/INCHI-1-SRC/INCHI_API/libinchi/src/lib/libinchi.so") -INCHI_LIB = ctypes.CDLL(str(INCHI_LIB_PATH)) +INCHI_LIB_PATH = ( + "CMake_build/full_build/INCHI-1-SRC/INCHI_API/libinchi/src/lib/libinchi.so" +) +INCHI_LIB = ctypes.CDLL(INCHI_LIB_PATH) class ConsumerThread(threading.Thread): @@ -34,7 +36,6 @@ def run(self): if __name__ == "__main__": - threads = [ ConsumerThread(INCHI_LIB, molfile) for molfile in read_records_from_gzipped_sdf(SDF_PATH) diff --git a/README.md b/README.md index a04a43ec..8b5fbb0d 100644 --- a/README.md +++ b/README.md @@ -89,10 +89,6 @@ That is, your comments will automatically be rendered to HTML and served as onli ## Contents of this repository -### INCHI-1-BIN - -The [INCHI-1-BIN](https://github.com/IUPAC-InChI/InChI/tree/main/INCHI-1-BIN) subfolder contains binaries of the command line `InChI` executable (`inchi-1`) and the `InChI API` library (`libinchi`). - ### INCHI-1-DOC The [INCHI-1-DOC](https://github.com/IUPAC-InChI/InChI/tree/main/INCHI-1-DOC) subfolder contains documentation related to the InChI Software. @@ -107,126 +103,18 @@ related projects/makefiles. The [INCHI-1-TEST](https://github.com/IUPAC-InChI/InChI/tree/main/INCHI-1-TEST) subfolder contains the test scripts and resources. -## Using precompiled binaries/libraries - -_64-bit_ and _32-bit_ precompiled binaries/libraries (i.e. executable, `.dll/.so/.dylib` and ELF files) are located in the following folders: +## Using compiled binaries/libraries - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Microsoft Windows
- Files (given in compressed .zip format) - - Location(s) - - Compiler -
- inchi-1.exe - - 64-bit: INCHI-1-BIN/windows/64bit - - Microsoft Visual Studio C++ (MSVC) -
- 32-bit: INCHI-1-BIN/windows/32bit - - MinGW-w64/Clang(1) -
- libinchi.dll
+ corresponding inchi_main.exe -
- 64-bit: INCHI-1-BIN/windows/64bit/dll - - Microsoft Visual Studio C++ (MSVC) -
- 32-bit: INCHI-1-BIN/windows/32bit/dll - - MinGW-w64/Clang(1) -
-

Table pcb01. Location of precompiled binaries/libraries for Microsoft Windows platforms.

- - - - - - - - - - - - - - - - - - - - - - - - - - - -
UNIX-based OSs (except Apple macOS)
- Files (given in compressed .zip format) - - Location(s) - - Compiler -
- inchi-1 (ELF file) - - 64-bit: INCHI-1-BIN/linux/64bit - - GCC -
- 32-bit: INCHI-1-BIN/linux/32bit - - Clang/LLVM(2) -
- libinchi.so/libinchi.dylib
+ corresponding inchi_main (ELF file) -
- 64-bit: INCHI-1-BIN/linux/64bit/so - - GCC -
- 32-bit: INCHI-1-BIN/linux/32bit/so - - Clang/LLVM(2) -
-

Table pcb02. Location of precompiled binaries/libraries for Linux/Apple macOS platforms.

- -(1) IMPORTANT NOTE: Since 32-bit binaries for Microsoft Windows operating system have been compiled using MinGW-w64, it has been reported that in certain environments a dynamic link library libgcc_s_dw2-1.dll has to be included in the same folder with the executables. Therefore, libgcc_s_dw2-1.dll has been added to INCHI-1-BIN/windows/32bit and INCHI-1-BIN/windows/32bit/dll folders (we would like to thank nbehrnd for his assistance with this matter). +You can download compiled artifacts from . +The archive `release_artifacts.zip` contains 64-bit artifacts for Windows, Linux, and macOS. +The artifact archive of each of those three platforms includes the following: -(2) In order to make makefile32s more consistent on all operating systems (see preceding note (1)), and for easier change of the default compiler, the default compiler on 32-bit UNIX-based OSs has been set to Clang/LLVM. +- InChI executable `inchi-1` +- InChI library `libinchi` with corresponding `inchi_main` program -Precompiled binaries for Apple macOS (i.e. `.app` executables and `.dylib` libraries) will be provided soon. Until then, please note that `InChI` can now be [compiled from source](#building-from-source) on Apple macOS using native/default `Clang` or `GCC` (if installed). +We're compiling these artifacts with GitHub Actions. +If you're interested in details about the platforms and compilers, have a look at the following [configuration](.github/workflows/release.yml), +as well as the files in the `cmake_configurations.zip` archive, which is included for each platform. ## Building from source @@ -460,7 +348,7 @@ The use of bounds checking functions in `InChI` can be enabled/disabled in `bcf_ #### Intel oneAPI Threading Building Blocks (oneTBB) -If you wish to use [Intel oneAPI Threading Building Blocks (oneTBB)](https://github.com/oneapi-src/oneTBB), please follow the instructions given in header files `mode.h` and `tbbmalloc_proxy.h`. Please note that the [pre-compiled binaries](#using-precompiled-binaries) _do not_ use `oneTBB`. +If you wish to use [Intel oneAPI Threading Building Blocks (oneTBB)](https://github.com/oneapi-src/oneTBB), please follow the instructions given in header files `mode.h` and `tbbmalloc_proxy.h`. Please note that the [compiled binaries](#using-compiled-binaries) _do not_ use `oneTBB`. ## Experimental features under development