Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Piggyback migrator for boost unification #1668

Merged
merged 8 commits into from
Sep 28, 2023
Merged

Conversation

h-vetinari
Copy link
Contributor

@h-vetinari h-vetinari commented May 5, 2023

This is a draft the implenentation for conda-forge/boost-feedstock#164

TL;DR

The main rule is:

  • if boost-cpp is only a host dep, replace it with libboost-headers (that doesn't have nor need a run-export)
  • if boost-cpp is also a run dep, remove it there and turn the host dep into libboost-devel (which has a run-export)

Additionally, boost is renamed to libboost-python-devel.

Implementation

I tried to base myself on #1602, but found that I needed some more control, especially for multi-output recipes. Since everything is already parsed and re-parsed many times, I went with a dead-simple solution that avoids having to identify exactly where in the meta.yaml a given requirement comes from, but have a broad section (based on the outputs that we know) in which to do replacements. It's possible that this already exists (or should exist?) in the utils here...?

The implementation is already pretty involved due to the fact that while operating on the unstructured strings, it's hard to tell what's a host or a run dependence, and we have to fall back to some assumptions involving how many times we want to replace or discard something. This gets more complicated by the occurrence of our key strings in build dependencies or comments. Of course, there are always things that are going to break the logic here, but I think it should hopefully handle 90+% of feedstocks correctly, and I think there are diminishing returns for upping the complexity of the implementation further.

Tests

I added a bunch of tests for feedstocks that showed up when searching for boost-cpp or boost, and I'm quite happy that even some of the trickier setups (pins, selectors, etc.) are handled correctly.

These were hard to write (because the machinery in play is very hard to understand IMO), so happy to improve. I ended up replacing the source sections of all sample recipes with scipy, because the version migrator (that's necessary to test the piggybacking, because we cannot test an actual pin migration AFAICT) would otherwise choke for reasons that aren't clear to me. Aside from that (and light editing that the migrator insists on, like removing quotes or changing selector spacing), the recipes are as they are on their current feedstocks.

I kept the tests in separate commits, because they're hard to read in the GH UI. For the benefit of the reader, here is the diff between the before/after file:

Single output; only host-dependence on boost-cpp

git diff HEAD:tests/test_yaml/libboost_gudhi_before_meta.yaml HEAD:tests/test_yaml/libboost_gudhi_after_meta.yaml
--- a/tests/test_yaml/libboost_gudhi_before_meta.yaml
+++ b/tests/test_yaml/libboost_gudhi_after_meta.yaml
@@ -1,4 +1,4 @@
-{% set version = "1.9.0" %}
+{% set version = "1.10.0" %}

 package:
   name: gudhi
@@ -7,12 +7,12 @@ package:
 source:
   # fake source url to get version migrator to pass
   url: https://github.com/scipy/scipy/archive/refs/tags/v{{ version }}.tar.gz
-  sha256: b6d893dc7dcd4138b9e9df59a13c59695e50e80dc5c2cacee0674670693951a1
+  sha256: 3f9e587a96844a9b4ee7f998cfe4dc3964dc95c4ca94d7de6a77bffb99f873da
   # git_url: https://github.com/GUDHI/gudhi-devel.git
   # git_rev: tags/gudhi-release-{{ version }}

 build:
-  number: 5
+  number: 0

 requirements:
   build:
@@ -33,7 +33,7 @@ requirements:
     - cython
     - pybind11
     - numpy
-    - boost-cpp
+    - libboost-headers
     - eigen
     - cgal-cpp >=5.5
   run:

Single output; host- & run-dependence on boost-cpp

git diff HEAD:tests/test_yaml/libboost_carve_before_meta.yaml HEAD:tests/test_yaml/libboost_carve_after_meta.yaml
--- a/tests/test_yaml/libboost_carve_before_meta.yaml
+++ b/tests/test_yaml/libboost_carve_after_meta.yaml
@@ -1,5 +1,5 @@
 {% set name = "carve" %}
-{% set version = "1.9.0" %}
+{% set version = "1.10.0" %}

 package:
   name: {{ name|lower }}
@@ -8,12 +8,12 @@ package:
 source:
   # fake source url to get version migrator to pass
   url: https://github.com/scipy/scipy/archive/refs/tags/v{{ version }}.tar.gz
-  sha256: b6d893dc7dcd4138b9e9df59a13c59695e50e80dc5c2cacee0674670693951a1
+  sha256: 3f9e587a96844a9b4ee7f998cfe4dc3964dc95c4ca94d7de6a77bffb99f873da
   # url: https://github.com/ngodber/carve/archive/v{{ version }}.tar.gz
   # sha256: 20481918af488fc92694bf1d5bdd6351ad73a0b64fbe4373e1f829a7b0eeff63

 build:
-  number: 1
+  number: 0
   run_exports:
     - {{ pin_subpackage("carve", max_pin="x.x") }}

@@ -24,9 +24,8 @@ requirements:
     - {{ compiler('c') }}
     - {{ compiler('cxx') }}
   host:
-    - boost-cpp
+    - libboost-devel
   run:
-    - boost-cpp

 test:
   commands:

Multiple outputs; tricky because appearance in comment messes up naïve counting

git diff HEAD:tests/test_yaml/libboost_fenics_before_meta.yaml HEAD:tests/test_yaml/libboost_fenics_after_meta.yaml

I consider the fact that the patch name gets spuriously renamed to be acceptable.

--- a/tests/test_yaml/libboost_fenics_before_meta.yaml
+++ b/tests/test_yaml/libboost_fenics_after_meta.yaml
@@ -1,4 +1,4 @@
-{% set version = "1.9.0" %}
+{% set version = "1.10.0" %}

 package:
   name: fenics-pkgs
@@ -7,7 +7,7 @@ package:
 source:
   # fake source url to get version migrator to pass
   - url: https://github.com/scipy/scipy/archive/refs/tags/v{{ version }}.tar.gz
-    sha256: b6d893dc7dcd4138b9e9df59a13c59695e50e80dc5c2cacee0674670693951a1
+    sha256: 3f9e587a96844a9b4ee7f998cfe4dc3964dc95c4ca94d7de6a77bffb99f873da
   # - url: https://bitbucket.org/fenics-project/dijitso/downloads/dijitso-{{ version }}.tar.gz
   #   sha256: eaa45eec4457f3f865d72a926b7cba86df089410e78de04cd89b15bb405e8fd9
   #   folder: dijitso
@@ -26,24 +26,24 @@ source:
   #   sha256: 61abdcdb13684ba2a3ba4afb7ea6c7907aa0896a46439d3af7e8848483d4392f
   #   folder: dolfin
   #   patches:
-  #     - boost.patch
+  #     - libboost-devel-python.patch
   #     - linuxboost.patch  # [linux]
   #     - find-petsc-slepc.patch
   #     - hdf5-1.12.patch
   #     - fix-xdmf.patch

 build:
-  number: 35
+  number: 0
   skip: true  # [win]

-# NOTE: Top-level environment with boost-cpp is only to separate the build for
+# NOTE: Top-level environment with libboost-devel is only to separate the build for
 #       multiple boost versions into different CI jobs.
 # TODO: Needs investigation why "separate the two boost builds more strictly"
 #       would be necessary. Ref:
 #       https://github.com/conda-forge/mshr-feedstock/pull/23#issuecomment-749520383
 requirements:
   host:
-    - boost-cpp
+    - libboost-devel
     # need to split the build matrix on mpi provider
     - {{ mpi }}

@@ -144,7 +144,7 @@ outputs:
       host:
         - libblas
         - libcblas
-        - boost-cpp
+        - libboost-devel
         - cmake >=3.9
         - make
         - eigen
@@ -174,7 +174,6 @@ outputs:
         - suitesparse
         - zlib
         - fenics-ffc =={{ version }}
-        - boost-cpp
     test:
       commands:
         - test -f ${PREFIX}/lib/libdolfin${SHLIB_EXT}
@@ -195,7 +194,7 @@ outputs:
       host:
         - libblas
         - libcblas
-        - boost-cpp
+        - libboost-devel
         - python
         - pip
         - cmake >=3.9
@@ -221,7 +220,6 @@ outputs:
       run:
         - {{ compiler('cxx') }}  # [linux]
         - python
-        - boost-cpp
         - setuptools
         - {{ mpi }}
         - mpi4py

Multiple outputs; tricky due to selectors, {{ }} pins & pin_compatible

git diff HEAD:tests/test_yaml/libboost_poppler_before_meta.yaml HEAD:tests/test_yaml/libboost_poppler_after_meta.yaml
--- a/tests/test_yaml/libboost_poppler_before_meta.yaml
+++ b/tests/test_yaml/libboost_poppler_after_meta.yaml
@@ -1,4 +1,4 @@
-{% set version = "1.9.0" %}
+{% set version = "1.10.0" %}
 {% set posix = 'm2-' if win else '' %}
 {% set native = 'm2w64-' if win else '' %}
 {% set prefix = 'Library/' if win else '' %}
@@ -11,7 +11,7 @@ source:
   # fake source url to get version migrator to pass
   url: https://github.com/scipy/scipy/archive/refs/tags/v{{ version }}.tar.gz
   # url: https://poppler.freedesktop.org/poppler-{{ version }}.tar.xz
-  sha256: b6d893dc7dcd4138b9e9df59a13c59695e50e80dc5c2cacee0674670693951a1
+  sha256: 3f9e587a96844a9b4ee7f998cfe4dc3964dc95c4ca94d7de6a77bffb99f873da
   patches:
     - exportsymbols.patch  # [win]
     - windows-data.patch  # [win]
@@ -21,7 +21,7 @@ source:
     - includesystembeforejpeg.patch  # [win]

 build:
-  number: 1
+  number: 0
   detect_binary_files_with_prefix: true

 requirements:
@@ -45,7 +45,7 @@ requirements:
     - {{ posix }}patch
     - perl 5
     - gobject-introspection 1.*  # [not win]
-    - boost-cpp {{ boost_cpp }}  # [build_platform != target_platform]
+    - libboost-devel  # [build_platform != target_platform]
     - cairo       # [build_platform != target_platform]
     - curl        # [build_platform != target_platform]
     - fontconfig  # [build_platform != target_platform]
@@ -62,7 +62,7 @@ requirements:
     - openjpeg    # [build_platform != target_platform]
     - zlib        # [build_platform != target_platform]
   host:
-    - boost-cpp
+    - libboost-devel
     - cairo
     - curl
     - fontconfig
@@ -105,7 +105,7 @@ outputs:
         - {{ posix }}patch
         - perl 5
         - gobject-introspection 1.*  # [not win]
-        - boost-cpp {{ boost_cpp }}  # [build_platform != target_platform]
+        - libboost-devel  # [build_platform != target_platform]
         - cairo       # [build_platform != target_platform]
         - curl        # [build_platform != target_platform]
         - fontconfig  # [build_platform != target_platform]
@@ -122,7 +122,7 @@ outputs:
         - openjpeg    # [build_platform != target_platform]
         - zlib        # [build_platform != target_platform]
       host:
-        - boost-cpp {{ boost_cpp }}
+        - libboost-devel
         - cairo
         - curl
         - fontconfig
@@ -139,7 +139,6 @@ outputs:
         - openjpeg
         - zlib
       run:
-        - {{ pin_compatible('boost-cpp') }}
         - poppler-data
     test:
       commands:
@@ -173,7 +172,7 @@ outputs:
         - {{ posix }}patch
         - perl 5
         - gobject-introspection 1.*  # [not win]
-        - boost-cpp {{ boost_cpp }}  # [build_platform != target_platform]
+        - libboost-devel  # [build_platform != target_platform]
         - cairo       # [build_platform != target_platform]
         - curl        # [build_platform != target_platform]
         - fontconfig  # [build_platform != target_platform]
@@ -190,7 +189,7 @@ outputs:
         - openjpeg    # [build_platform != target_platform]
         - zlib        # [build_platform != target_platform]
       host:
-        - boost-cpp {{ boost_cpp }}
+        - libboost-headers
         - cairo
         - curl
         - fontconfig

Multiple outputs; tricky due to duplicate host entries & version pins

git diff HEAD:tests/test_yaml/libboost_scipopt_before_meta.yaml HEAD:tests/test_yaml/libboost_scipopt_after_meta.yaml
--- a/tests/test_yaml/libboost_scipopt_before_meta.yaml
+++ b/tests/test_yaml/libboost_scipopt_after_meta.yaml
@@ -1,5 +1,5 @@
 # TODO check these versions have not changed
-{% set version = "1.9.0" %}
+{% set version = "1.10.0" %}
 {% set papilo_version = "2.1.2" %}
 {% set soplex_version = "6.0.3" %}
 {% set gcg_version = "3.5.3" %}
@@ -17,13 +17,13 @@ package:
 source:
   # fake source url to get version migrator to pass
   - url: https://github.com/scipy/scipy/archive/refs/tags/v{{ version }}.tar.gz
-    sha256: b6d893dc7dcd4138b9e9df59a13c59695e50e80dc5c2cacee0674670693951a1
+    sha256: 3f9e587a96844a9b4ee7f998cfe4dc3964dc95c4ca94d7de6a77bffb99f873da
 #   - url: https://scipopt.org/download/release/scipoptsuite-{{ scip_version }}.tgz
 #     sha256: 5ad50eb42254c825d96f5747d8f3568dcbff0284dfbd1a727910c5a7c2899091
 #     folder: scipoptsuite

 build:
-  number: 1
+  number: 0

 requirements:
   build:
@@ -38,8 +38,7 @@ requirements:
     - zlib
     - ipopt
     - cppad
-    - boost-cpp ==1.72.0  # [win]
-    - boost-cpp       # [unix]
+    - libboost-devel
     - gmp             # [unix]
     - cliquer         # [unix]
     - bison           # [unix]
@@ -57,8 +56,8 @@ outputs:
       host:
         - zlib
         - gmp             # [unix]
-        - boost-cpp ==1.72.0  # [win]
-        - boost-cpp       # [unix]
+        - libboost-headers  # [win]
+        - libboost-headers       # [unix]
         - libblas
       run:
         - tbb-devel
@@ -128,16 +127,13 @@ outputs:
       host:
         - zlib
         - gmp             # [unix]
-        - boost-cpp ==1.72.0  # [win]
-        - boost-cpp       # [unix]
+        - libboost-devel
         # Papilo statically linked but needs direct dependency from used shared libs.
         - tbb-devel
         - libblas
       run:
         # libboost_program_options.so needed by bin/soplex.
         # boost does not set run_exports so it is needed in run requirements.
-        - boost-cpp ==1.72.0  # [win]
-        - boost-cpp       # [unix]
         - zlib
         - {{ pin_subpackage('papilo', exact=True) }}
     files:

Python output (boost -> libboost-python-devel): simple case

git diff HEAD:tests/test_yaml/libboost_rdkit_before_meta.yaml HEAD:tests/test_yaml/libboost_rdkit_after_meta.yaml
--- a/tests/test_yaml/libboost_rdkit_before_meta.yaml
+++ b/tests/test_yaml/libboost_rdkit_after_meta.yaml
@@ -1,5 +1,5 @@
 {% set name = "rdkit" %}
-{% set version = "1.9.0" %}
+{% set version = "1.10.0" %}
 {% set filename = "Release_%s.tar.gz" % version.replace(".", "_") %}

 package:
@@ -9,7 +9,7 @@ package:
 source:
   # fake source url to get version migrator to pass
   url: https://github.com/scipy/scipy/archive/refs/tags/v{{ version }}.tar.gz
-  sha256: b6d893dc7dcd4138b9e9df59a13c59695e50e80dc5c2cacee0674670693951a1
+  sha256: 3f9e587a96844a9b4ee7f998cfe4dc3964dc95c4ca94d7de6a77bffb99f873da
   # fn: {{ filename }}
   # url: https://github.com/rdkit/rdkit/archive/{{ filename }}
   # sha256: db346afbd0ba52c843926a2a62f8a38c7b774ffab37eaf382d789a824f21996c
@@ -31,7 +31,7 @@ requirements:
     - make  # [unix]
     - pkg-config
   host:
-    - boost
+    - libboost-python-devel
     - cairo
     - eigen
     - freetype
@@ -40,7 +40,7 @@ requirements:
     - pillow
     - pandas
   run:
-    - boost
+    - libboost-python-devel
     - cairo
     - python
     - pillow

Python output (boost -> libboost-python-devel): interaction with boost-cpp

git diff HEAD:tests/test_yaml/libboost_cctx_before_meta.yaml HEAD:tests/test_yaml/libboost_cctx_after_meta.yaml
--- a/tests/test_yaml/libboost_cctx_before_meta.yaml
+++ b/tests/test_yaml/libboost_cctx_after_meta.yaml
@@ -1,4 +1,4 @@
-{% set version = "1.9.0" %}
+{% set version = "1.10.0" %}

 package:
   name: cctbx-base
@@ -7,7 +7,7 @@ package:
 source:
   # fake source url to get version migrator to pass
   url: https://github.com/scipy/scipy/archive/refs/tags/v{{ version }}.tar.gz
-  sha256: b6d893dc7dcd4138b9e9df59a13c59695e50e80dc5c2cacee0674670693951a1
+  sha256: 3f9e587a96844a9b4ee7f998cfe4dc3964dc95c4ca94d7de6a77bffb99f873da
   # url: https://github.com/cctbx/cctbx_project/releases/download/v{{ version }}/cctbx-{{ version }}.tar.gz
   # sha256: ad46f373875e1893f5fa87267b5445b97d660d0d05887e41d38d1fdd0e46724b
   patches:
@@ -36,8 +36,8 @@ requirements:
     - {{ cdt('libxxf86vm') }}  # [linux]
     - {{ cdt('libxext') }}     # [linux]
   host:
-    - boost
-    - boost-cpp
+    - libboost-python-devel
+    - libboost-devel
     - eigen
     - future
     - libglu  # [linux]
@@ -55,8 +55,6 @@ outputs:
     requirements:
       run:
         - biopython
-        - {{ pin_compatible('boost') }}
-        - boost-cpp
         - future
         - {{ pin_compatible('libglu') }}  # [linux]
         - libsvm

@h-vetinari h-vetinari force-pushed the boost branch 2 times, most recently from f62bc72 to 6655299 Compare May 5, 2023 05:16
@codecov
Copy link

codecov bot commented May 5, 2023

Codecov Report

Attention: 4 lines in your changes are missing coverage. Please review.

Comparison is base (5e22e28) 68.18% compared to head (3d81ed1) 68.65%.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1668      +/-   ##
==========================================
+ Coverage   68.18%   68.65%   +0.46%     
==========================================
  Files          91       93       +2     
  Lines        8701     8789      +88     
==========================================
+ Hits         5933     6034     +101     
+ Misses       2768     2755      -13     
Files Coverage Δ
conda_forge_tick/migrators/__init__.py 100.00% <100.00%> (ø)
tests/test_libboost.py 100.00% <100.00%> (ø)
conda_forge_tick/auto_tick.py 0.00% <0.00%> (ø)
conda_forge_tick/migrators/libboost.py 97.67% <97.67%> (ø)

... and 2 files with indirect coverage changes

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@h-vetinari
Copy link
Contributor Author

@beckermr, any thoughts here? In case this needs a large overhaul, I'd like to tackle it. But if it look +/- alright, I'm happy to let it lie until we finish conda-forge/boost-feedstock#164

@beckermr
Copy link
Contributor

beckermr commented May 7, 2023

This PR is pretty hefty so I have not had a chance to look in detail. The test suite looks amazing and so I'm very happy to trust you on the details. Let's let this one wait until things are ready to move ahead.

@h-vetinari
Copy link
Contributor Author

This PR is pretty hefty so I have not had a chance to look in detail.

It might be scary-looking, but in terms of LoC, it's <7% implementation, <2% tests & >90% test cases. That's why I split it into separate commits. ;-)

The test suite looks amazing and so I'm very happy to trust you on the details.

Happy to hear it, thanks for taking a look!

Let's let this one wait until things are ready to move ahead.

SGTM

@h-vetinari h-vetinari changed the title WIP: Piggyback migrator for boost unification Piggyback migrator for boost unification Sep 21, 2023
@h-vetinari
Copy link
Contributor Author

This has now been updated to the new naming adopted in conda-forge/boost-feedstock#164

Copy link
Contributor

@beckermr beckermr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shall I merge or would you like commit access so you can merge when ready? Once we merge it goes live so all of the packages it depends on need to exist.

@h-vetinari
Copy link
Contributor Author

Shall I merge or would you like commit access so you can merge when ready?

I don't mind pinging you when I'm ready, but if you're happy to share commit access, sure.

Once we merge it goes live so all of the packages it depends on need to exist.

I asked for any last comments on conda-forge/boost-feedstock#164, but clearly that PR needs to be merged first. However, w.r.t. the migration, we're now exactly in the situation we wanted to avoid - coinciding with the 3.12 migration. I guess we could still squeak in boost before 3.12 kicks off in earnest?

Talking about what we need for this to be merged; I also think we need to merge a corresponding pinning PR (the base of the piggyback)? At least for #1602 (which I was basing myself off of) there was a special migrator; I can prepare that once conda-forge/boost-feedstock#164 is merged...

@beckermr
Copy link
Contributor

Ah right. I'll add you here in a bit. You should go ahead with what you need.

@h-vetinari
Copy link
Contributor Author

Still trying to follow #1602 as closely as I could1, I've now paired this with conda-forge/conda-forge-pinning-feedstock#4961.

Footnotes

  1. note that conda_forge_tick/audit.py doesn't exist anymore...

@h-vetinari h-vetinari requested a review from isuruf September 28, 2023 12:26
@h-vetinari
Copy link
Contributor Author

Alright, here goes nothing! 😅

@h-vetinari h-vetinari merged commit b54a19f into regro:master Sep 28, 2023
5 checks passed
@h-vetinari h-vetinari deleted the boost branch September 28, 2023 23:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants