├── .gitignore ├── .gitmodules ├── .pyup.yml ├── .travis.yml ├── CHANGELOG.rst ├── CMakeLists.txt ├── README.rst ├── RELEASE.rst ├── cmake ├── catkin-pip-base.req ├── catkin-pip-fixups.req ├── catkin-pip-package.cmake.in ├── catkin-pip-prefix.cmake.in ├── catkin-pip-requirements.cmake.in ├── catkin-pip-runcmd.cmake.in ├── catkin-pip.cmake.in ├── env-hooks │ └── 42.site_packages.sh.develspace.in ├── nosetests.cmake.in ├── pytest.cmake.in ├── scripts │ └── path_prepend.sh └── templates │ └── python_setuptools_install.sh.in ├── doc ├── catkin_package.rst ├── catkin_pip_notes.rst ├── catkin_pip_overview.rst ├── catkin_pip_package.rst ├── changelog_link.rst ├── conf.py ├── doc-requirements.txt ├── from_catkin_to_python.rst ├── from_python_to_catkin.rst ├── index.rst ├── pip_package.rst ├── pycharm_setup.rst ├── readme_link.rst └── weblinks.rst ├── package.xml ├── rosdoc.yaml ├── test ├── CMakeLists.txt ├── README.md ├── catkin_pip ├── catkin_pip_pytest │ ├── __init__.py │ ├── conftest.py │ ├── test_easyinstallpth.py │ ├── test_import.py │ ├── test_path.py │ ├── test_site.py │ ├── test_syspath.py │ └── test_syspath_pyros.py ├── distutils-setup │ ├── .gitignore │ ├── CMakeLists.txt │ ├── catkin_pip │ ├── distutils_setup │ │ ├── dstest │ │ │ ├── __init__.py │ │ │ └── test │ │ │ │ ├── __init__.py │ │ │ │ └── test_install.py │ │ ├── setup.py │ │ └── test │ │ │ └── test_dstest.py │ ├── extra_installs │ │ ├── bin.txt │ │ ├── etc.txt │ │ ├── include.txt │ │ ├── lib.txt │ │ ├── python.txt │ │ └── share.txt │ └── package.xml ├── pipproject │ ├── .gitignore │ ├── CMakeLists.txt │ ├── catkin_pip │ └── package.xml ├── pylibrary │ ├── .gitignore │ ├── CMakeLists.txt │ ├── catkin_pip │ └── package.xml ├── pypackage-minimal │ ├── .gitignore │ ├── CMakeLists.txt │ ├── catkin_pip │ └── package.xml ├── pypackage │ ├── .gitignore │ ├── CMakeLists.txt │ ├── catkin_pip │ └── package.xml ├── setuptools-setup │ ├── .gitignore │ ├── CMakeLists.txt │ ├── catkin_pip │ ├── extra_installs │ │ ├── bin.txt │ │ ├── etc.txt │ │ ├── include.txt │ │ ├── lib.txt │ │ ├── python.txt │ │ └── share.txt │ ├── package.xml │ └── setuptools_setup │ │ ├── setup.py │ │ ├── sstest │ │ ├── __init__.py │ │ └── test │ │ │ ├── __init__.py │ │ │ └── test_install.py │ │ └── test │ │ └── test_sstest.py └── test_requirements.txt └── travis_checks.bash /.gitignore: -------------------------------------------------------------------------------- 1 | doc/html 2 | build 3 | .cache 4 | test/.cache 5 | testbuild 6 | test/pipproject/mypippkg 7 | .idea 8 | *.pyc -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyros-dev/catkin_pip/440004356798491d347cc81b809b22968be8741c/.gitmodules -------------------------------------------------------------------------------- /.pyup.yml: -------------------------------------------------------------------------------- 1 | update: all 2 | search: False 3 | 4 | requirements: 5 | - cmake/catkin-pip-base.req 6 | - cmake/catkin-pip-fixups.req 7 | - test/test_requirements.txt 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | language: generic 3 | services: 4 | - docker 5 | 6 | branches: 7 | except: 8 | - gh-pages 9 | 10 | env: 11 | global: 12 | - CONTAINER_NAME=catkin_pip_docker 13 | # This will check any ROS distro supported on this OS 14 | # checking devel and install separately so that they don't influence each other (dependencies, path, env, etc.) 15 | matrix: 16 | - ROS_DISTRO=indigo ROS_FLOW=devel 17 | - ROS_DISTRO=indigo ROS_FLOW=install 18 | - ROS_DISTRO=jade ROS_FLOW=devel 19 | - ROS_DISTRO=jade ROS_FLOW=install 20 | - ROS_DISTRO=kinetic ROS_FLOW=devel 21 | - ROS_DISTRO=kinetic ROS_FLOW=install 22 | - ROS_DISTRO=lunar ROS_FLOW=devel 23 | - ROS_DISTRO=lunar ROS_FLOW=install 24 | # TODO : test all possible flows (installing deps on devel or not, etc.) 25 | 26 | before_install: 27 | # Getting docker ros image 28 | - docker pull ros:${ROS_DISTRO}-ros-core 29 | # Running as daemon 30 | - docker run --name ${CONTAINER_NAME} -d -t ros:${ROS_DISTRO}-ros-core /bin/bash | tee container.id 31 | # Checking current container 32 | - docker ps -a 33 | - docker exec -ti ${CONTAINER_NAME} hostname 34 | - docker exec -ti ${CONTAINER_NAME} uname -a 35 | - docker exec -ti ${CONTAINER_NAME} cat /etc/lsb-release 36 | 37 | install: 38 | # refreshing packages 39 | - docker exec -ti ${CONTAINER_NAME} apt-get update 40 | # TMP Patch because rosdep doesnt declare a dependency to sudo yet (2016-08-25) and it doesnt come with xenial 41 | - docker exec -ti ${CONTAINER_NAME} apt-get install sudo -y 42 | - docker exec -ti ${CONTAINER_NAME} rosdep update 43 | # copying local clone to the running container (volume is currently broken) 44 | - docker cp . ${CONTAINER_NAME}:/git_clone 45 | # Installing package dependencies 46 | - docker exec -ti ${CONTAINER_NAME} rosdep install --default-yes --from-paths /git_clone --rosdistro $ROS_DISTRO 47 | 48 | # full ROS setup, build and test 49 | script: 50 | - CONTAINER_ID=$(cat container.id) 51 | - docker ps -a 52 | - docker exec -ti ${CONTAINER_NAME} /bin/bash -c "source /opt/ros/$ROS_DISTRO/setup.bash && rospack profile" 53 | # Passing env vars here since passing in docker run currently breaks (2016-08-25) 54 | - docker exec -ti ${CONTAINER_NAME} /bin/bash -c "export ROS_DISTRO=$ROS_DISTRO && export ROS_FLOW=$ROS_FLOW && /git_clone/travis_checks.bash" 55 | - docker stop "${CONTAINER_ID}" 56 | 57 | notifications: 58 | email: false 59 | 60 | -------------------------------------------------------------------------------- /CHANGELOG.rst: -------------------------------------------------------------------------------- 1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2 | Changelog for package catkin_pip 3 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 4 | 5 | 0.2.3 (2017-08-11) 6 | ------------------ 7 | * Merge pull request `#147 `_ from pyros-dev/lunar 8 | adding lunar 9 | * adding --ignore-src when calling rosdep on tests, 10 | to not attempt to download an old (or missing) version of catkin_pip. 11 | * adding lunar 12 | * Merge pull request `#144 `_ from pyros-dev/fix_destinations 13 | fixing catkin_destination not being called 14 | * tests are now using the new catkin_pip_target and calling catkin_package directly. 15 | * adding catkin_pip_target to API, to allow the user to call catkin_package how he wants. 16 | * splitting catkin_pip_package in function and macro to expose the catkin_destinations variables set in the scope. 17 | * adding install rules to verify catkin variables. 18 | * Merge pull request `#128 `_ from pyros-dev/pyup-update-pytest-3.0.6-to-3.1.3 19 | Update pytest to 3.1.3 20 | * Update pytest from 3.0.6 to 3.1.3 21 | * Contributors: AlexV, pyup-bot 22 | 23 | 0.2.2 (2017-05-30) 24 | ------------------ 25 | * Merge pull request `#123 `_ from yotabits/devel 26 | Added option NOSE_OPT to catkin_add_nosetests func 27 | * Added option NOSE_OPT to catkin_add_nosetests func 28 | In order to use some specific option for nosetests we now have a NOSE_OPT 29 | parameter that allow to use some customs options for launching nosetests 30 | The same has been done for pytests with the param PYTEST_OPT 31 | * Contributors: AlexV, Thomas 32 | 33 | 0.2.1 (2017-05-11) 34 | ------------------ 35 | * Merge pull request `#115 `_ from asmodehn/distutils 36 | Implementing distutils support 37 | * refining tests on install flow, to confirm which test framework is used. 38 | upgrading catkin package format to advised format 2. 39 | * fixes to support distutils as well as setuptools. 40 | * adding setuptools_setup test project and tests to validate package structure after installation. 41 | * adding test to make sure "make install" does not trigger errors. 42 | * adding a basic package to test distutils based setup.py 43 | * Contributors: AlexV, yotabits 44 | 45 | 0.2.0 (2017-03-17) 46 | ------------------ 47 | * removing dependency on daemontools (not available on fedora) 48 | * setlock -> flock 49 | * Merge pull request `#95 `_ from k-okada/install_data 50 | data should not install right under the CMAKE_INSTALL_PREFIX 51 | * fixing syntax for ros distro autodetection when building this package. 52 | * Merge pull request `#97 `_ from asmodehn/gopher-devel 53 | Preparing next release 0.2 54 | * install data 55 | * Contributors: AlexV, Kei Okada, alexv 56 | 57 | * Merge branch 'devel' into gopher-devel 58 | * now using catkin_pip_runcmd to retrieve cookiecutter package samples. 59 | * removing install envhook. seems to break things. 60 | we dont want the install envhook to be created for catkin_pip since the target build env does not exist. 61 | * Merge pull request `#61 `_ from asmodehn/refactor_envs 62 | Refactor envs 63 | * adding docs to make decision clear regarding catkin / pyros_setup behavior. 64 | * fixing up install devel command since we do not pass editable pkg path into pythonpath anymore. 65 | * Merge branch 'gopher-devel' into refactor_envs 66 | * Merge pull request `#76 `_ from asmodehn/easyinstall_fix 67 | Easyinstall fix 68 | * commenting install tests... we dont have any. 69 | * always adding the catkin_pip_env path to pythonpath to be able to find basic tools from the first time around. 70 | * envhooks now not adding to pythonpath from pth files. too confusing. 71 | envhooks now not adding non existent paths to pythonpath. maybe good idea to match site module behavior. 72 | fixing tests. 73 | * improved tests. added test for check with pyros_setup and interractive debugging 74 | * fixed broken tests. now needs pyros-setup to get .pth paths before workspaces. 75 | cosmetics. 76 | * improved tests and fix all. 77 | added actual test for pytest to pipproject. 78 | * cleaning up command args when running pip install --editable to clean python path and workaround pip bug... 79 | * replacing CI_ROS_DISTRO var by ROS_DISTRO, to have it set for calls to rosdep. 80 | * more exhaustive test for sys_path 81 | * commenting echoes from script since it cannot echo without breaking things anyway. 82 | * reviewing shell script to make them a tiny more robust... 83 | * removed useless bash envhook, fixed easy-install parse to include last line even if no empty line at end of file. 84 | * Merge pull request `#77 `_ from asmodehn/pyup-update-pytest-3.0.5-to-3.0.6 85 | Update pytest to 3.0.6 86 | * Merge pull request `#86 `_ from asmodehn/pyup-update-cookiecutter-1.5.0-to-1.5.1 87 | Update cookiecutter to 1.5.1 88 | * Update cookiecutter from 1.5.0 to 1.5.1 89 | * moved rosdep install out of catkin_pip, only used for tests. 90 | temporarily skipping broken test because of pip behavior... 91 | * improved concurrency handling for pip by using setlock from daemontools. 92 | improved status message output. 93 | * adding libssl-dev as dependency forpypackage 94 | * adding catkin_pip function to call rosdep install. attempting fix for pypackage tests. 95 | * adding libffi-dev as build_depend for python_boilerplate 96 | * API changed ! redesigned workflow by doing "pip install -e package" during make stage instead of configure. All tests passing. 97 | * Update pytest from 3.0.5 to 3.0.6 98 | * reverted to pip 8.1.2 99 | changes added in prevision of switching to pip 9.X when --ignore-installed working... 100 | * added comment about sourcing install/setup.bash 101 | * improved test cases to check the content of easy-install.pth 102 | * adding cookiecutter pypackage-minimal for tests 103 | * adding cookiecutter pypackage for tests 104 | * adding cookiecutter pylibrary for testing 105 | * adding result of investigation for unexpected dist-packages in sys.path tail... still WIP 106 | * now handling environment setup only via catkin_env from env-hooks. 107 | made pure sh envhook to allow implementing other shells. 108 | * WIP refactoring how we setup configure / build / devel/ install enironments 109 | * improved path_prepend shell script 110 | * Contributors: AlexV, alexv, pyup-bot 111 | 112 | * removing install envhook. seems to break things. 113 | we dont want the install envhook to be created for catkin_pip since the target build env does not exist. 114 | * Merge pull request `#61 `_ from asmodehn/refactor_envs 115 | Refactor envs 116 | * adding docs to make decision clear regarding catkin / pyros_setup behavior. 117 | * fixing up install devel command since we do not pass editable pkg path into pythonpath anymore. 118 | * Merge branch 'gopher-devel' into refactor_envs 119 | * Merge pull request `#76 `_ from asmodehn/easyinstall_fix 120 | Easyinstall fix 121 | * commenting install tests... we dont have any. 122 | * always adding the catkin_pip_env path to pythonpath to be able to find basic tools from the first time around. 123 | * envhooks now not adding to pythonpath from pth files. too confusing. 124 | envhooks now not adding non existent paths to pythonpath. maybe good idea to match site module behavior. 125 | fixing tests. 126 | * improved tests. added test for check with pyros_setup and interractive debugging 127 | * fixed broken tests. now needs pyros-setup to get .pth paths before workspaces. 128 | cosmetics. 129 | * improved tests and fix all. 130 | added actual test for pytest to pipproject. 131 | * cleaning up command args when running pip install --editable to clean python path and workaround pip bug... 132 | * replacing CI_ROS_DISTRO var by ROS_DISTRO, to have it set for calls to rosdep. 133 | * more exhaustive test for sys_path 134 | * commenting echoes from script since it cannot echo without breaking things anyway. 135 | * reviewing shell script to make them a tiny more robust... 136 | * removed useless bash envhook, fixed easy-install parse to include last line even if no empty line at end of file. 137 | * moved rosdep install out of catkin_pip, only used for tests. 138 | temporarily skipping broken test because of pip behavior... 139 | * improved concurrency handling for pip by using setlock from daemontools. 140 | improved status message output. 141 | * adding libssl-dev as dependency forpypackage 142 | * adding catkin_pip function to call rosdep install. attempting fix for pypackage tests. 143 | * adding libffi-dev as build_depend for python_boilerplate 144 | * API changed ! redesigned workflow by doing "pip install -e package" during make stage instead of configure. All tests passing. 145 | * reverted to pip 8.1.2 146 | changes added in prevision of switching to pip 9.X when --ignore-installed working... 147 | * added comment about sourcing install/setup.bash 148 | * improved test cases to check the content of easy-install.pth 149 | * adding cookiecutter pypackage-minimal for tests 150 | * adding cookiecutter pypackage for tests 151 | * adding cookiecutter pylibrary for testing 152 | * adding result of investigation for unexpected dist-packages in sys.path tail... still WIP 153 | * now handling environment setup only via catkin_env from env-hooks. 154 | made pure sh envhook to allow implementing other shells. 155 | * WIP refactoring how we setup configure / build / devel/ install enironments 156 | * improved path_prepend shell script 157 | * Contributors: AlexV, alexv 158 | 159 | 0.1.18 (2017-03-04) 160 | ------------------- 161 | * Pin pytest to latest version 3.0.5 162 | * Pin pytest-timeout to latest version 1.2.0 163 | * Pin nose to latest version 1.3.7 164 | * Pin pytest-cov to latest version 2.4.0 165 | * Pin cookiecutter to latest version 1.5.0 166 | * adding pyup checks for dependencies 167 | * Contributors: AlexV, alexv, pyup-bot 168 | 169 | 0.1.17 (2017-01-13) 170 | ------------------- 171 | * now always ignore-installed when installing requirements. 172 | * pinned pip to 8.1.2 because of https://github.com/asmodehn/catkin_pip/issues/58 173 | * Merge pull request `#57 `_ from asmodehn/devel 174 | upgrading gopher_devel 175 | * Merge pull request `#56 `_ from asmodehn/gopher-devel 176 | drop some echoing 177 | * drop some echoing 178 | * Contributors: AlexV, Daniel Stonier, alexv 179 | 180 | 0.1.16 (2016-09-05) 181 | ------------------- 182 | * now also checking for --system for pip > 6.0.0. 183 | * small improvements for travis checks 184 | * Contributors: AlexV, alexv 185 | 186 | 0.1.15 (2016-09-01) 187 | ------------------- 188 | * now transferring paths from pth in devel site-packages to pythonpath shell env, to handle egg-link and workspace overlaying together... 189 | * adding current devel space dist-packages via envhook to get it even if env not sourced... is it a good idea ? 190 | * officially not supporting broken old pip on EOL saucy. 191 | * Contributors: AlexV, alexv 192 | 193 | 0.1.14 (2016-08-30) 194 | ------------------- 195 | * Merge pull request `#44 `_ from asmodehn/pip_system 196 | Now checking for pip --system option before using. 197 | * Now checking for pip --system option before using. 198 | cleanup some cmake status messages. 199 | * improving pip detection 200 | * Contributors: AlexV, alexv 201 | 202 | 0.1.13 (2016-08-28) 203 | ------------------- 204 | * fixing install rule for moved script. 205 | * getting rid of rospack dependency. didnt always work. 206 | moved pythonpath_prepend shell script to use it via cmake variable. 207 | * now checking system pip version to choose command line arguments for setup 208 | * Contributors: AlexV 209 | 210 | 0.1.12 (2016-08-27) 211 | ------------------- 212 | * Merge pull request `#40 `_ from asmodehn/env_hooks 213 | Env hooks 214 | * Merge pull request `#39 `_ from asmodehn/include_seq 215 | preventing multiple includes, reviewing variable scope. 216 | * preventing multiple includes, reviewing variable scope. 217 | * Merge branch 'devel' of https://github.com/asmodehn/catkin_pip into env_hooks 218 | # Conflicts: 219 | # CMakeLists.txt 220 | # cmake/catkin-pip.cmake.in 221 | # cmake/env-hooks/42.site_packages.bash.develspace.in 222 | * Updated README 223 | * Merge pull request `#33 `_ from asmodehn/install_no_deps 224 | first implementation of --no-deps to no install a package dependencie… 225 | * Merge pull request `#35 `_ from asmodehn/kinetic-devel 226 | fixing pip upgrade for kinetic, based on ROS_DISTRO env var. 227 | * requirements now correctly loading catkin-pip build/catkin_pip_env. 228 | now avoiding to load catkin-pip-requirements by itself. 229 | * fixing check of envvar ROS_DISTRO from cmake configure to decide which pip command to run 230 | * fixing rospack call. passing travis matrix env vars via shell command since docker run vars break on exec call. 231 | * now passing travis matrix env vars to container. 232 | * adding apt-get update call. also install sudo as not installed by default on xenial and required by rosdep. 233 | cosmetics 234 | * using docker cp instead of volume to workaround docker/travis bug. 235 | * removing volume to $HOME in case it is the cause of docker breaks. 236 | * travis_checks script now change to its directory as first step. 237 | fixed some docker commands. 238 | * fixing ros image name, container_name. 239 | added rosdep comand to get dependencies. 240 | * changing travis to use docker to test multiple distro. 241 | * fixing pip upgrade for kinetic, based on ROS_DISTRO env var. 242 | * Restructured documentation 243 | * started new doc structure 244 | * documentation improvements 245 | * adding doc as reference for basic catkin build release flow 246 | * first implementation of --no-deps to no install a package dependencies via pip. helps confirm rosdep dependencies 247 | * now using simplified sh env_hook 248 | * Contributors: AlexV, alexv 249 | 250 | 0.1.11 (2016-08-11) 251 | ------------------- 252 | * added description of the catkin_pip build flow 253 | * we might not need the install envhook after all. 254 | correct setuptools is found via path in install script. 255 | correct tools for test or other should be found via path in generated scripts, and used via catkin/make commands. 256 | * added warning in pycharm setup doc. 257 | * added first draft of pycharm setup doc 258 | * improved workflow doc with pointer to example package repos. 259 | * adding documentation for 3 ros-python workflows enabled by catkin_pip 260 | * improving documentation 261 | * disabling tests check from travis on install since mypippkg doesnt have any yet. 262 | * fixing travis_checks to run our pytest version from catkin_pip_env 263 | * cleaning up doc, installing ros-base in travis install step. 264 | * adding specific script for travis checks. 265 | added basic doc structure. 266 | * new travis build flow to split devel and install flow and avoid one unwanted interferences. 267 | * Contributors: alexv 268 | 269 | 0.1.10 (2016-08-09) 270 | ------------------- 271 | * added rospack dependency 272 | * (Re)adding site-packages folder creation in devel workspace. 273 | * setup of catkin_pip environment also adds the workspace site-packages to the python path to get it ready for use, even if envhook was not used before. 274 | * Merge pull request `#28 `_ from asmodehn/separate_catkin_pip_env 275 | separating catkin_pip environment with workspace environment. 276 | * making sure env-hooks have all variables setup before adding. 277 | * separating catkin_pip environment with workspace environment. 278 | added envhook for loading caktin_pip env on installspace. 279 | removing install script for python on windows for now (outdated). 280 | * Contributors: AlexV, alexv 281 | 282 | 0.1.9 (2016-06-24) 283 | ------------------ 284 | * fixed site_packages env-hook. 285 | bash script seems to work fine after all, the problem was somewhere else. 286 | simplified the envhook flow between catkin, package, overlay. 287 | * changed site-packages env-hook to have .sh extension. 288 | moving prepend function into catkin-pip package itself. 289 | * Contributors: alexv 290 | 291 | 0.1.8 (2016-06-06) 292 | ------------------ 293 | * fix nose and pytest test runners to launch from pip latest install by catkin-pip. 294 | * fix PYTHONPATH manipulation to prepend a path. 295 | not adding /opt/ros/ to the path since original catkin will take care of that. 296 | * Contributors: AlexV 297 | 298 | 0.1.7 (2016-06-05) 299 | ------------------ 300 | * fixed site-packages env-hook to install with catkin-pip and not built project, and to be activated only in devel space. 301 | * Contributors: AlexV 302 | 303 | 0.1.6 (2016-06-05) 304 | ------------------ 305 | * improving python_install templates to match original version more... 306 | * improving python install script to pass only one --root option 307 | * Contributors: AlexV, alexv 308 | 309 | 0.1.5 (2016-06-03) 310 | ------------------ 311 | * removing subdir in cfg_extra because of https://github.com/ros/catkin/issues/805 312 | * Contributors: alexv 313 | 314 | 0.1.4 (2016-06-02) 315 | ------------------ 316 | * adding pytest as a test runner. 317 | now using our nose in nosetests (instead of sytem one) 318 | small fixes. 319 | * now travis building on jade as well 320 | * Contributors: AlexV, alexv 321 | 322 | 0.1.3 (2016-06-01) 323 | ------------------ 324 | * renaming catkin_pure_python to catkin_pip for clarity 325 | * Contributors: alexv 326 | 327 | 0.1.2 (2016-05-30) 328 | ------------------ 329 | * fixing python_setuptools_install templates location and permissions 330 | * Contributors: alexv 331 | 332 | 0.1.1 (2016-05-30) 333 | ------------------ 334 | * fixing catkin_pip_runcmd for package, hopefully. 335 | * Contributors: AlexV 336 | 337 | 0.1.0 (2016-05-29) 338 | ------------------ 339 | * separating catkin_pip_setup and catkin_package macros. 340 | * now ignoring installed pip packaging when fetching requirements for pipproject. 341 | * removing debug output for shell envhook 342 | * fixing install procedure to get same structure as the distutils version. 343 | * now catkin-pip package is using normal catkin_package(), and installs fine, although with setuptools, which might break packaging... 344 | * refactoring cmake include and configure. test project devel space ok. the rest is still broken... 345 | * small improvement to do less configuration 346 | * now using an envhook to modify pythonpath instead of hacking catkin's _setup_util.py 347 | * _setup_util.py hack now done in cmake binary dir instead of final workspace. 348 | * Contributors: AlexV, alexv 349 | 350 | 0.0.8 (2016-05-10) 351 | ------------------ 352 | * not writing cmake files into workspace anymore. instead in build directory of each package. 353 | * added doc about pip/ros dependency handling. 354 | * Contributors: alexv 355 | 356 | 0.0.7 (2016-05-09) 357 | ------------------ 358 | * removing --ignore-installed for editable package, to allow requirements to satisfy setup.py dependencies. 359 | * changing package to format v2 360 | * Contributors: alexv 361 | 362 | 0.0.6 (2016-04-29) 363 | ------------------ 364 | * adding --ignore-installed to avoid pip picking up local editable package when installing. 365 | * informative comments 366 | * better fix for catkin-pip requirements not found in workspace path 367 | * fixing travis to run tests for catkin-pip 368 | * Contributors: alexv 369 | 370 | 0.0.5 (2016-04-26) 371 | ------------------ 372 | * fix catkin-pip requirements not found in workspace path 373 | * typo 374 | * Contributors: alexv 375 | 376 | 0.0.4 (2016-04-08) 377 | ------------------ 378 | * Merge remote-tracking branch 'origin/indigo' into indigo 379 | * now prepending site-packages path. also for install space. 380 | * Contributors: alexv 381 | 382 | 0.0.3 (2016-04-07) 383 | ------------------ 384 | * small refactor to improve cmake messages 385 | * now specifying source director and exists-action backup when installing requirements. 386 | restored previous behavior to check for installed packages before installing current package. this avoid reinstalling dependencies satisfied by requirements. 387 | * always cleaning cache for catkin_pip for safety. 388 | * added --ignore-installed so pip doesnt try to remove old packages from system. 389 | quick Readme Roadmap 390 | * Contributors: alexv 391 | 392 | 0.0.2 (2016-04-04) 393 | ------------------ 394 | * cleaning up cmake ouput. fixing install sys pip path and pippkg path. 395 | * Merge pull request `#2 `_ from asmodehn/install_rules 396 | Install rules 397 | * improve pip finding. fixed install. 398 | * restructuring to get install running same code as devel 399 | * adding git ignore and cmake file for building mypippkg test 400 | * removed ROS dependency on cookiecutter since we need to get it from pip. 401 | * added travis build status 402 | * fixing default argument for catkin_pip_package 403 | fixing catkin_pip test build. 404 | * attempting to fix nose and tests... 405 | * improved environment detection and setup. 406 | * improved readme 407 | * fixed changelog 408 | * Contributors: AlexV 409 | 410 | 0.0.1 (2016-03-31) 411 | ------------------ 412 | * fixing install rules. 413 | improving pip download by using cache for catkin-pip requirements. 414 | * now devel workspace populated with latest pip. 415 | * first version of package. still trying stuff out... 416 | * Contributors: AlexV 417 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.3) 2 | project(catkin_pip) 3 | 4 | # Attempting auto detection of ros install if needed 5 | # sourcing a ros workspace would have already fill up the CMAKE_PREFIX_PATH 6 | if ( NOT CMAKE_PREFIX_PATH ) 7 | if (EXISTS "/opt/ros/lunar") 8 | set(CMAKE_PREFIX_PATH "/opt/ros/lunar") 9 | elseif (EXISTS "/opt/ros/kinetic") 10 | set(CMAKE_PREFIX_PATH "/opt/ros/kinetic") 11 | elseif (EXISTS "/opt/ros/jade") 12 | set(CMAKE_PREFIX_PATH "/opt/ros/jade") 13 | elseif (EXISTS "/opt/ros/indigo") 14 | set(CMAKE_PREFIX_PATH "/opt/ros/indigo") 15 | endif () 16 | endif () 17 | 18 | find_package(catkin REQUIRED) 19 | 20 | # 21 | # Here we put catkin_pip settings 22 | # So that we can manipulate them like catkin settings from inside the cfg_extras scripts 23 | 24 | if ( NOT CATKIN_PIP_GLOBAL_PYTHON_DESTINATION ) 25 | # using site-packages as it is the default for pip and should also be used on debian systems for installs from non system packages 26 | # Explanation here : http://stackoverflow.com/questions/9387928/whats-the-difference-between-dist-packages-and-site-packages 27 | set (CATKIN_PIP_GLOBAL_PYTHON_DESTINATION "lib/python2.7/site-packages") 28 | endif() 29 | 30 | # 31 | # All cmake files here are CFG_EXTRAS, because they need to be loaded by any package using catkin_pip. 32 | 33 | catkin_package( 34 | CFG_EXTRAS 35 | catkin-pip.cmake 36 | catkin-pip-runcmd.cmake 37 | catkin-pip-package.cmake 38 | catkin-pip-prefix.cmake 39 | catkin-pip-requirements.cmake 40 | pytest.cmake 41 | nosetests.cmake 42 | ) 43 | 44 | # to be found in devel space 45 | configure_file(cmake/catkin-pip-base.req ${CATKIN_DEVEL_PREFIX}/${CATKIN_PACKAGE_SHARE_DESTINATION}/cmake/catkin-pip-base.req COPYONLY) 46 | configure_file(cmake/catkin-pip-fixups.req ${CATKIN_DEVEL_PREFIX}/${CATKIN_PACKAGE_SHARE_DESTINATION}/cmake/catkin-pip-fixups.req COPYONLY) 47 | configure_file(cmake/scripts/path_prepend.sh ${CATKIN_DEVEL_PREFIX}/${CATKIN_PACKAGE_SHARE_DESTINATION}/cmake/scripts/path_prepend.sh COPYONLY) 48 | configure_file(cmake/env-hooks/42.site_packages.sh.develspace.in ${CATKIN_DEVEL_PREFIX}/${CATKIN_PACKAGE_SHARE_DESTINATION}/cmake/env-hooks/42.site_packages.sh.develspace.in COPYONLY) 49 | #configure_file(cmake/templates/python_setuptools_install.bat.in ${CATKIN_DEVEL_PREFIX}/${CATKIN_PACKAGE_SHARE_DESTINATION}/cmake/templates/python_setuptools_install.bat.in COPYONLY) 50 | configure_file(cmake/templates/python_setuptools_install.sh.in ${CATKIN_DEVEL_PREFIX}/${CATKIN_PACKAGE_SHARE_DESTINATION}/cmake/templates/python_setuptools_install.sh.in COPYONLY) 51 | 52 | # to be found in install space and from package 53 | install(FILES 54 | cmake/catkin-pip-base.req 55 | cmake/catkin-pip-fixups.req 56 | DESTINATION 57 | ${CATKIN_PACKAGE_SHARE_DESTINATION}/cmake 58 | ) 59 | 60 | install(PROGRAMS 61 | cmake/scripts/path_prepend.sh 62 | DESTINATION 63 | ${CATKIN_PACKAGE_SHARE_DESTINATION}/cmake/scripts 64 | ) 65 | 66 | # We install in cmake folder the files that are needed by cmake code 67 | install(FILES 68 | cmake/env-hooks/42.site_packages.sh.develspace.in 69 | DESTINATION 70 | ${CATKIN_PACKAGE_SHARE_DESTINATION}/cmake/env-hooks 71 | ) 72 | 73 | install(PROGRAMS 74 | # cmake/templates/python_setuptools_install.bat.in 75 | cmake/templates/python_setuptools_install.sh.in 76 | DESTINATION 77 | ${CATKIN_PACKAGE_SHARE_DESTINATION}/cmake/templates 78 | ) 79 | 80 | # Not testing when building here. 81 | # But travis should. 82 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | catkin_pip 2 | ========== 3 | 4 | |Documentation| |Build Status| |Project View| |Gitter| 5 | 6 | | Provides catkin extension (cmake hooks) to work with pure python 7 | packages in catkin workspaces. 8 | | Because state of the art python (ref. 9 | http://jeffknupp.com/blog/2013/08/16/open-sourcing-a-python-project-the-right-way/) 10 | should be allowed to work with catkin. 11 | 12 | catkin_pip allows you to use your own package as a normal python 13 | package, with python workflow (example using virtualenvwrapper):: 14 | 15 | $ mkvirtualenv my_package_venv --system-site-packages 16 | (my_package_venv)$ pip install -r requirements.txt 17 | (my_package_venv)$ python -m my_package 18 | (my_package_venv)$ nosetests my_package 19 | (my_package_venv)$ deactivate 20 | $ 21 | 22 | OR using the python workflow from inside a catkin workspace:: 23 | 24 | $ source /opt/ros/indigo/setup.bash 25 | $ cd existing_catkin_ws 26 | $ catkin_make 27 | $ source devel/setup.bash 28 | $ python -m my_package 29 | $ nosetests my_package 30 | 31 | TODO : improve this with real simple command line examples, copied 32 | verbatim. 33 | 34 | | It basically make use, through cmake, of the workspace as a virtual 35 | env would be used in a python flow. 36 | | Mostly it’s just a few arguments added to pip to get it to install 37 | packages in the correct way in a workspace. 38 | 39 | The provided cmake macros are: 40 | 41 | - catkin_pip_setup() 42 | - catkin_pip_requirements(requirements_file) 43 | - catkin_pip_package() 44 | 45 | they can be used like this : 46 | 47 | :: 48 | 49 | ... 50 | cmake_minimum_required(VERSION 2.8.3) 51 | project(my_project) 52 | 53 | find_package(catkin REQUIRED COMPONENTS 54 | catkin_pip 55 | ) 56 | 57 | # Getting pip requirements for catkin_pip itself 58 | catkin_pip_setup() 59 | 60 | # We need to install the project pip dependencies in the devel workspace being created 61 | catkin_pip_requirements(${CMAKE_CURRENT_SOURCE_DIR}/requirements.txt) 62 | 63 | # defining current package as a package that should be managed by pip (not catkin - even though we make it usable with workspaces) 64 | catkin_pip_package() 65 | 66 | # Corresponding install rules are also setup by each of these macros. 67 | ... 68 | 69 | As a result you can: 70 | 71 | - Use pip/setup.py dependency mechanism with any python git repo, for devel workspace. 72 | - Use pip dependency requirements mechanism with any pip dependency, for devel workspace. 73 | - Directly work with python package sources in your usual catkin workspaces (devel only), after just adding a `CMakeLists.txt` and a `package.xml` files. 74 | - Work with "hybrid" packages that can be released both via pip packages and ros packages, provided the proper dependencies exists for both package management systems (Note rosdep support of pip is not clear...). 75 | - Do a Third Party release of an existing python package into a ROS package (no setup.py changes required). 76 | 77 | 78 | .. |Build Status| image:: https://travis-ci.org/pyros-dev/catkin_pip.svg?branch=devel 79 | :target: https://travis-ci.org/pyros-dev/catkin_pip 80 | 81 | .. |Project View| image:: https://badge.waffle.io/pyros-dev/catkin_pip.svg?columns=all 82 | :target: https://waffle.io/pyros-dev/catkin_pip 83 | :alt: 'Waffle.io - Columns and their card count' 84 | 85 | .. |Documentation| image:: https://readthedocs.org/projects/catkin-pip/badge/?version=latest 86 | :target: http://catkin-pip.readthedocs.io/en/latest/?badge=latest 87 | :alt: Documentation Status 88 | 89 | .. |Gitter| image:: https://badges.gitter.im/asmodehn/catkin_pip.svg 90 | :target: https://gitter.im/asmodehn/catkin_pip?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge 91 | :alt: Gitter 92 | -------------------------------------------------------------------------------- /RELEASE.rst: -------------------------------------------------------------------------------- 1 | catkin_pip release process 2 | ========================== 3 | 4 | 1) Check travis builds are passing 5 | 6 | 2) `catkin_generate_changelog` 7 | 8 | 3) git commit -m "updating changelog" 9 | 10 | 4) `catkin_prepare_release` and optionally bump minor (or major) 11 | 12 | 5) Double check travis builds are passing 13 | 14 | 6) `bloom-release` to all the supported ROS distros 15 | 16 | 7) There is no check enabled on the release repo, since it is just a copy of the source repo. 17 | 18 | 8) Done ! You can start to use the new version (dont forget to configure your apt to get packages from ros-shadow-fixed) 19 | 20 | -------------------------------------------------------------------------------- /cmake/catkin-pip-base.req: -------------------------------------------------------------------------------- 1 | # Basic tools to install, simulating virtualenv creation behavior. 2 | # It is better here to pin packages to a verified version, especially since we are explointing a borderline usecase 3 | # However this means we need a short maintenance cycle to not be outdated by python folks... 4 | 5 | pip==8.1.2 # pip > 9.0 tries to remove system packages data, even if we specify /home/alexv/ROS/gopher_bootstrap/build/catkin_pip_env/bin/pip install -e /home/alexv/ROS/gopher_bootstrap/src/pyros --ignore-installed --no-dependencies --prefix /home/alexv/ROS/gopher_bootstrap/devel 6 | # Issue : https://github.com/asmodehn/catkin_pip/issues/58 7 | setuptools==33.1.1 8 | -------------------------------------------------------------------------------- /cmake/catkin-pip-fixups.req: -------------------------------------------------------------------------------- 1 | # Extra requirements, usually to fix some broken platform implementations... 2 | 3 | # Installs base packages a second time, from a recent pip, to setup all entrypoints and other latest setuptools bells and whistles properly 4 | -r catkin-pip-base.req 5 | 6 | # Upgrading to use latest nose 7 | nose==1.3.7 8 | # Also install pytest since we support it 9 | pytest==3.5.0 10 | pytest-cov==2.4.0 11 | pytest-timeout==1.2.0 12 | 13 | # Fixing security since python 2.7.6 on trusty is broken : https://stackoverflow.com/questions/29099404/ssl-insecureplatform-error-when-using-requests-package 14 | # On trusty it seems that installing libgnutls28-dev fixes the issue... 15 | #requests[security] 16 | -------------------------------------------------------------------------------- /cmake/catkin-pip-package.cmake.in: -------------------------------------------------------------------------------- 1 | if ( CMAKE_BACKWARDS_COMPATIBILITY LESS 2.8 ) 2 | message ( FATAL_ERROR " CMAKE MINIMUM BACKWARD COMPATIBILITY REQUIRED : 2.8 !" ) 3 | endif( CMAKE_BACKWARDS_COMPATIBILITY LESS 2.8 ) 4 | 5 | # Enforcing one time include https://cmake.org/Wiki/CMake_Performance_Tips#Use_an_include_guard 6 | if(catkin_pip_setup_included) 7 | return() 8 | endif(catkin_pip_setup_included) 9 | set(catkin_pip_setup_included true) 10 | 11 | message(STATUS "Loading catkin-pip-package.cmake from ${CMAKE_CURRENT_LIST_DIR}... ") 12 | 13 | 14 | # protecting against missing cmake file 15 | include ( "${CMAKE_CURRENT_LIST_DIR}/catkin-pip-runcmd.cmake" RESULT_VARIABLE CATKIN_PIP_RUNCMD_FOUND ) 16 | IF ( NOT CATKIN_PIP_RUNCMD_FOUND ) 17 | message ( FATAL_ERROR "{CMAKE_CURRENT_LIST_DIR}/catkin-pip-runcmd.cmake Not Found !!!" ) 18 | ENDIF ( NOT CATKIN_PIP_RUNCMD_FOUND ) 19 | 20 | # protecting against missing cmake file 21 | include ( "${CMAKE_CURRENT_LIST_DIR}/catkin-pip-prefix.cmake" RESULT_VARIABLE CATKIN_PIP_PREFIX_FOUND ) 22 | IF ( NOT CATKIN_PIP_PREFIX_FOUND ) 23 | message ( FATAL_ERROR "{CMAKE_CURRENT_LIST_DIR}/catkin-pip-prefix.cmake Not Found !!!" ) 24 | ENDIF ( NOT CATKIN_PIP_PREFIX_FOUND ) 25 | 26 | 27 | # These are set on include time by catkin-pip and point to catkin-pip folders 28 | if ( NOT CATKIN_PIP_TEMPLATES_PATH ) 29 | # templates should found relative to our current path 30 | set (CATKIN_PIP_TEMPLATES_PATH ${CMAKE_CURRENT_LIST_DIR}/templates CACHE PATH "templates path") 31 | endif() 32 | 33 | # We are replacing catkin's python_setup functionality 34 | # This is run by the package and CMAKE_CURRENT_LIST_DIR refer to the package one. 35 | function(catkin_pip_python_setup) 36 | 37 | # Setting up variables for scripts configuration (in a function to keep it here) 38 | set(CATKIN_PIP_PACKAGE_PATH ${package_path}) 39 | 40 | # sourcing envhooks to keep coherence between cmake run and shell run (especially for tests) 41 | # DUPLICATED with catkin_pip_setup 42 | #catkin_pip_runcmd(${CATKIN_PIP} install -e ${package_path} --no-dependencies --prefix "${CATKIN_DEVEL_PREFIX}") 43 | 44 | # BEGIN : This is from catkin_python_setup 45 | # we follow same process but with slightly different scripts 46 | # 47 | 48 | assert(PYTHON_INSTALL_DIR) 49 | assert(CATKIN_PIP_PYTHON_INSTALL_DIR) 50 | set(INSTALL_CMD_WORKING_DIRECTORY ${package_path}) 51 | 52 | if(NOT WIN32) 53 | set(INSTALL_SCRIPT 54 | ${CMAKE_CURRENT_BINARY_DIR}/catkin_generated/python_setuptools_install.sh) 55 | configure_file(${CATKIN_PIP_TEMPLATES_PATH}/python_setuptools_install.sh.in 56 | ${INSTALL_SCRIPT} 57 | @ONLY) 58 | else() 59 | # need to convert install prefix to native path for python setuptools --prefix (its fussy about \'s) 60 | file(TO_NATIVE_PATH ${CMAKE_INSTALL_PREFIX} PYTHON_INSTALL_PREFIX) 61 | set(INSTALL_SCRIPT 62 | ${CMAKE_CURRENT_BINARY_DIR}/catkin_generated/python_setuptools_install.bat) 63 | configure_file(${CATKIN_PIP_TEMPLATES_PATH}/python_setuptools_install.bat.in 64 | ${INSTALL_SCRIPT} 65 | @ONLY) 66 | endif() 67 | 68 | # generate python script which gets executed at install time 69 | configure_file(${catkin_EXTRAS_DIR}/templates/safe_execute_install.cmake.in 70 | ${CMAKE_CURRENT_BINARY_DIR}/catkin_generated/safe_execute_install.cmake) 71 | install(SCRIPT ${CMAKE_CURRENT_BINARY_DIR}/catkin_generated/safe_execute_install.cmake) 72 | 73 | # END : This is the end of catkin_python_setup copy 74 | # Ideally we shouldn't need any more tricks for building the install space 75 | # 76 | 77 | endfunction() 78 | 79 | 80 | function(catkin_pip_target package_name) 81 | 82 | set (extra_macro_args ${ARGN}) 83 | 84 | # Did we get any optional args? 85 | list(LENGTH extra_macro_args num_extra_args) 86 | if (${num_extra_args} GREATER 0) 87 | list(GET extra_macro_args 0 package_path) 88 | #message ("Got package_path: ${package_path}") 89 | else() 90 | set(package_path ${CMAKE_CURRENT_SOURCE_DIR}) 91 | endif() 92 | 93 | set(${PROJECT_NAME}_PIP_TARGET ${package_name} CACHE STRING "Make target generated to install this pip package as --editable for development") 94 | 95 | # Note : environment should already be setup at configure time for devel 96 | 97 | # Then we can run the pip command 98 | # Note when installing in editable mode (for development) we shouldnt care about already installed versions. 99 | # However : https://github.com/asmodehn/catkin_pip/issues/58 100 | if(CATKIN_PIP_NO_DEPS) 101 | catkin_pip_install_devel_target(${package_name} ${package_path} --no-dependencies --ignore-installed) 102 | #catkin_pip_runcmd(${CATKIN_PIP} install -e ${package_path} --no-dependencies --prefix "${CATKIN_DEVEL_PREFIX}" --ignore-installed) 103 | else() 104 | catkin_pip_install_devel_target(${package_name} ${package_path} --ignore-installed) 105 | #catkin_pip_runcmd(${CATKIN_PIP} install -e ${package_path} --prefix "${CATKIN_DEVEL_PREFIX}" --ignore-installed) 106 | endif() 107 | 108 | if(NOT EXISTS ${package_path}/setup.py) 109 | message(FATAL_ERROR "catkin_pip_setup() called without 'setup.py' in project folder '${package_path}'") 110 | endif() 111 | 112 | # Probably better to do that here (dont do anything "special" for python) 113 | catkin_pip_python_setup() 114 | 115 | # TODO : we might want to generate a package.xml on the fly from setup.py contents... 116 | 117 | endfunction() 118 | 119 | 120 | # BWCOMPAT : eventually get rid of that... 121 | macro(catkin_pip_package package_name) 122 | 123 | catkin_pip_target(${package_name} ${ARGN}) 124 | 125 | # Here we plug back into usual catkin package build flow 126 | # CAREFUL : this will set variables into current scope. 127 | catkin_package() 128 | 129 | endmacro() 130 | -------------------------------------------------------------------------------- /cmake/catkin-pip-prefix.cmake.in: -------------------------------------------------------------------------------- 1 | if ( CMAKE_BACKWARDS_COMPATIBILITY LESS 2.8 ) 2 | message ( FATAL_ERROR " CMAKE MINIMUM BACKWARD COMPATIBILITY REQUIRED : 2.8 !" ) 3 | endif( CMAKE_BACKWARDS_COMPATIBILITY LESS 2.8 ) 4 | 5 | # Enforcing one time include https://cmake.org/Wiki/CMake_Performance_Tips#Use_an_include_guard 6 | if(catkin_pip_prefix_included) 7 | return() 8 | endif(catkin_pip_prefix_included) 9 | set(catkin_pip_prefix_included true) 10 | 11 | message(STATUS "Loading catkin-pip-prefix.cmake from ${CMAKE_CURRENT_LIST_DIR}... ") 12 | 13 | 14 | # 15 | # Important : This script is included by multiple cmake scripts at configure and build time 16 | # So it needs to be idempotent (no change if called multiple time with same settings/environment) 17 | # 18 | 19 | 20 | # protecting against missing cmake file 21 | include ( "${CMAKE_CURRENT_LIST_DIR}/catkin-pip-runcmd.cmake" RESULT_VARIABLE CATKIN_PIP_RUNCMD_FOUND ) 22 | IF ( NOT CATKIN_PIP_RUNCMD_FOUND ) 23 | message ( FATAL_ERROR "{CMAKE_CURRENT_LIST_DIR}/catkin-pip-runcmd.cmake Not Found !!!" ) 24 | ENDIF ( NOT CATKIN_PIP_RUNCMD_FOUND ) 25 | 26 | if ( NOT CATKIN_PIP_REQUIREMENTS_PATH ) 27 | # Our current path is where all catkin-pip requirements should be 28 | set (CATKIN_PIP_REQUIREMENTS_PATH ${CMAKE_CURRENT_LIST_DIR} CACHE PATH "where all catkin-pip requirements should be") 29 | endif() 30 | 31 | function(find_catkin_system_pip) 32 | # we need to make sure we don't find any other catkin-pip from somewhere else if our path is not clean (careful with underlays or install/devel) 33 | find_program(CATKIN_SYS_PIP NAMES pip pip2 pip2.7 NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH NO_SYSTEM_ENVIRONMENT_PATH) 34 | 35 | if(CATKIN_SYS_PIP) 36 | set(PIP_VERSION_COMMAND ${CATKIN_SYS_PIP} --version) 37 | 38 | string(REPLACE ";" " " PIP_VERSION_CMDSTR "${PIP_VERSION_COMMAND}") 39 | #message(STATUS " ... Running ${PIP_VERSION_CMDSTR} ...") 40 | 41 | execute_process( 42 | COMMAND ${PIP_VERSION_COMMAND} 43 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 44 | RESULT_VARIABLE PIP_VERSION_RESULT 45 | OUTPUT_VARIABLE PIP_VERSION_VARIABLE 46 | ERROR_VARIABLE PIP_VERSION_ERROR 47 | ) 48 | 49 | #message(STATUS " ... Done ... [${PIP_VERSION_RESULT}]: ${PIP_VERSION_VARIABLE}") 50 | if (PIP_VERSION_RESULT) 51 | message(STATUS "System Introspection Command ${PIP_VERSION_CMDSTR} FAILED !") 52 | message(FATAL_ERROR "${PIP_VERSION_ERROR}") 53 | else() 54 | # we need to parse the result to extract the version 55 | string(REPLACE " " ";" PIP_VERSION_VARIABLE_LIST ${PIP_VERSION_VARIABLE}) 56 | list(GET PIP_VERSION_VARIABLE_LIST 1 CATKIN_SYS_PIP_VERSION) 57 | set (CATKIN_SYS_PIP_VERSION ${CATKIN_SYS_PIP_VERSION} CACHE INTERNAL "Major version of pip detected on the system") 58 | 59 | message(STATUS " System pip version detected : ${CATKIN_SYS_PIP_VERSION}") 60 | 61 | endif() 62 | 63 | # Detecting debian pip "--system" extension 64 | # ros@ros-Kinetic-VM:~/Project$ pip install --help | grep -e "--system" 65 | # --system Install using the system scheme (overrides --user on Debian systems) 66 | # ros@ros-Kinetic-VM:~/Project$ pip install --help | grep -e "--system" | wc -l 67 | # 1 68 | 69 | set(PIP_INSTALL_HELP_COMMAND ${CATKIN_SYS_PIP} install --help) 70 | 71 | string(REPLACE ";" " " PIP_INSTALL_HELP_CMDSTR "${PIP_VERSION_COMMAND}") 72 | #message(STATUS " ... Running ${PIP_INSTALL_HELP_CMDSTR} ...") 73 | 74 | execute_process( 75 | COMMAND ${PIP_INSTALL_HELP_COMMAND} 76 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 77 | RESULT_VARIABLE PIP_INSTALL_HELP_RESULT 78 | OUTPUT_VARIABLE PIP_INSTALL_HELP_VARIABLE 79 | ERROR_VARIABLE PIP_INSTALL_HELP_ERROR 80 | ) 81 | 82 | #message(STATUS " ... Done ... [${PIP_INSTALL_HELP_RESULT}]: ${PIP_INSTALL_HELP_VARIABLE}") 83 | if (PIP_INSTALL_HELP_RESULT) 84 | message(STATUS "System Introspection Command ${PIP_INSTALL_HELP_CMDSTR} FAILED !") 85 | message(FATAL_ERROR "${PIP_INSTALL_HELP_ERROR}") 86 | else() 87 | message(STATUS " System pip install detected options : ") 88 | string(REPLACE "\n" ";" PIP_INSTALL_HELP_VARIABLE_LIST ${PIP_INSTALL_HELP_VARIABLE}) 89 | 90 | # CMake list search 91 | foreach(line IN LISTS PIP_INSTALL_HELP_VARIABLE_LIST) 92 | # message("LINE : ${line}") 93 | # parsing line by line to extract available options 94 | string(REPLACE " " ";" line_list ";${line};") 95 | 96 | list (FIND line_list "--user" _index) 97 | if (${_index} GREATER -1) 98 | message(STATUS " --user") 99 | set(CATKIN_SYS_PIP_HAS_USER TRUE CACHE INTERNAL "Whether detected system pip can do 'pip install --user'" ) 100 | endif() 101 | 102 | list (FIND line_list "--system" _index) 103 | if (${_index} GREATER -1) 104 | message(STATUS " --system") 105 | set(CATKIN_SYS_PIP_HAS_SYSTEM TRUE CACHE INTERNAL "Whether detected system pip can do 'pip install --system'" ) 106 | endif() 107 | 108 | endforeach() 109 | 110 | endif() 111 | 112 | else(CATKIN_SYS_PIP) 113 | message( FATAL_ERROR "pip system command not found. Make sure you have installed the python-pip package on your system.") 114 | endif() 115 | 116 | endfunction(find_catkin_system_pip) 117 | 118 | 119 | function(catkin_pip_setup_prefix ws_prefix) 120 | 121 | # Trying to find our own pip 122 | # Careful this creates a CACHE variable that we need to recreate here in case people clean devel without cleaning build 123 | unset(CATKIN_PIP CACHE) 124 | find_program(CATKIN_PIP NAMES pip pip2 pip2.7 PATHS ${ws_prefix}/@CATKIN_GLOBAL_BIN_DESTINATION@ NO_DEFAULT_PATH) 125 | 126 | if (CATKIN_PIP) 127 | set(CATKIN_PIP "${CATKIN_PIP} -q") # we can add all default basic options here. 128 | else () 129 | # If not found, it means we need to do the whole setup... 130 | unset(CATKIN_PIP CACHE) 131 | # TODO: cleanup if unnecessary message (the find_program already outputs something 132 | message(STATUS " ... Catkin pip was not found in ${ws_prefix}/@CATKIN_GLOBAL_BIN_DESTINATION@ ...") 133 | 134 | # Assuming Ubuntu Trusty here. platform detection is another hurdle 135 | set(CMAKE_SYSTEM_PREFIX_PATH / /usr /usr/local) 136 | 137 | find_catkin_system_pip() 138 | 139 | message(STATUS " ... Retrieving catkin_pip requirements using system pip ...") 140 | 141 | if(${CATKIN_SYS_PIP_HAS_SYSTEM}) 142 | # if --system is present, it means the default behavior has been changed to --user (by debian/ubuntu) 143 | # and we have to specify --system in order to use --target 144 | set(OPT_SYSTEM "--system") 145 | else(${CATKIN_SYS_PIP_HAS_SYSTEM}) 146 | set(OPT_SYSTEM "") 147 | endif(${CATKIN_SYS_PIP_HAS_SYSTEM}) 148 | 149 | if (${CATKIN_SYS_PIP_VERSION} VERSION_LESS 6.0.0) 150 | # We need to find a pip command that works for old pip versions (indigo supports trusty which is pip v1.5.4) 151 | # Note --target here means we cannot check if a package is already installed or not before installing, using old pip. 152 | # which means we have to reinstall dependencies everytime and specify --exists-action w to avoid "already exists" errors 153 | # Avoid --install-option since the setuptools version found will be different the first time and the following times 154 | execute_process( 155 | COMMAND ${CATKIN_ENV} ${CATKIN_SYS_PIP} install ${OPT_SYSTEM} -r "${CATKIN_PIP_REQUIREMENTS_PATH}/catkin-pip-base.req" --download-cache "${CMAKE_BINARY_DIR}/pip-cache" --target "${ws_prefix}/@CATKIN_PIP_GLOBAL_PYTHON_DESTINATION@" --exists-action w 156 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 157 | RESULT_VARIABLE PIP_RESULT 158 | OUTPUT_VARIABLE PIP_VARIABLE 159 | ERROR_VARIABLE PIP_ERROR 160 | ) 161 | message(STATUS " ... Done ... [${PIP_RESULT}]: ${PIP_VARIABLE}") 162 | if (PIP_RESULT) 163 | message(STATUS "Command ${CATKIN_SYS_PIP} install ${OPT_SYSTEM} -r \"${CATKIN_PIP_REQUIREMENTS_PATH}/catkin-pip-base.req\" --download-cache \"${CMAKE_BINARY_DIR}/pip-cache\" --target \"${ws_prefix}/@CATKIN_PIP_GLOBAL_PYTHON_DESTINATION@\" --exists-action w FAILED") 164 | message(FATAL_ERROR "${PIP_ERROR}") 165 | endif() 166 | else () # assuming latest pip 167 | # We need to find a pip command that works for pip versions (kinetic supports xenial which is pip v8.1.1) 168 | # Careful --system is a debian porting extension. This will not work if the system pip command loads the pip package of pip itself, after the environment has been setup... 169 | execute_process( 170 | COMMAND ${CATKIN_ENV} ${CATKIN_SYS_PIP} install ${OPT_SYSTEM} -r "${CATKIN_PIP_REQUIREMENTS_PATH}/catkin-pip-base.req" --cache-dir "${CMAKE_BINARY_DIR}/pip-cache" --target "${ws_prefix}/@CATKIN_PIP_GLOBAL_PYTHON_DESTINATION@" --exists-action w 171 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 172 | RESULT_VARIABLE PIP_RESULT 173 | OUTPUT_VARIABLE PIP_VARIABLE 174 | ERROR_VARIABLE PIP_ERROR 175 | ) 176 | message(STATUS " ... Done ... [${PIP_RESULT}]: ${PIP_VARIABLE}") 177 | if (PIP_RESULT) 178 | message(STATUS "Command ${CATKIN_SYS_PIP} install ${OPT_SYSTEM} -r \"${CATKIN_PIP_REQUIREMENTS_PATH}/catkin-pip-base.req\" --cache-dir \"${CMAKE_BINARY_DIR}/pip-cache\" --target \"${ws_prefix}/@CATKIN_PIP_GLOBAL_PYTHON_DESTINATION@\" --exists-action w FAILED") 179 | message(FATAL_ERROR "${PIP_ERROR}") 180 | endif() 181 | endif() 182 | 183 | 184 | set(CATKIN_PIP ${PYTHON_EXECUTABLE} -m pip) # to make sure we use our recently downloaded pip version (its entrypoints were not installed by old pip/setuptools) 185 | 186 | unset(CATKIN_SYS_PIP CACHE) # we dont need this any longer 187 | # We are now using the latest pip from pip package, and not the system one. 188 | 189 | # Fixing security since python 2.7.6 on trusty is broken : https://stackoverflow.com/questions/29099404/ssl-insecureplatform-error-when-using-requests-package 190 | # Also reinstalling pip to finally get it in bin/ 191 | 192 | # To debug the python environment at this stage 193 | #catkin_pip_runcmd(${PYTHON_EXECUTABLE} -m site) 194 | 195 | catkin_pip_runcmd(${CATKIN_PIP} install --ignore-installed -r "${CATKIN_PIP_REQUIREMENTS_PATH}/catkin-pip-fixups.req" --src ${CMAKE_SOURCE_DIR} --exists-action b --prefix "${ws_prefix}") 196 | 197 | unset(CATKIN_PIP) 198 | # now we can finally use the simple "pip" entry_point (forcing cmake to find it) 199 | find_program( CATKIN_PIP NAMES pip pip2 pip2.7 PATHS ${ws_prefix}/@CATKIN_GLOBAL_BIN_DESTINATION@ NO_DEFAULT_PATH) 200 | if (CATKIN_PIP) 201 | message( STATUS "Found catkin_pip pip command at ${CATKIN_PIP}.") 202 | else() 203 | message( FATAL_ERROR "catkin_pip pip command not found in ${ws_prefix}/@CATKIN_GLOBAL_BIN_DESTINATION@. Make sure you have installed the pip pip package on ${ws_prefix} workspace.") 204 | endif() 205 | 206 | endif() 207 | endfunction() 208 | -------------------------------------------------------------------------------- /cmake/catkin-pip-requirements.cmake.in: -------------------------------------------------------------------------------- 1 | if ( CMAKE_BACKWARDS_COMPATIBILITY LESS 2.8 ) 2 | message ( FATAL_ERROR " CMAKE MINIMUM BACKWARD COMPATIBILITY REQUIRED : 2.8 !" ) 3 | endif( CMAKE_BACKWARDS_COMPATIBILITY LESS 2.8 ) 4 | 5 | # Enforcing one time include https://cmake.org/Wiki/CMake_Performance_Tips#Use_an_include_guard 6 | if(catkin_pip_requirements_included) 7 | return() 8 | endif(catkin_pip_requirements_included) 9 | set(catkin_pip_requirements_included true) 10 | 11 | message(STATUS "Loading catkin-pip-requirements.cmake from ${CMAKE_CURRENT_LIST_DIR}... ") 12 | 13 | 14 | # protecting against missing cmake file 15 | include ( "${CMAKE_CURRENT_LIST_DIR}/catkin-pip-prefix.cmake" RESULT_VARIABLE CATKIN_PIP_PREFIX_FOUND ) 16 | IF ( NOT CATKIN_PIP_PREFIX_FOUND ) 17 | message ( FATAL_ERROR "{CMAKE_CURRENT_LIST_DIR}/catkin-pip-prefix.cmake Not Found !!!" ) 18 | ENDIF ( NOT CATKIN_PIP_PREFIX_FOUND ) 19 | 20 | # 21 | # Here we also setup the environment so that detected pip version is usable enough 22 | # This is used by any other project directly (at configure time). 23 | # It will automatically setup a prefix with catkin-pip. 24 | # 25 | function(catkin_pip_requirements requirements_txt) 26 | 27 | # Setting up our environment (for devel space only) 28 | # Needed in case user call this directly (configure time) 29 | catkin_pip_setup_prefix(${CATKIN_PIP_ENV}) 30 | 31 | # runnig the pip command (configure time) 32 | catkin_pip_runcmd(${CATKIN_PIP} install ${ARGN} -r ${requirements_txt} --ignore-installed --src ${CMAKE_SOURCE_DIR} --exists-action b --prefix "${CATKIN_DEVEL_PREFIX}") 33 | 34 | endfunction() 35 | -------------------------------------------------------------------------------- /cmake/catkin-pip-runcmd.cmake.in: -------------------------------------------------------------------------------- 1 | if ( CMAKE_BACKWARDS_COMPATIBILITY LESS 2.8 ) 2 | message ( FATAL_ERROR " CMAKE MINIMUM BACKWARD COMPATIBILITY REQUIRED : 2.8 !" ) 3 | endif( CMAKE_BACKWARDS_COMPATIBILITY LESS 2.8 ) 4 | 5 | # Enforcing one time include https://cmake.org/Wiki/CMake_Performance_Tips#Use_an_include_guard 6 | if(catkin_pip_runcmd_included) 7 | return() 8 | endif(catkin_pip_runcmd_included) 9 | set(catkin_pip_runcmd_included true) 10 | 11 | message(STATUS "Loading catkin-pip-runcmd.cmake from ${CMAKE_CURRENT_LIST_DIR}... ") 12 | 13 | # 14 | # Important : This script is included by multiple cmake scripts at configure and build time 15 | # So it needs to be idempotent (no change if called multiple time with same settings/environment) 16 | # 17 | 18 | 19 | function(catkin_pip_runcmd) 20 | 21 | set(CATKIN_PIP_COMMAND ${ARGN}) 22 | 23 | # TODO : refactor to use separate arguments, like catkin_pip_install_devel_target 24 | string(REPLACE ";" " " CATKIN_PIP_CMDSTR "${CATKIN_ENV} ${CATKIN_PIP_COMMAND}") 25 | message(STATUS " ... Running ${CATKIN_PIP_CMDSTR} ...") 26 | 27 | execute_process( 28 | # Note we need to use catkin_env to make sure our envhook is properly loaded 29 | COMMAND ${CATKIN_ENV} ${CATKIN_PIP_COMMAND} 30 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 31 | RESULT_VARIABLE PIP_RESULT 32 | OUTPUT_VARIABLE PIP_VARIABLE 33 | ERROR_VARIABLE PIP_ERROR 34 | ) 35 | 36 | message(STATUS " ... Done ... [${PIP_RESULT}]: ${PIP_VARIABLE}") 37 | if (PIP_RESULT) 38 | message(STATUS "Command ${CATKIN_PIP_CMDSTR} FAILED !") 39 | message(FATAL_ERROR "${PIP_ERROR}") 40 | endif() 41 | 42 | endfunction() 43 | 44 | 45 | function(catkin_pip_install_devel_target package_name package_path) 46 | set(CATKIN_PIP_INSTALL_DEVEL_OUTPUTS 47 | # ${CATKIN_DEVEL_PREFIX}/${CATKIN_PIP_PYTHON_INSTALL_DIR}/easy-install.pth 48 | # CAREFUL with multiple outputs : https://cmake.org/Bug/view.php?id=15116 49 | ${CATKIN_DEVEL_PREFIX}/${CATKIN_PIP_PYTHON_INSTALL_DIR}/${package_name}.egg-link 50 | ) 51 | 52 | string(REPLACE ";" " " ARGN_STR "${ARGN}") 53 | 54 | # note setlock/flock because of https://github.com/pypa/pip/issues/2361 55 | # TODO : change to use --target to allow installing duplicate packages with pip>=9.0.0 ... Ref https://github.com/pypa/pip/issues/4243 56 | 57 | 58 | set(CATKIN_PIP_CMD ${CATKIN_ENV}) 59 | set(CATKIN_PIP_CMD_ARGS_STR "flock ${CATKIN_PIP_ENV}/catkin_pip.lock ${CATKIN_PIP} install -e ${package_path} --prefix ${CATKIN_DEVEL_PREFIX} ${ARGN_STR}") 60 | # IF WE ARE PASSING EDITABLE PKG PATHS INTO PYTHONPATH we need to work around bug : 61 | # PYTHONPATH breaks pip install --editable Ref : https://github.com/pypa/pip/issues/4261 62 | # set(CATKIN_PIP_CMD_ARGS_STR "-c 'export PYTHONPATH=${CATKIN_DEVEL_PREFIX}/${CATKIN_PIP_PYTHON_INSTALL_DIR}:${CATKIN_PIP_ENV}/${CATKIN_PIP_PYTHON_INSTALL_DIR}\; ${CATKIN_PIP_CMD_ARGS_STR}'") 63 | # set(CATKIN_PIP_CMD /bin/bash) # Ubuntu (Linux?) only # Also we are probably missing some other CATKIN_ENV setup... 64 | 65 | 66 | separate_arguments(CATKIN_PIP_CMD_ARGS_LIST UNIX_COMMAND ${CATKIN_PIP_CMD_ARGS_STR}) 67 | 68 | 69 | # Note that catkin_env is called first. That is because we do not trust catkin_env return code and async behavior. 70 | # However we have to assume it doesn't alter the environment in a way that breaks setlock/flock. 71 | # Hint : on ubuntu trusty, I noticed the lock file stay there after execution, however the mutex behavior works fine. 72 | 73 | add_custom_command( 74 | OUTPUT ${CATKIN_PIP_INSTALL_DEVEL_OUTPUTS} 75 | 76 | # Note we are using setlock/flock to avoid concurrent pip calls (if make runs target in parallel) 77 | # Note we override PYTHONPATH to workaround a pip bug 78 | # Note we need to use catkin_env to make sure our envhook is properly loaded 79 | 80 | COMMAND ${CATKIN_PIP_CMD} ${CATKIN_PIP_CMD_ARGS_LIST} 81 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 82 | DEPENDS "${package_path}" # file level dependency : package needs to be in the path 83 | COMMENT "${CATKIN_PIP_CMD} ${CATKIN_PIP_CMD_ARGS_STR}" 84 | VERBATIM 85 | ) 86 | 87 | add_custom_target(${package_name} ALL DEPENDS ${CATKIN_PIP_INSTALL_DEVEL_OUTPUTS}) # file level dependency : we need the output of the custom command 88 | 89 | endfunction() 90 | -------------------------------------------------------------------------------- /cmake/catkin-pip.cmake.in: -------------------------------------------------------------------------------- 1 | if ( CMAKE_BACKWARDS_COMPATIBILITY LESS 2.8 ) 2 | message ( FATAL_ERROR " CMAKE MINIMUM BACKWARD COMPATIBILITY REQUIRED : 2.8 !" ) 3 | endif( CMAKE_BACKWARDS_COMPATIBILITY LESS 2.8 ) 4 | 5 | # Enforcing one time include https://cmake.org/Wiki/CMake_Performance_Tips#Use_an_include_guard 6 | if(catkin_pip_main_included) 7 | return() 8 | endif(catkin_pip_main_included) 9 | set(catkin_pip_main_included true) 10 | 11 | message(STATUS "Loading catkin-pip.cmake from ${CMAKE_CURRENT_LIST_DIR}... ") 12 | 13 | # Setting required policies 14 | # required to be able to do "if (True)" 15 | # FOREACH(policy CMP0011 CMP0012 CMP0013 CMP0014) 16 | # IF(POLICY ${policy}) 17 | # CMAKE_POLICY(SET ${policy} NEW) 18 | # ENDIF() 19 | # ENDFOREACH() 20 | 21 | # protecting against missing cmake file dependency 22 | include ( "${CMAKE_CURRENT_LIST_DIR}/catkin-pip-requirements.cmake" RESULT_VARIABLE CATKIN_PIP_REQUIREMENTS_FOUND ) 23 | IF ( NOT CATKIN_PIP_REQUIREMENTS_FOUND ) 24 | message ( FATAL_ERROR "${CMAKE_CURRENT_LIST_DIR}/catkin-pip-requirements.cmake Not Found !!!" ) 25 | ENDIF ( NOT CATKIN_PIP_REQUIREMENTS_FOUND ) 26 | 27 | # protecting against missing cmake file dependency 28 | include ( "${CMAKE_CURRENT_LIST_DIR}/catkin-pip-package.cmake" RESULT_VARIABLE CATKIN_PIP_PACKAGE_FOUND ) 29 | IF ( NOT CATKIN_PIP_PACKAGE_FOUND ) 30 | message ( FATAL_ERROR "${CMAKE_CURRENT_LIST_DIR}/catkin-pip-package.cmake Not Found !!!" ) 31 | ENDIF ( NOT CATKIN_PIP_PACKAGE_FOUND ) 32 | 33 | # Setting our paths to package env-hooks provided by catkin-pip 34 | if ( NOT CATKIN_PIP_ENV_HOOKS_PATH ) 35 | # templates should be found relative to our current path 36 | set (CATKIN_PIP_ENV_HOOKS_PATH ${CMAKE_CURRENT_LIST_DIR}/env-hooks) 37 | endif() 38 | 39 | # We want the catkin environment to be used for both devel and install workspace 40 | # to use latest versions python tools in both. 41 | set(CATKIN_PIP_ENV ${CMAKE_BINARY_DIR}/catkin_pip_env CACHE PATH "The path containing the python environment for catkin_pip dependencies" ) 42 | set(CATKIN_PIP_NO_DEPS True CACHE BOOL "Whether we want to retrieve python dependencies and requirements for packages" ) 43 | set(CATKIN_PIP_PYTHON_INSTALL_DIR @CATKIN_PIP_GLOBAL_PYTHON_DESTINATION@) 44 | set(CATKIN_PYTHON_INSTALL_DIR @CATKIN_GLOBAL_PYTHON_DESTINATION@) 45 | 46 | # These are set on include time by catkin-pip and point to catkin-pip folders 47 | if ( NOT CATKIN_PIP_SCRIPTS_PATH ) 48 | # templates should found relative to our current path 49 | set (CATKIN_PIP_SCRIPTS_PATH ${CMAKE_CURRENT_LIST_DIR}/scripts CACHE PATH "scripts path") 50 | endif() 51 | 52 | # Setting up python site-packages directory in devel workspace 53 | # If needed we create the directory (to avoid later errors) 54 | # It is required on isolated builds and for env-hooks 55 | file(MAKE_DIRECTORY ${CATKIN_DEVEL_PREFIX}/@CATKIN_PIP_GLOBAL_PYTHON_DESTINATION@) 56 | 57 | # Since we need the envhook as soon as a package is using catkin-pip from source. 58 | catkin_add_env_hooks(42.site_packages SHELLS sh DIRECTORY ${CATKIN_PIP_ENV_HOOKS_PATH}) 59 | # If we need paths in install space, they should somehow be stored in generated scripts (make or others) as much as possible 60 | # TODO : cmake should include this file only once per workspace, so the env hook is not recreated for every package that uses catkin_pip if they are in same workspace... 61 | 62 | 63 | # Setting up catkin prefix in catkin_pip_env 64 | catkin_pip_setup_prefix(${CATKIN_PIP_ENV}) 65 | 66 | # 67 | # Install Space should have same behavior as package build 68 | # We want to check dependencies are all satisfied, without relying on pip requirements. 69 | # But we want to use latest version python libraries (especially setuptools) 70 | # 71 | -------------------------------------------------------------------------------- /cmake/env-hooks/42.site_packages.sh.develspace.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Careful : env.sh *executes* it during cmake configure, but setup.sh source it ! 3 | # If using a sh script, this can make a lot of issues... 4 | # Reference to address these from a Bourne shell http://stackoverflow.com/a/29835459 5 | 6 | # lets be safe : Ref : http://www.davidpashley.com/articles/writing-robust-shell-scripts/ 7 | set -o nounset 8 | set -o noglob 9 | # set -o errexit # for development only 10 | # tested with dash on ubuntu trusty 11 | 12 | # For catkin it is simpler to do add site-packages to PYTHONPATH in _setup_util.py.in than us doing it from here... 13 | # but until catkin does this by default, the proper way from outside catkin is probably a env-hook like this one 14 | 15 | # Note : We should enable site-package only on devel space. 16 | # Install space should behave like packages, everything in debian layout. 17 | 18 | # TODO : find a cleaner way to call a shell function defined in another script 19 | 20 | # Setting up the catkin environment itself 21 | # This needs to be in a different prefix, to be able to generate an install dir with setuptools, yet clear of any catkin_pip artifacts. 22 | # Also this path needs to ALWAYS be added to PYTHONPATH. Mandatory the first time we run catkin_pip to setup the environment. 23 | #echo "Inserting @CATKIN_PIP_ENV@/@CATKIN_PIP_PYTHON_INSTALL_DIR@ in front of PYTHONPATH" 24 | PYTHONPATH=$("@CATKIN_PIP_SCRIPTS_PATH@/path_prepend.sh" "@CATKIN_PIP_ENV@/@CATKIN_PIP_PYTHON_INSTALL_DIR@" "${PYTHONPATH}") || ${PYTHONPATH} # to be safe if path_prepend fails 25 | 26 | 27 | # Adding bin/ into the path 28 | if [ -d "@CATKIN_PIP_ENV@/@CATKIN_GLOBAL_BIN_DESTINATION@" ]; then 29 | #echo "Inserting @CATKIN_PIP_ENV@/@CATKIN_GLOBAL_BIN_DESTINATION@ in front of PATH" 30 | PATH=$("@CATKIN_PIP_SCRIPTS_PATH@/path_prepend.sh" "@CATKIN_PIP_ENV@/@CATKIN_GLOBAL_BIN_DESTINATION@" "${PATH}") || ${PATH} # to be safe if path_prepend fails 31 | fi 32 | 33 | # Somehow It seems we need to also (re)add dist-packages here to get package tests to work with ROS packages in same workspace 34 | # Especially when running tests with catkin_pip from source... there seem to be some workflow issue due to catkin cache environment... 35 | # Anyway it doesnt hurt to have it here as well. 36 | # this is usual for catkin -> no echo. This might actually be a fix for catkin not setting this before running tests. 37 | 38 | if [ -d "@CATKIN_DEVEL_PREFIX@/@CATKIN_PYTHON_INSTALL_DIR@" ]; then 39 | #echo "Inserting @CATKIN_DEVEL_PREFIX@/@CATKIN_PYTHON_INSTALL_DIR@ in front of PYTHONPATH" 40 | PYTHONPATH=$("@CATKIN_PIP_SCRIPTS_PATH@/path_prepend.sh" "@CATKIN_DEVEL_PREFIX@/@CATKIN_PYTHON_INSTALL_DIR@" "${PYTHONPATH}") || ${PYTHONPATH} # to be safe if path_prepend fails 41 | # Problem : before which workspace ? we might break workspace overlay order here 42 | fi 43 | 44 | # We combine our build path (catkin_pip_env) with site-packages (pip default) location, before attempting to prepend to the python path 45 | # Careful : echo is only possible if we are in a bash script (not used by env.sh) 46 | 47 | if [ -d "@CATKIN_DEVEL_PREFIX@/@CATKIN_PIP_PYTHON_INSTALL_DIR@" ]; then 48 | #echo "Inserting @CATKIN_DEVEL_PREFIX@/@CATKIN_PIP_PYTHON_INSTALL_DIR@ before @CATKIN_DEVEL_PREFIX@/@CATKIN_PYTHON_INSTALL_DIR@ into PYTHONPATH" 49 | PYTHONPATH=$("@CATKIN_PIP_SCRIPTS_PATH@/path_prepend.sh" "@CATKIN_DEVEL_PREFIX@/@CATKIN_PIP_PYTHON_INSTALL_DIR@" "${PYTHONPATH}" "@CATKIN_DEVEL_PREFIX@/@CATKIN_PYTHON_INSTALL_DIR@") || ${PYTHONPATH} # to be safe if path_prepend fails 50 | fi 51 | 52 | # NOT DOING THIS any longer : it half-works but somehow doesnt change behavior when using catkin cmake scripts : usual python way, editable links are after python path 53 | # TO FIX IT : use pyros_setup 54 | # # Prepending here our easy-install.pth content into PYTHONPATH, for overlayed workspace to get it before the workspace path 55 | # # Somehow Python pth/.egg behavior doesnt work well with workspace overlays, based on PYTHONPATH. 56 | # # However be aware of : https://github.com/pypa/pip/issues/3160 57 | # # And : https://github.com/pypa/pip/issues/4261 58 | # if [ -f "@CATKIN_DEVEL_PREFIX@/@CATKIN_PIP_PYTHON_INSTALL_DIR@/easy-install.pth" ]; then 59 | # # Ref : http://stackoverflow.com/questions/4165135/how-to-use-while-read-bash-to-read-the-last-line-in-a-file-if-there-s-no-new 60 | # while IFS='' read -r DEVEL_PKG_PATH || [ -n "$DEVEL_PKG_PATH" ]; do 61 | # #echo "Inserting $DEVEL_PKG_PATH before "@CATKIN_DEVEL_PREFIX@/@CATKIN_PIP_PYTHON_INSTALL_DIR@" into PYTHONPATH" 62 | # PYTHONPATH=$("@CATKIN_PIP_SCRIPTS_PATH@/path_prepend.sh" "$DEVEL_PKG_PATH" "${PYTHONPATH}" "@CATKIN_DEVEL_PREFIX@/@CATKIN_PIP_PYTHON_INSTALL_DIR@") || ${PYTHONPATH} # to be safe if path_prepend fails 63 | # done <"@CATKIN_DEVEL_PREFIX@/@CATKIN_PIP_PYTHON_INSTALL_DIR@/easy-install.pth" 64 | # fi 65 | 66 | 67 | # Exporting is required to make sure we get the new value in children processes (catkin_make, test runs, etc.) 68 | export PYTHONPATH 69 | export PATH 70 | 71 | 72 | # resetting shell options (especially useful if sourced) 73 | set +o nounset 74 | set +o noglob 75 | # set +o errexit # for development only -------------------------------------------------------------------------------- /cmake/nosetests.cmake.in: -------------------------------------------------------------------------------- 1 | _generate_function_if_testing_is_disabled("catkin_add_nosetests") 2 | 3 | # 4 | # Add Python nose tests. 5 | # 6 | # Nose collects tests from the directory ``dir`` automatically. 7 | # 8 | # .. note:: The test can be executed by calling ``nosetests`` 9 | # directly or using: 10 | # `` make run_tests_${PROJECT_NAME}_nosetests_${dir}`` 11 | # (where slashes in the ``dir`` are replaced with periods) 12 | # 13 | # :param path: a relative or absolute directory to search for 14 | # nosetests in or a relative or absolute file containing tests 15 | # :type path: string 16 | # :param DEPENDENCIES: the targets which must be built before executing 17 | # the test 18 | # :type DEPENDENCIES: list of strings 19 | # :param TIMEOUT: the timeout for individual tests in seconds 20 | # (default: 60) 21 | # :type TIMEOUT: integer 22 | # :param WORKING_DIRECTORY: the working directory when executing the 23 | # tests (this option can only be used when the ``path`` argument is a 24 | # file but not when it is a directory) 25 | # :type WORKING_DIRECTORY: string 26 | # :param NOSE_OPT: additional options to be used to run pytest, this param 27 | # should be used only if the other ones do not fulfill you requirements to 28 | # properly run your pytests. 29 | # 30 | # @public 31 | # 32 | function(catkin_add_nosetests path) 33 | _warn_if_skip_testing("catkin_add_nosetests") 34 | 35 | if(NOT CATKIN_PIP_NOSETESTS) 36 | message(WARNING "skipping nosetests(${path}) in project '${PROJECT_NAME}'") 37 | return() 38 | endif() 39 | 40 | 41 | cmake_parse_arguments(_nose "" "TIMEOUT;WORKING_DIRECTORY;NOSE_OPT" "DEPENDENCIES" ${ARGN}) 42 | if(NOT _nose_TIMEOUT) 43 | set(_nose_TIMEOUT 60) 44 | endif() 45 | if(NOT _nose_TIMEOUT GREATER 0) 46 | message(FATAL_ERROR "nosetests() TIMEOUT argument must be a valid number of seconds greater than zero") 47 | endif() 48 | 49 | # check that the directory exists 50 | set(_path_name _path_name-NOTFOUND) 51 | if(IS_ABSOLUTE ${path}) 52 | set(_path_name ${path}) 53 | else() 54 | find_file(_path_name ${path} 55 | PATHS ${CMAKE_CURRENT_SOURCE_DIR} 56 | NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) 57 | if(NOT _path_name) 58 | message(FATAL_ERROR "Can't find nosetests path '${path}'") 59 | endif() 60 | endif() 61 | 62 | # check if coverage reports are being requested 63 | if("$ENV{CATKIN_TEST_COVERAGE}" STREQUAL "1") 64 | set(_covarg " --with-coverage") 65 | endif() 66 | 67 | # strip PROJECT_SOURCE_DIR and PROJECT_BINARY_DIR prefix from output_file_name 68 | set(output_file_name ${path}) 69 | _strip_path_prefix(output_file_name "${output_file_name}" "${PROJECT_SOURCE_DIR}") 70 | _strip_path_prefix(output_file_name "${output_file_name}" "${PROJECT_BINARY_DIR}") 71 | if("${output_file_name}" STREQUAL "") 72 | set(output_file_name ".") 73 | endif() 74 | string(REPLACE "/" "." output_file_name ${output_file_name}) 75 | string(REPLACE ":" "." output_file_name ${output_file_name}) 76 | 77 | set(output_path ${CATKIN_TEST_RESULTS_DIR}/${PROJECT_NAME}) 78 | # make --xunit-file argument an absolute path (https://github.com/nose-devs/nose/issues/779) 79 | get_filename_component(output_path "${output_path}" ABSOLUTE) 80 | set(cmd "${CMAKE_COMMAND} -E make_directory ${output_path}") 81 | if(IS_DIRECTORY ${_path_name}) 82 | set(tests "--where=${_path_name}") 83 | else() 84 | set(tests "${_path_name}") 85 | endif() 86 | set(cmd ${cmd} "${CATKIN_ENV} ${CATKIN_PIP_NOSETESTS} -P --process-timeout=${_nose_TIMEOUT} ${tests} ${_nose_NOSE_OPT} --with-xunit --xunit-file=${output_path}/nosetests-${output_file_name}.xml${_covarg}") 87 | catkin_run_tests_target("nosetests" ${output_file_name} "nosetests-${output_file_name}.xml" COMMAND ${cmd} DEPENDENCIES ${_nose_DEPENDENCIES} WORKING_DIRECTORY ${_nose_WORKING_DIRECTORY}) 88 | endfunction() 89 | 90 | # Providing another catkin nosetests usage... 91 | # now we can finally use the simple "nosetests" entry_point (forcing cmake to find it) 92 | find_program(CATKIN_PIP_NOSETESTS NAMES 93 | "nosetests${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}" 94 | "nosetests-${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}" 95 | "nosetests${PYTHON_VERSION_MAJOR}" 96 | "nosetests-${PYTHON_VERSION_MAJOR}" 97 | "nosetests" 98 | PATHS 99 | ${CATKIN_PIP_ENV}/@CATKIN_GLOBAL_BIN_DESTINATION@ 100 | NO_DEFAULT_PATH 101 | ) 102 | if(CATKIN_PIP_NOSETESTS) 103 | message(STATUS "Catkin_pip using Python nosetests: ${CATKIN_PIP_NOSETESTS}") 104 | else() 105 | message(FATAL_ERROR "Catkin_pip nosetests not found in ${CATKIN_DEVEL_PREFIX}/@CATKIN_GLOBAL_BIN_DESTINATION@. Make sure you have installed the nose pip package on your ${CATKIN_DEVEL_PREFIX} workspace.") 106 | endif() 107 | 108 | macro(_strip_path_prefix var value prefix) 109 | if("${value}" STREQUAL "${prefix}" OR "${value}" STREQUAL "${prefix}/") 110 | set(${var} "") 111 | else() 112 | set(${var} "${value}") 113 | string(LENGTH "${prefix}/" prefix_length) 114 | string(LENGTH "${value}" var_length) 115 | if(${var_length} GREATER ${prefix_length}) 116 | string(SUBSTRING "${value}" 0 ${prefix_length} var_prefix) 117 | if("${var_prefix}" STREQUAL "${prefix}/") 118 | # passing length -1 does not work for CMake < 2.8.5 119 | # http://public.kitware.com/Bug/view.php?id=10740 120 | string(LENGTH "${value}" _rest) 121 | math(EXPR _rest "${_rest} - ${prefix_length}") 122 | string(SUBSTRING "${value}" ${prefix_length} ${_rest} ${var}) 123 | endif() 124 | endif() 125 | endif() 126 | endmacro() 127 | -------------------------------------------------------------------------------- /cmake/pytest.cmake.in: -------------------------------------------------------------------------------- 1 | _generate_function_if_testing_is_disabled("catkin_add_pytests") 2 | 3 | # 4 | # Add Python pytest tests. 5 | # 6 | # Nose collects tests from the directory ``dir`` automatically. 7 | # 8 | # .. note:: The test can be executed by calling ``py.test`` 9 | # directly or using: 10 | # `` make run_tests_${PROJECT_NAME}_pytests_${dir}`` 11 | # (where slashes in the ``dir`` are replaced with periods) 12 | # 13 | # :param path: a relative or absolute directory to search for 14 | # pytests in or a relative or absolute file containing tests 15 | # :type path: string 16 | # :param DEPENDENCIES: the targets which must be built before executing 17 | # the test 18 | # :type DEPENDENCIES: list of strings 19 | # :param TIMEOUT: the timeout for individual tests in seconds 20 | # (default: 60) 21 | # :type TIMEOUT: integer 22 | # :param WORKING_DIRECTORY: the working directory when executing the 23 | # tests (this option can only be used when the ``path`` argument is a 24 | # file but not when it is a directory) 25 | # :type WORKING_DIRECTORY: string 26 | # :param PYTEST_OPT: additional options to be used to run pytest, this param 27 | # should be used only if the other ones do not fullfill you requirements to 28 | # properly run your pytests. 29 | # :type PYTEST_OPT: string 30 | # 31 | # @public 32 | # 33 | function(catkin_add_pytests path) 34 | _warn_if_skip_testing("catkin_add_pytests") 35 | 36 | if(NOT CATKIN_PIP_PYTEST) 37 | message(WARNING "skipping pytests(${path}) in project '${PROJECT_NAME}'") 38 | return() 39 | endif() 40 | 41 | cmake_parse_arguments(_pytest "" "TIMEOUT;WORKING_DIRECTORY;PYTEST_OPT" "DEPENDENCIES" ${ARGN}) 42 | if(NOT _pytest_TIMEOUT) 43 | set(_pytest_TIMEOUT 60) 44 | endif() 45 | if(NOT _pytest_TIMEOUT GREATER 0) 46 | message(FATAL_ERROR "py.test() TIMEOUT argument must be a valid number of seconds greater than zero") 47 | endif() 48 | 49 | # check that the directory exists 50 | set(_path_name _path_name-NOTFOUND) 51 | if(IS_ABSOLUTE ${path}) 52 | set(_path_name ${path}) 53 | else() 54 | find_file(_path_name ${path} 55 | PATHS ${CMAKE_CURRENT_SOURCE_DIR} 56 | NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) 57 | if(NOT _path_name) 58 | message(FATAL_ERROR "Can't find pytests path '${path}'") 59 | endif() 60 | endif() 61 | 62 | # check if coverage reports are being requested 63 | if("$ENV{CATKIN_TEST_COVERAGE}" STREQUAL "1") 64 | set(_covarg "--cov-report xml --cov-report annotate --cov=${PROJECT_SOURCE_DIR}") 65 | endif() 66 | 67 | # strip PROJECT_SOURCE_DIR and PROJECT_BINARY_DIR prefix from output_file_name 68 | set(output_file_name ${path}) 69 | _strip_path_prefix(output_file_name "${output_file_name}" "${PROJECT_SOURCE_DIR}") 70 | _strip_path_prefix(output_file_name "${output_file_name}" "${PROJECT_BINARY_DIR}") 71 | if("${output_file_name}" STREQUAL "") 72 | set(output_file_name ".") 73 | endif() 74 | string(REPLACE "/" "." output_file_name ${output_file_name}) 75 | string(REPLACE ":" "." output_file_name ${output_file_name}) 76 | 77 | set(output_path ${CATKIN_TEST_RESULTS_DIR}/${PROJECT_NAME}) 78 | get_filename_component(output_path "${output_path}" ABSOLUTE) 79 | set(cmd "${CMAKE_COMMAND} -E make_directory ${output_path}") 80 | set(tests "${_path_name}") 81 | set(cmd ${cmd} "${CATKIN_ENV} ${CATKIN_PIP_PYTEST} --timeout=${_pytest_TIMEOUT} ${tests} ${_pytest_PYTEST_OPT} --junit-xml ${output_path}/pytests-${output_file_name}.xml ${_covarg}") 82 | catkin_run_tests_target("pytests" ${output_file_name} "pytests-${output_file_name}.xml" COMMAND ${cmd} DEPENDENCIES ${_pytest_DEPENDENCIES} WORKING_DIRECTORY ${_pytest_WORKING_DIRECTORY}) 83 | endfunction() 84 | 85 | # Providing another catkin pytests usage... 86 | # now we can finally use the simple "py.test" entry_point (forcing cmake to find it) 87 | find_program(CATKIN_PIP_PYTEST NAMES 88 | "py.test${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}" 89 | "py.test-${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}" 90 | "py.test${PYTHON_VERSION_MAJOR}" 91 | "py.test-${PYTHON_VERSION_MAJOR}" 92 | "py.test" 93 | PATHS 94 | ${CATKIN_PIP_ENV}/@CATKIN_GLOBAL_BIN_DESTINATION@ 95 | NO_DEFAULT_PATH 96 | ) 97 | if(CATKIN_PIP_PYTEST) 98 | message(STATUS "Catkin_pip using Python py.test: ${CATKIN_PIP_PYTEST}") 99 | else() 100 | message(FATAL_ERROR "Catkin_pip py.test command not found in ${CATKIN_DEVEL_PREFIX}/@CATKIN_GLOBAL_BIN_DESTINATION@. Make sure you have installed the pytest pip package on your ${CATKIN_DEVEL_PREFIX} workspace.") 101 | endif() 102 | -------------------------------------------------------------------------------- /cmake/scripts/path_prepend.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This scripts takes one argument (a path) 4 | # and prepends it to the beginning of the second argument (a ':' separated list of path) 5 | # It returns the new list. 6 | 7 | # lets be safe : Ref : http://www.davidpashley.com/articles/writing-robust-shell-scripts/ 8 | set -o nounset 9 | set -o noglob 10 | # set -o errexit # for development only 11 | # tested with dash on ubuntu trusty 12 | 13 | if [ $# -gt 3 -o $# -lt 1 ]; then 14 | # echo "Usage : path_prepend []" # TMP : we cannot echo anything in the way the script is used 15 | exit 127 # TODO this breaks calling script (with source setup.bash) -> FIX IT 16 | fi 17 | if [ $# -ge 1 ]; then 18 | if [ -z "$1" ]; then # to protect against empty arg 19 | # echo "ERROR: Attempting to prepend an empty argument" # TMP : we cannot echo anything in the way the script is used 20 | exit 63 # TODO this breaks calling script (with source setup.bash) -> FIX IT (easy test by changing -z -> -n) 21 | fi 22 | # The path to insert 23 | ARG="$1" 24 | fi 25 | if [ $# -lt 2 ]; then 26 | LIST="" 27 | else 28 | LIST="$2" 29 | fi 30 | if [ $# -eq 3 ]; then 31 | BEFORE="$3" 32 | fi 33 | 34 | # if PATH is empty 35 | if [ -z "$LIST" ]; then 36 | LIST="$ARG" 37 | else 38 | # we move it from tail to head of paths in PATH list 39 | PATH_LIST=$(echo $LIST | /bin/sed 's/:/\n/g') 40 | LIST="" 41 | for p in $PATH_LIST; do 42 | if [ X"$p" = X"${BEFORE:-}" ]; then 43 | BEFORE_FOUND=1 # to mark we have found BEFORE 44 | [ -z "${LIST:-}" ] && LIST=${ARG} || LIST=${LIST}:${ARG} 45 | #echo $LIST 46 | fi 47 | if [ X$p != X$ARG ]; then 48 | [ -z "${LIST:-}" ] && LIST=${p} || LIST=${LIST}:${p} 49 | #echo $LIST 50 | fi 51 | done 52 | # we prepend ARG here, after we made sure it is not in LIST any longer 53 | if [ -z "${BEFORE:-}" -o -z "${BEFORE_FOUND:-}" ]; then # if there was no before or if it was not found, we put it in front 54 | [ -z "${LIST:-}" ] && LIST="$ARG" || LIST="$ARG":"${LIST}" 55 | fi 56 | fi 57 | 58 | # returning our new PATH 59 | echo $LIST 60 | 61 | 62 | # Testing : 63 | # TODO : detail how to test this and cover all usecases (even if ony manual steps at first) 64 | # Unit testing : http://stackoverflow.com/questions/971945/unit-testing-for-shell-scripts 65 | # 66 | # $ PATHLIST= 67 | # 1. Testing empty path 68 | # $ ./path_prepend.bash test/path $PATHLIST 69 | # => test/path 70 | # $ PATHLIST=test/path 71 | # 2. Testing going to the front 72 | # $ ./path_prepend.bash test/blah $PATHLIST 73 | # => test/blah:test/path 74 | # $ PATHLIST=test/blah:test/path 75 | # 3. Testing going to the front more than once 76 | # $ ./cmake/scripts/path_prepend.bash test/blah $PATHLIST 77 | # => test/blah:test/path 78 | # $ PATHLIST=test/blah:test/path 79 | # 4. Testing inserting 80 | # ./cmake/scripts/path_prepend.bash test/boum $PATHLIST test/path 81 | # => test/blah:test/boum:test/path -------------------------------------------------------------------------------- /cmake/templates/python_setuptools_install.sh.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ -n "$DESTDIR" ] ; then 4 | case $DESTDIR in 5 | /*) # ok 6 | ;; 7 | *) 8 | /bin/echo "DESTDIR argument must be absolute... " 9 | /bin/echo "otherwise python's distutils will bork things." 10 | exit 1 11 | esac 12 | DESTDIR_ARG="--root=$DESTDIR" 13 | # --root implies --single-version-externally-managed (but this option is not recognized by distutils) 14 | # Ref : http://setuptools.readthedocs.io/en/latest/history.html?highlight=root#a11 15 | else 16 | # In this case we need to specify root to install in a way that is compatible with distutils (assumed by ROS), 17 | # and set it to a sensible root value, to work with both setuptools and distutils when installing... 18 | DESTDIR_ARG="--root=/" 19 | fi 20 | 21 | echo_and_run() { echo "+ $@" ; "$@" ; } 22 | 23 | echo_and_run cd "@INSTALL_CMD_WORKING_DIRECTORY@" 24 | 25 | # Ensure that Python install destination exists 26 | # Not needed with latest setuptools ? 27 | #echo_and_run mkdir -p "$DESTDIR@CMAKE_INSTALL_PREFIX@/@PYTHON_INSTALL_DIR@" 28 | 29 | # Verifying setuptools version 30 | echo_and_run /usr/bin/env \ 31 | PYTHONPATH="@CATKIN_PIP_ENV@/@CATKIN_PIP_PYTHON_INSTALL_DIR@:@CMAKE_INSTALL_PREFIX@/@PYTHON_INSTALL_DIR@:@CMAKE_BINARY_DIR@/@PYTHON_INSTALL_DIR@:$PYTHONPATH" \ 32 | python -c "import setuptools; print 'setuptools from {0} version {1}'.format(setuptools.__file__, setuptools.__version__)" 33 | 34 | # Note that PYTHONPATH is pulled from the environment to support installing 35 | # into one location when some dependencies were installed in another 36 | # location, #123. 37 | # One of these locations must be the catkin_pip_env with the latest setuptools version to install packages with recent setuptools. 38 | echo_and_run /usr/bin/env \ 39 | PYTHONPATH="@CATKIN_PIP_ENV@/@CATKIN_PIP_PYTHON_INSTALL_DIR@:@CMAKE_INSTALL_PREFIX@/@PYTHON_INSTALL_DIR@:@CMAKE_BINARY_DIR@/@PYTHON_INSTALL_DIR@:$PYTHONPATH" \ 40 | "@PYTHON_EXECUTABLE@" \ 41 | "@CATKIN_PIP_PACKAGE_PATH@/setup.py" \ 42 | build --build-base "@CMAKE_CURRENT_BINARY_DIR@" \ 43 | install \ 44 | $DESTDIR_ARG \ 45 | @SETUPTOOLS_ARG_EXTRA@ --prefix="@CMAKE_INSTALL_PREFIX@" --install-scripts="@CMAKE_INSTALL_PREFIX@/@CATKIN_GLOBAL_BIN_DESTINATION@" --install-data="@CMAKE_INSTALL_PREFIX@/@CATKIN_GLOBAL_SHARE_DESTINATION@" 46 | -------------------------------------------------------------------------------- /doc/catkin_package.rst: -------------------------------------------------------------------------------- 1 | ============== 2 | Catkin Package 3 | ============== 4 | 5 | Ref : http://wiki.ros.org/ROS/Tutorials/catkin/CreatingPackage 6 | 7 | We are focusing here only in python packages. 8 | We will use the "catkin way of doing things" described here, as a reference when discussing improvements brought with catkin_pip. 9 | 10 | Package Structure 11 | ================= 12 | 13 | This is a generic example inspired by the pure catkin package from the Pyros dependencies : `pyros-test `_ 14 | 15 | 16 | Files hierarchy 17 | --------------- 18 | 19 | 20 | The source file hierarchy is:: 21 | 22 | . 23 | ├── CHANGELOG.rst # A changelog, usually generated from git commit with catkin_generate_changelog 24 | ├── CMakeLists.txt # A CMakeLists, using Catkin macros 25 | ├── doc 26 | │   ├── changelog_link.rst # Documentation link to existing changelog 27 | │   ├── conf.py # Sphinx doc configuration 28 | │   ├── mydocs.rst # Documentation for Sphinx 29 | │   └── readme_link.rst # Documentation link to existing readme 30 | ├── nodes 31 | │   └── node1.py # python script launching a ROS node 32 | ├── scripts 33 | │   └── script1.py # python utility script 34 | ├── package.xml # package.xml required by catkin 35 | ├── README.rst 36 | ├── setup.py # setup.py using distutils and catkin_pkg extension 37 | ├── src 38 | │   └── mypkg # mypkg python package 39 | │   ├── module1.py 40 | │   └── __init__.py 41 | ├── msg 42 | │ └── mymessage.msg # ROS message definition 43 | └── srv 44 | └── myservice.srv # ROS service definition 45 | 46 | 47 | - package.xml looks like :: 48 | 49 | 50 | 51 | mypkg 52 | 0.0.4 53 | 54 | MyPkg description 55 | 56 | 57 | BSD 58 | 59 | https://github.com/author/mypkg 60 | https://github.com/author/mypkg/issues 61 | 62 | Author 63 | Maintainer 64 | 65 | catkin 66 | 67 | rospy 68 | std_msgs 69 | 70 | message_generation 71 | roslint 72 | 73 | message_runtime 74 | 75 | 76 | rostest 77 | rosunit 78 | 79 | 80 | python-catkin-pkg 81 | 82 | 83 | 84 | 85 | 86 | - CMakeLists.txt looks like :: 87 | 88 | cmake_minimum_required(VERSION 2.8.3) 89 | project(mypkg) 90 | 91 | # Minimal Python module setup 92 | find_package(catkin REQUIRED COMPONENTS 93 | roslint 94 | rospy 95 | std_msgs 96 | message_generation 97 | ) 98 | 99 | catkin_python_setup() 100 | 101 | add_message_files(DIRECTORY msg 102 | FILES 103 | mymessage.msg 104 | ) 105 | add_service_files(DIRECTORY srv 106 | FILES 107 | myservice.srv 108 | ) 109 | generate_messages(DEPENDENCIES std_msgs) 110 | 111 | catkin_package( CATKIN_DEPENDS message_runtime std_msgs) 112 | 113 | install( 114 | PROGRAMS 115 | nodes/node1.py 116 | DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} 117 | ) 118 | 119 | install( 120 | PROGRAMS 121 | scripts/script1.py 122 | DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} 123 | ) 124 | 125 | # Lint Python modules 126 | file(GLOB_RECURSE ${PROJECT_NAME}_PY_SRCS 127 | RELATIVE ${PROJECT_SOURCE_DIR} src/pyros_test/*.py) 128 | roslint_python(${${PROJECT_NAME}_PY_SRCS}) 129 | 130 | 131 | - setup.py looks like:: 132 | 133 | from distutils.core import setup 134 | from catkin_pkg.python_setup import generate_distutils_setup 135 | 136 | # ROS PACKAGING 137 | # using distutils : https://docs.python.org/2/distutils 138 | # fetch values from package.xml 139 | setup_args = generate_distutils_setup( 140 | packages=[ 141 | 'mypkg', 142 | ], 143 | package_dir={ 144 | 'mypkg': 'src/mypkg', 145 | } 146 | ) 147 | setup(**setup_args) 148 | 149 | 150 | Dependencies 151 | ------------ 152 | 153 | Dependencies are expressed via rosdep keys in the package.xml file. 154 | 155 | Note these rosdep keys can refer to pip packages (check the rosdistro repository, you will find pip keys) but AFAIK: 156 | 157 | - there are no guarantees that these pip packages will play nice along the rest of your ROS distro. 158 | - there are little information on how rosdep handle pip dependencies (version requirements ?) 159 | - there is no clear visibility on rosdep pip support in the long term. 160 | 161 | If you think I am mistaken please open an issue on catkin_pip repository, and share the information you have regarding these topics. 162 | 163 | 164 | Package Development Workflow 165 | ============================ 166 | 167 | This is a description of the generic ROS catkin workflow to retrieve, develop, build, test and release a catkin-based package. 168 | We will use pyros-test project as an example. 169 | **TODO : travis check these with doctest + running these in isolation in container** 170 | 171 | - Retrieve the project:: 172 | 173 | $ mkdir -p catkin_ws/src 174 | $ cd catkin_ws/src/ 175 | $ wstool init 176 | Writing /home/alexv/doctest/catkin_ws/src/.rosinstall 177 | 178 | update complete. 179 | 180 | $ wstool set pyros-test https://github.com/asmodehn/pyros-test.git --git 181 | 182 | Add new elements: 183 | pyros-test git https://github.com/asmodehn/pyros-test.git 184 | 185 | Continue: (y)es, (n)o: y 186 | Overwriting /home/alexv/doctest/catkin_ws/src/.rosinstall 187 | Config changed, remember to run 'wstool update pyros-test' to update the folder from git 188 | 189 | $ wstool update pyros-test 190 | [pyros-test] Fetching https://github.com/asmodehn/pyros-test.git (version None) to /home/alexv/doctest/catkin_ws/src/pyros-test 191 | Cloning into '/home/alexv/doctest/catkin_ws/src/pyros-test'... 192 | remote: Counting objects: 87, done. 193 | remote: Total 87 (delta 0), reused 0 (delta 0), pack-reused 87 194 | Unpacking objects: 100% (87/87), done. 195 | Checking connectivity... done. 196 | [pyros-test] Done. 197 | 198 | 199 | - Source your ROS environment:: 200 | 201 | $ source /opt/ros/indigo/setup.bash 202 | 203 | - Build with catkin_make:: 204 | 205 | $ catkin_make 206 | Base path: /home/alexv/doctest/catkin_ws 207 | Source space: /home/alexv/doctest/catkin_ws/src 208 | Build space: /home/alexv/doctest/catkin_ws/build 209 | Devel space: /home/alexv/doctest/catkin_ws/devel 210 | Install space: /home/alexv/doctest/catkin_ws/install 211 | Creating symlink "/home/alexv/doctest/catkin_ws/src/CMakeLists.txt" pointing to "/opt/ros/indigo/share/catkin/cmake/toplevel.cmake" 212 | #### 213 | #### Running command: "cmake /home/alexv/doctest/catkin_ws/src -DCATKIN_DEVEL_PREFIX=/home/alexv/doctest/catkin_ws/devel -DCMAKE_INSTALL_PREFIX=/home/alexv/doctest/catkin_ws/install -G Unix Makefiles" in "/home/alexv/doctest/catkin_ws/build" 214 | #### 215 | -- The C compiler identification is GNU 4.8.4 216 | -- The CXX compiler identification is GNU 4.8.4 217 | -- Check for working C compiler: /usr/bin/cc 218 | -- Check for working C compiler: /usr/bin/cc -- works 219 | -- Detecting C compiler ABI info 220 | -- Detecting C compiler ABI info - done 221 | -- Check for working CXX compiler: /usr/bin/c++ 222 | -- Check for working CXX compiler: /usr/bin/c++ -- works 223 | -- Detecting CXX compiler ABI info 224 | -- Detecting CXX compiler ABI info - done 225 | -- Using CATKIN_DEVEL_PREFIX: /home/alexv/doctest/catkin_ws/devel 226 | -- Using CMAKE_PREFIX_PATH: /opt/ros/indigo 227 | -- This workspace overlays: /opt/ros/indigo 228 | -- Found PythonInterp: /usr/bin/python (found version "2.7.6") 229 | -- Using PYTHON_EXECUTABLE: /usr/bin/python 230 | -- Using Debian Python package layout 231 | -- Using empy: /usr/bin/empy 232 | -- Using CATKIN_ENABLE_TESTING: ON 233 | -- Call enable_testing() 234 | -- Using CATKIN_TEST_RESULTS_DIR: /home/alexv/doctest/catkin_ws/build/test_results 235 | -- Looking for include file pthread.h 236 | -- Looking for include file pthread.h - found 237 | -- Looking for pthread_create 238 | -- Looking for pthread_create - not found 239 | -- Looking for pthread_create in pthreads 240 | -- Looking for pthread_create in pthreads - not found 241 | -- Looking for pthread_create in pthread 242 | -- Looking for pthread_create in pthread - found 243 | -- Found Threads: TRUE 244 | -- Found gtest sources under '/usr/src/gtest': gtests will be built 245 | -- Using Python nosetests: /usr/bin/nosetests-2.7 246 | -- catkin 0.6.18 247 | -- BUILD_SHARED_LIBS is on 248 | -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 249 | -- ~~ traversing 1 packages in topological order: 250 | -- ~~ - pyros_test 251 | -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 252 | -- +++ processing catkin package: 'pyros_test' 253 | -- ==> add_subdirectory(pyros-test) 254 | -- Using these message generators: gencpp;genlisp;genpy 255 | -- pyros_test: 0 messages, 1 services 256 | -- Configuring done 257 | -- Generating done 258 | -- Build files have been written to: /home/alexv/doctest/catkin_ws/build 259 | #### 260 | #### Running command: "make -j8 -l8" in "/home/alexv/doctest/catkin_ws/build" 261 | #### 262 | Scanning dependencies of target std_msgs_generate_messages_cpp 263 | Scanning dependencies of target std_msgs_generate_messages_py 264 | Scanning dependencies of target _pyros_test_generate_messages_check_deps_StringEchoService 265 | Scanning dependencies of target std_msgs_generate_messages_lisp 266 | [ 0%] [ 0%] Built target std_msgs_generate_messages_cpp 267 | [ 0%] Built target std_msgs_generate_messages_py 268 | Built target std_msgs_generate_messages_lisp 269 | [ 0%] Built target _pyros_test_generate_messages_check_deps_StringEchoService 270 | Scanning dependencies of target pyros_test_generate_messages_cpp 271 | Scanning dependencies of target pyros_test_generate_messages_lisp 272 | Scanning dependencies of target pyros_test_generate_messages_py 273 | [ 75%] [ 75%] [ 75%] Generating Lisp code from pyros_test/StringEchoService.srv 274 | Generating C++ code from pyros_test/StringEchoService.srv 275 | Generating Python code from SRV pyros_test/StringEchoService 276 | [100%] Generating Python srv __init__.py for pyros_test 277 | [100%] Built target pyros_test_generate_messages_lisp 278 | [100%] Built target pyros_test_generate_messages_py 279 | [100%] Built target pyros_test_generate_messages_cpp 280 | Scanning dependencies of target pyros_test_generate_messages 281 | [100%] Built target pyros_test_generate_messages 282 | 283 | 284 | 285 | 286 | - Source devel space:: 287 | 288 | $ source devel/setup.bash 289 | 290 | 291 | - Run tests with catkin_make test:: 292 | 293 | $ catkin_make test 294 | Base path: /home/alexv/doctest/catkin_ws 295 | Source space: /home/alexv/doctest/catkin_ws/src 296 | Build space: /home/alexv/doctest/catkin_ws/build 297 | Devel space: /home/alexv/doctest/catkin_ws/devel 298 | Install space: /home/alexv/doctest/catkin_ws/install 299 | #### 300 | #### Running command: "make cmake_check_build_system" in "/home/alexv/doctest/catkin_ws/build" 301 | #### 302 | #### 303 | #### Running command: "make test -j8 -l8" in "/home/alexv/doctest/catkin_ws/build" 304 | #### 305 | Running tests... 306 | Test project /home/alexv/doctest/catkin_ws/build 307 | No tests were found!!! 308 | 309 | 310 | - Debug tests with catkin_make run_tests:: 311 | 312 | $ catkin_make run_tests 313 | Base path: /home/alexv/doctest/catkin_ws 314 | Source space: /home/alexv/doctest/catkin_ws/src 315 | Build space: /home/alexv/doctest/catkin_ws/build 316 | Devel space: /home/alexv/doctest/catkin_ws/devel 317 | Install space: /home/alexv/doctest/catkin_ws/install 318 | #### 319 | #### Running command: "make cmake_check_build_system" in "/home/alexv/doctest/catkin_ws/build" 320 | #### 321 | #### 322 | #### Running command: "make run_tests -j8 -l8" in "/home/alexv/doctest/catkin_ws/build" 323 | #### 324 | Scanning dependencies of target run_tests 325 | Built target run_tests 326 | 327 | 328 | 329 | From a different shell to not have your environment polluted with devel space: 330 | 331 | 332 | - Source your ROS environment:: 333 | 334 | $ source /opt/ros/indigo/setup.bash 335 | 336 | - Install with catkin_make install:: 337 | 338 | $ catkin_make install 339 | Base path: /home/alexv/doctest/catkin_ws 340 | Source space: /home/alexv/doctest/catkin_ws/src 341 | Build space: /home/alexv/doctest/catkin_ws/build 342 | Devel space: /home/alexv/doctest/catkin_ws/devel 343 | Install space: /home/alexv/doctest/catkin_ws/install 344 | #### 345 | #### Running command: "make cmake_check_build_system" in "/home/alexv/doctest/catkin_ws/build" 346 | #### 347 | #### 348 | #### Running command: "make install -j8 -l8" in "/home/alexv/doctest/catkin_ws/build" 349 | #### 350 | [ 0%] [ 0%] [ 0%] Built target std_msgs_generate_messages_lisp 351 | Built target std_msgs_generate_messages_py 352 | Built target std_msgs_generate_messages_cpp 353 | [ 0%] Built target _pyros_test_generate_messages_check_deps_StringEchoService 354 | [100%] [100%] [100%] Built target pyros_test_generate_messages_lisp 355 | Built target pyros_test_generate_messages_cpp 356 | Built target pyros_test_generate_messages_py 357 | [100%] Built target pyros_test_generate_messages 358 | Install the project... 359 | -- Install configuration: "" 360 | -- Installing: /home/alexv/doctest/catkin_ws/install/_setup_util.py 361 | -- Installing: /home/alexv/doctest/catkin_ws/install/env.sh 362 | -- Installing: /home/alexv/doctest/catkin_ws/install/setup.bash 363 | -- Installing: /home/alexv/doctest/catkin_ws/install/setup.sh 364 | -- Installing: /home/alexv/doctest/catkin_ws/install/setup.zsh 365 | -- Installing: /home/alexv/doctest/catkin_ws/install/.rosinstall 366 | + cd /home/alexv/doctest/catkin_ws/src/pyros-test 367 | + mkdir -p /home/alexv/doctest/catkin_ws/install/lib/python2.7/dist-packages 368 | + /usr/bin/env PYTHONPATH=/home/alexv/doctest/catkin_ws/install/lib/python2.7/dist-packages:/home/alexv/doctest/catkin_ws/build/lib/python2.7/dist-packages:/opt/ros/indigo/lib/python2.7/dist-packages CATKIN_BINARY_DIR=/home/alexv/doctest/catkin_ws/build /usr/bin/python /home/alexv/doctest/catkin_ws/src/pyros-test/setup.py build --build-base /home/alexv/doctest/catkin_ws/build/pyros-test install --install-layout=deb --prefix=/home/alexv/doctest/catkin_ws/install --install-scripts=/home/alexv/doctest/catkin_ws/install/bin 369 | running build 370 | running build_py 371 | creating /home/alexv/doctest/catkin_ws/build/pyros-test/lib.linux-x86_64-2.7 372 | creating /home/alexv/doctest/catkin_ws/build/pyros-test/lib.linux-x86_64-2.7/pyros_test 373 | copying src/pyros_test/echo_node.py -> /home/alexv/doctest/catkin_ws/build/pyros-test/lib.linux-x86_64-2.7/pyros_test 374 | copying src/pyros_test/__init__.py -> /home/alexv/doctest/catkin_ws/build/pyros-test/lib.linux-x86_64-2.7/pyros_test 375 | running install 376 | running install_lib 377 | creating /home/alexv/doctest/catkin_ws/install/lib/python2.7/dist-packages/pyros_test 378 | copying /home/alexv/doctest/catkin_ws/build/pyros-test/lib.linux-x86_64-2.7/pyros_test/echo_node.py -> /home/alexv/doctest/catkin_ws/install/lib/python2.7/dist-packages/pyros_test 379 | copying /home/alexv/doctest/catkin_ws/build/pyros-test/lib.linux-x86_64-2.7/pyros_test/__init__.py -> /home/alexv/doctest/catkin_ws/install/lib/python2.7/dist-packages/pyros_test 380 | byte-compiling /home/alexv/doctest/catkin_ws/install/lib/python2.7/dist-packages/pyros_test/echo_node.py to echo_node.pyc 381 | byte-compiling /home/alexv/doctest/catkin_ws/install/lib/python2.7/dist-packages/pyros_test/__init__.py to __init__.pyc 382 | running install_egg_info 383 | Writing /home/alexv/doctest/catkin_ws/install/lib/python2.7/dist-packages/pyros_test-0.0.4.egg-info 384 | -- Installing: /home/alexv/doctest/catkin_ws/install/share/pyros_test/srv/StringEchoService.srv 385 | -- Installing: /home/alexv/doctest/catkin_ws/install/share/pyros_test/cmake/pyros_test-msg-paths.cmake 386 | -- Installing: /home/alexv/doctest/catkin_ws/install/include/pyros_test 387 | -- Installing: /home/alexv/doctest/catkin_ws/install/include/pyros_test/StringEchoServiceResponse.h 388 | -- Installing: /home/alexv/doctest/catkin_ws/install/include/pyros_test/StringEchoServiceRequest.h 389 | -- Installing: /home/alexv/doctest/catkin_ws/install/include/pyros_test/StringEchoService.h 390 | -- Installing: /home/alexv/doctest/catkin_ws/install/share/common-lisp/ros/pyros_test 391 | -- Installing: /home/alexv/doctest/catkin_ws/install/share/common-lisp/ros/pyros_test/srv 392 | -- Installing: /home/alexv/doctest/catkin_ws/install/share/common-lisp/ros/pyros_test/srv/_package.lisp 393 | -- Installing: /home/alexv/doctest/catkin_ws/install/share/common-lisp/ros/pyros_test/srv/pyros_test-srv.asd 394 | -- Installing: /home/alexv/doctest/catkin_ws/install/share/common-lisp/ros/pyros_test/srv/StringEchoService.lisp 395 | -- Installing: /home/alexv/doctest/catkin_ws/install/share/common-lisp/ros/pyros_test/srv/_package_StringEchoService.lisp 396 | Listing /home/alexv/doctest/catkin_ws/devel/lib/python2.7/dist-packages/pyros_test ... 397 | Compiling /home/alexv/doctest/catkin_ws/devel/lib/python2.7/dist-packages/pyros_test/__init__.py ... 398 | Listing /home/alexv/doctest/catkin_ws/devel/lib/python2.7/dist-packages/pyros_test/srv ... 399 | Compiling /home/alexv/doctest/catkin_ws/devel/lib/python2.7/dist-packages/pyros_test/srv/_StringEchoService.py ... 400 | Compiling /home/alexv/doctest/catkin_ws/devel/lib/python2.7/dist-packages/pyros_test/srv/__init__.py ... 401 | -- Installing: /home/alexv/doctest/catkin_ws/install/lib/python2.7/dist-packages/pyros_test 402 | -- Installing: /home/alexv/doctest/catkin_ws/install/lib/python2.7/dist-packages/pyros_test/srv 403 | -- Installing: /home/alexv/doctest/catkin_ws/install/lib/python2.7/dist-packages/pyros_test/srv/_StringEchoService.pyc 404 | -- Installing: /home/alexv/doctest/catkin_ws/install/lib/python2.7/dist-packages/pyros_test/srv/_StringEchoService.py 405 | -- Installing: /home/alexv/doctest/catkin_ws/install/lib/python2.7/dist-packages/pyros_test 406 | -- Installing: /home/alexv/doctest/catkin_ws/install/lib/python2.7/dist-packages/pyros_test/srv 407 | -- Installing: /home/alexv/doctest/catkin_ws/install/lib/python2.7/dist-packages/pyros_test/srv/__init__.pyc 408 | -- Installing: /home/alexv/doctest/catkin_ws/install/lib/python2.7/dist-packages/pyros_test/srv/__init__.py 409 | -- Installing: /home/alexv/doctest/catkin_ws/install/lib/pkgconfig/pyros_test.pc 410 | -- Installing: /home/alexv/doctest/catkin_ws/install/share/pyros_test/cmake/pyros_test-msg-extras.cmake 411 | -- Installing: /home/alexv/doctest/catkin_ws/install/share/pyros_test/cmake/pyros_testConfig.cmake 412 | -- Installing: /home/alexv/doctest/catkin_ws/install/share/pyros_test/cmake/pyros_testConfig-version.cmake 413 | -- Installing: /home/alexv/doctest/catkin_ws/install/share/pyros_test/package.xml 414 | -- Installing: /home/alexv/doctest/catkin_ws/install/lib/pyros_test/echo.py 415 | -- Installing: /home/alexv/doctest/catkin_ws/install/lib/pyros_test/emptyService.py 416 | -- Installing: /home/alexv/doctest/catkin_ws/install/lib/pyros_test/slowService.py 417 | -- Installing: /home/alexv/doctest/catkin_ws/install/lib/pyros_test/triggerService.py 418 | -- Installing: /home/alexv/doctest/catkin_ws/install/lib/pyros_test/common.py 419 | -- Installing: /home/alexv/doctest/catkin_ws/install/lib/pyros_test/string_pub_node.py 420 | -- Installing: /home/alexv/doctest/catkin_ws/install/lib/pyros_test/string_pubnot_node.py 421 | -- Installing: /home/alexv/doctest/catkin_ws/install/lib/pyros_test/string_slow_node.py 422 | -- Installing: /home/alexv/doctest/catkin_ws/install/lib/pyros_test/string_sub_node.py 423 | 424 | 425 | 426 | - Source the install space:: 427 | 428 | $ source install/setup.bash 429 | 430 | 431 | - Run tests as a final user would:: 432 | 433 | **TODO** 434 | 435 | Release 436 | 437 | - Change to the project directory you want to release:: 438 | 439 | $ cd src/pyros-test/ 440 | 441 | - Generate the changelog:: 442 | 443 | $ catkin_generate_changelog 444 | Found packages: pyros_test 445 | Querying commit information since latest tag... 446 | Updating forthcoming section of changelog files... 447 | - updating './CHANGELOG.rst' 448 | Done. 449 | Please review the extracted commit messages and consolidate the changelog entries before committing the files! 450 | 451 | 452 | - Prepare the release:: 453 | 454 | $ catkin_prepare_release 455 | 456 | - bloom-release --rosdistro indigo --track indigo pyros_test 457 | 458 | 459 | 460 | **If this is not accurate, if I missed a step, or if there is a better way to do the same, please open a PullRequest or an issue on the catkin_pip repository with the related information so this doc can be corrected** 461 | 462 | **TODO : review this with the new catkin tools coming up (ie catkin build)** 463 | 464 | 465 | 466 | Continuous Testing Workflow 467 | =========================== 468 | 469 | Because no software works until it has been tested, you should configure travis on your repository to run test with each commit and pull request. 470 | 471 | Catkin testing can be done with a simple `.travis.yml` file and a small shell script. 472 | 473 | 474 | -------------------------------------------------------------------------------- /doc/catkin_pip_notes.rst: -------------------------------------------------------------------------------- 1 | Catkin-Pip Notes 2 | ================ 3 | 4 | This documents gather various notes and detailed issues with Catkin-Pip 5 | 6 | 7 | Python virtualenvs, imports /vs/ ROS workspaces 8 | ----------------------------------------------- 9 | 10 | It is important to keep in mind that the way Python imports works, with or without virtualenv, is not compatible with the way ROS workspaces work. 11 | 12 | Python Virtual envs allow only 2 layers, ie. you cannot overlay a venv on top of another venv : 13 | 14 | - system python 15 | - python in virtualenv 16 | 17 | ROS workspaces allow many layers, by using CMAKE_PREFIX_PATH when building, and relying on the user to do `source setup.sh` before usage : 18 | 19 | - system ROS 20 | - ROS workspace1 21 | - ROS workspace2 22 | - etc. 23 | 24 | Python imports behavior depends on sys.path. This is managed by the python site module. 25 | Python uses PYTHONPATH as a "last measure" of *temporarily* setting a site directory (usually called site-packages or dist-packages on debian), or any path containing python packages and modules. 26 | Python adds a directory to the sys.path only if it exists, and if it is not there yet. 27 | This behavior is relied upon to decide which packages to import and from where (1st PYTHONPATH paths, 2nd any dynamically discovered package (pth files, etc.), 3rd standard python directories on your system) 28 | 29 | ROS uses PYTHONPATH as the "first and only way" to *permanently* (from ROS point of view) set a list of workspaces 30 | The PYTHONPATH is setup to contain the ROS workspaces paths in the appropriate order. 31 | 32 | => Using any python import feature might break this order that ROS relies on to have this workspace hierarchy working properly. 33 | 34 | So the following behavior has been decided for Catkin-Pip : 35 | - Catkin-Pip adds extra site directories to the PYTHONPATH (to make things as obvious as possible for a ROS user) 36 | - Catkin-Pip does NOT do any dynamic discoveries (reading easy-install.pth file to discover editable packages). Better keep things simple and not reimplement a python behavior in a shell script... 37 | Because of this, **it can happen that a package PKG installed in an underlay will be imported before a catkin-pip'ed editable package PKG during development**. 38 | The expected workaround, is to **use pyros_setup in that package**. It will dynamically reset the desired path order in sys.path, following its user-modifiable configuration configuration file. 39 | 40 | More work can be done here, to make things more obvious (like add a field to a catkin-pip'ed package and use pkg_resources on import to find the correct one for example)... -------------------------------------------------------------------------------- /doc/catkin_pip_overview.rst: -------------------------------------------------------------------------------- 1 | Catkin-Pip Overview 2 | =================== 3 | 4 | This document describe the different areas where catkin-pip makes Python ROS development easier. 5 | 6 | 7 | Pip package 8 | ----------- 9 | 10 | Catkin-pip doesnt not change the behavior of a pip package. It just make its use easier in a catkin context. 11 | 12 | Catkin-pip however suppose that the pip package needs to use latest python tools (setuptools, pip, pytest, nose) for manipulating it. 13 | This is in line with python expectation to use latest stable software (and not obsolete system dependencies). 14 | 15 | ROS Package 16 | ----------- 17 | 18 | Catkin-pip doesnt not change the behavior of a ROS package. It just make it easier to build one from a recent python package. 19 | 20 | As ROS packages should only depend on other ros packages, one should be careful to have verified the package still behave as expected when not using pip dependencies before releasing. 21 | 22 | 23 | Devel Space 24 | ----------- 25 | 26 | When used to build a devel space, catkin-pip retrieves it s own dependencies (latest python tools) in the build folder. 27 | It also plug into the cmake flow to trigger pip download of the package dependencies (unless CATKIN_PIP_NO_DEPS is enabled) 28 | 29 | After sourcing the devel space, the catkin-pip python tools are overlayed on top of the system ones, and the package dependencies also overlay the system version of it, if there are any. 30 | this makes it simple to use any version you would like and manage your dependencies with pip, as usual in python workflow. 31 | 32 | With CATKIN_PIP_NO_DEPS enabled, only the catkin-pip python tools are retrieved by pip, and your package needs to rely on the system installed python dependencies. 33 | This is done in order for package developer to be able to slowly migrate from pip version to system version, so that they are eventually able to create a system package from their pip package. 34 | 35 | 36 | Install Space 37 | ------------- 38 | 39 | When used to create an install space, catkin-pip doesnt do anything special, except using the latest setuptools version to create the layout of that system package. 40 | No pip dependencies are ever loaded in that system, so using the install space requires your package to be able to run with system python dependencies, just as running from a system package would do. 41 | 42 | When in that step, one should be careful that tools used to manipulate the package (test, docs) might be at a different version now (system) than in the devel space (catkin-pip version) 43 | 44 | Creating a ROs package from the install space is done as usual, only using a recent version of setuptools. 45 | 46 | 47 | Virtual environments 48 | -------------------- 49 | 50 | Since Catkin-pip allows normal python package to "merge" easily with a ROS package, into what we call a "hybrid" package, one can now choose to use either : 51 | - a ROS package, installed on the system, in the ros environment. 52 | - a pip package, installed on a virtual env, with access to the system packages. 53 | 54 | Note that catkin-pip only solve the "build part" of the problem: 55 | 56 | - To dynamically use the python packages from your catkin workspace when launching a python program outside a ROS environment , you should check pyros-setup. 57 | - To dynamically discover/marshall/serialize messages format from your ROS processes, you should check pyros. 58 | 59 | -------------------------------------------------------------------------------- /doc/catkin_pip_package.rst: -------------------------------------------------------------------------------- 1 | ========================= 2 | Hybrid Catkin-pip Package 3 | ========================= 4 | 5 | Ref : http://wiki.ros.org/ROS/Tutorials/catkin/CreatingPackage 6 | 7 | We are introducing here a hybrid way of working with python packages in catkin environment. 8 | 9 | These Packages are structured to support both catkin workflow and python workflow. 10 | They can be built either from an existing python package, or from an existing catkin package. 11 | 12 | Because of the dynamic nature of python, we do not need to care about message type definition (pyros deals with it dynamically). 13 | So we will not consider these in this document. 14 | 15 | The dependencies of the package can be handled by: 16 | 17 | - pip (using setuptools.setup 'install_requires' parameter and requirements.txt files) 18 | - rosdep (using depend keys in packages.xml). 19 | 20 | This makes it easier to : 21 | 22 | - write ROS python code using recent python habits and dependencies. 23 | - test your package with different version of packages available on pypi. 24 | - specialize an existing python repository to integrate in your ROS development environment. 25 | - generalize a ROS package to a more "high level" "system independent" python package. 26 | 27 | An important limitation here is that this package will only work from source (inside a catkin devel workspace), and cannot be made into a ROS package, until all dependencies are resolvable via rosdep. 28 | This is due to the complexity of managing multiple package managers with different strategies and policies in place. 29 | 30 | However it is perfectly releasable on pypi, just like any python package, provided that all your ROS dependencies are optional. 31 | 32 | An example of the ros/python hybrid workflow is the pyros package : https://github.com/asmodehn/pyros 33 | Having a way to retrieve ros packages from the python install is a long term goal. 34 | 35 | This workflow is usually a transition workflow during the conversion from a python package (usable in source with catkin pip) to a ROS package (deployable via debs). 36 | As such it is important to test both the ROS devel workflow, and the ROS install workflow, separately. pyros has such a setup. 37 | 38 | The catkin devel and install workflow rely on rosdep for depencencies and the multiple pure python workflow rely on pip packages for dependencies. 39 | Therefore great care is needed to support interoparable version of all dependencies in all the different platforms. 40 | 41 | This documents describes a hybrid package. 42 | For the step by step process to convert a python package into a ROS package, follow this documentation . 43 | 44 | 45 | Package Structure 46 | ================= 47 | 48 | This is a generic example inspired by the hybrid catkin-pip package from Pyros : `pyros-test `_ 49 | 50 | 51 | Files hierarchy 52 | --------------- 53 | 54 | 55 | Dependencies 56 | ------------ 57 | 58 | 59 | Package Development Workflow 60 | ============================ 61 | 62 | This is a description of the generic ROS catkin workflow to develop, build, test and release a catkin based package. 63 | We will use this as the reference when implementing catkin_pip improvements 64 | 65 | - Build with catkin_make. this will use pip. 66 | 67 | - Source devel space. this will source extra python environments 68 | 69 | - Run tests with catkin_make test. This will use latest tests frameworks 70 | 71 | - Debug tests with catkin_make run_tests. This will use latest tests frameworks 72 | 73 | From a different shell to not have your environment polluted with devel space: 74 | 75 | - Install with catkin_make install. This will use latest setuptools 76 | 77 | - Source the install space. This will 78 | 79 | - Run tests as a final user would. 80 | 81 | Release 82 | 83 | - catkin_generate_changelog OR gitchangelog 84 | 85 | - catkin_prepare_release OR manual changes (or your own way in setup.py) 86 | 87 | - pypi upload with twine 88 | 89 | - bloom-release --rosdistro indigo --track indigo 90 | 91 | 92 | 93 | Continuous Testing Workflow 94 | =========================== 95 | 96 | Because no software works until it has been tested, you should configure travis on your repository to run test with each commit and pull request. 97 | 98 | Catkin testing can be done with a simple `.travis.yml` file and a small shell script. 99 | One important part is to separate the devel and the install flow to make sure dependencies used in the devel workspace wont affect the install test (which should use hte system dependencies) 100 | 101 | A matrix build can be setup to test behavior in ROS as well as in python virtualenvs. 102 | An example is there https://travis-ci.org/asmodehn/pyros. -------------------------------------------------------------------------------- /doc/changelog_link.rst: -------------------------------------------------------------------------------- 1 | .. include:: ../CHANGELOG.rst 2 | -------------------------------------------------------------------------------- /doc/conf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # catkin_pip documentation build configuration file 4 | # 5 | # This file is execfile()d with the current directory set to its 6 | # containing dir. 7 | # 8 | # Note that not all possible configuration values are present in this 9 | # autogenerated file. 10 | # 11 | # All configuration values have a default; values that are commented out 12 | # serve to show the default. 13 | 14 | # If extensions (or modules to document with autodoc) are in another directory, 15 | # add these directories to sys.path here. If the directory is relative to the 16 | # documentation root, use os.path.abspath to make it absolute, like shown here. 17 | 18 | ## get catkin package information 19 | import catkin_sphinx 20 | import os 21 | import catkin_pkg.package 22 | catkin_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 23 | catkin_package = catkin_pkg.package.parse_package( 24 | os.path.join(catkin_dir, catkin_pkg.package.PACKAGE_MANIFEST_FILENAME)) 25 | 26 | # -- General configuration --------------------------------------------------- 27 | 28 | # If your documentation needs a minimal Sphinx version, state it here. 29 | #needs_sphinx = '1.0' 30 | 31 | # Add any Sphinx extension module names here, as strings. They can be 32 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 33 | # ones. 34 | extensions = ['sphinx.ext.ifconfig', 'sphinx.ext.todo', 'sphinx.ext.graphviz', 35 | 'sphinx.ext.intersphinx', 36 | # 'catkin_sphinx.ShLexer', 'catkin_sphinx.cmake', # disabling because of build problems on readthedocs 37 | 'sphinx.ext.autodoc', 'sphinx.ext.viewcode'] 38 | 39 | 40 | # List automatically-documented module members in source code order. 41 | autodoc_member_order = 'bysource' 42 | 43 | # Add any paths that contain templates here, relative to this directory. 44 | templates_path = ['_templates'] 45 | 46 | # The suffix of source filenames. 47 | source_suffix = '.rst' 48 | 49 | # The encoding of source files. 50 | #source_encoding = 'utf-8-sig' 51 | 52 | # The master toctree document. 53 | master_doc = 'index' 54 | 55 | # General information about the project. 56 | project = u'catkin_pip' 57 | copyright = u'2015, 2016 AlexV' 58 | 59 | # The version info for the project you're documenting, acts as replacement for 60 | # |version| and |release|, also used in various other places throughout the 61 | # built documents. 62 | # 63 | # The short X.Y version. 64 | version = catkin_package.version 65 | # The full version, including alpha/beta/rc tags. 66 | release = catkin_package.version 67 | 68 | # The language for content autogenerated by Sphinx. Refer to documentation 69 | # for a list of supported languages. 70 | #language = None 71 | 72 | # There are two options for replacing |today|: either, you set today to some 73 | # non-false value, then it is used: 74 | #today = '' 75 | # Else, today_fmt is used as the format for a strftime call. 76 | #today_fmt = '%B %d, %Y' 77 | 78 | # List of patterns, relative to source directory, that match files and 79 | # directories to ignore when looking for source files. 80 | exclude_patterns = ['**/.git', 'testbuild/**', 'test/**', 'weblinks.rst'] 81 | 82 | # The reST default role (used for this markup: `text`) to use for all 83 | #documents. default_role = None 84 | 85 | # If true, '()' will be appended to :func: etc. cross-reference text. 86 | #add_function_parentheses = True 87 | 88 | # If true, the current module name will be prepended to all description 89 | # unit titles (such as .. function::). 90 | #add_module_names = True 91 | 92 | # If true, sectionauthor and moduleauthor directives will be shown in the 93 | # output. They are ignored by default. 94 | #show_authors = False 95 | 96 | # The name of the Pygments (syntax highlighting) style to use. 97 | pygments_style = 'sphinx' 98 | 99 | # A list of ignored prefixes for module index sorting. 100 | #modindex_common_prefix = [] 101 | 102 | 103 | # -- Options for HTML output ----------------------------------------------- 104 | 105 | # The theme to use for HTML and HTML Help pages. See the documentation for 106 | # a list of builtin themes. 107 | html_theme = 'nature' 108 | 109 | # Theme options are theme-specific and customize the look and feel of a theme 110 | # further. For a list of options available for each theme, see the 111 | # documentation. 112 | #html_theme_options = {} 113 | 114 | # Add any paths that contain custom themes here, relative to this directory. 115 | #html_theme_path = [] 116 | 117 | # The name for this set of Sphinx documents. If None, it defaults to 118 | # " v documentation". 119 | #html_title = None 120 | 121 | # A shorter title for the navigation bar. Default is the same as html_title. 122 | #html_short_title = None 123 | 124 | # The name of an image file (relative to this directory) to place at the top 125 | # of the sidebar. 126 | #html_logo = None 127 | 128 | # The name of an image file (within the static path) to use as favicon of the 129 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 130 | # pixels large. 131 | #html_favicon = None 132 | 133 | # Add any paths that contain custom static files (such as style sheets) here, 134 | # relative to this directory. They are copied after the builtin static files, 135 | # so a file named "default.css" will overwrite the builtin "default.css". 136 | #html_static_path = ['_static'] 137 | 138 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, 139 | # using the given strftime format. 140 | #html_last_updated_fmt = '%b %d, %Y' 141 | 142 | # If true, SmartyPants will be used to convert quotes and dashes to 143 | # typographically correct entities. 144 | #html_use_smartypants = True 145 | 146 | # Custom sidebar templates, maps document names to template names. 147 | #html_sidebars = {} 148 | 149 | # Additional templates that should be rendered to pages, maps page names to 150 | # template names. 151 | #html_additional_pages = {} 152 | 153 | # If false, no module index is generated. 154 | #html_domain_indices = True 155 | 156 | # If false, no index is generated. 157 | #html_use_index = True 158 | 159 | # If true, the index is split into individual pages for each letter. 160 | #html_split_index = False 161 | 162 | # If true, links to the reST sources are added to the pages. 163 | #html_show_sourcelink = True 164 | 165 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. 166 | #html_show_sphinx = True 167 | 168 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. 169 | #html_show_copyright = True 170 | 171 | # If true, an OpenSearch description file will be output, and all pages will 172 | # contain a tag referring to it. The value of this option must be the 173 | # base URL from which the finished HTML is served. 174 | #html_use_opensearch = '' 175 | 176 | # This is the file name suffix for HTML files (e.g. ".xhtml"). 177 | #html_file_suffix = None 178 | 179 | # Output file base name for HTML help builder. 180 | htmlhelp_basename = 'catkin_pip_pydoc' 181 | 182 | 183 | # -- Options for LaTeX output ------------------------------------------------ 184 | 185 | latex_elements = { 186 | # The paper size ('letterpaper' or 'a4paper'). 187 | #'papersize': 'letterpaper', 188 | 189 | # The font size ('10pt', '11pt' or '12pt'). 190 | #'pointsize': '10pt', 191 | 192 | # Additional stuff for the LaTeX preamble. 193 | #'preamble': '', 194 | } 195 | 196 | # Grouping the document tree into LaTeX files. List of tuples (source 197 | # start file, target name, title, author, documentclass 198 | # [howto/manual]). 199 | latex_documents = [ 200 | ('index', 'catkin_pip.tex', 201 | u'Catkin-Pip.', 202 | u'AlexV', 'manual'), 203 | ] 204 | 205 | # The name of an image file (relative to this directory) to place at the top of 206 | # the title page. 207 | #latex_logo = None 208 | 209 | # For "manual" documents, if this is true, then toplevel headings are parts, 210 | # not chapters. 211 | #latex_use_parts = False 212 | 213 | # If true, show page references after internal links. 214 | #latex_show_pagerefs = False 215 | 216 | # If true, show URL addresses after external links. 217 | #latex_show_urls = False 218 | 219 | # Documents to append as an appendix to all manuals. 220 | #latex_appendices = [] 221 | 222 | # If false, no module index is generated. 223 | #latex_domain_indices = True 224 | 225 | 226 | # -- Options for manual page output ------------------------------------------ 227 | 228 | # One entry per manual page. List of tuples 229 | # (source start file, name, description, authors, manual section). 230 | man_pages = [ 231 | ('index', 'catkin_pip', 232 | u'Catkin-Pip', 233 | [u'AlexV'], 1) 234 | ] 235 | 236 | # If true, show URL addresses after external links. 237 | #man_show_urls = False 238 | 239 | 240 | # -- Options for Texinfo output ---------------------------------------------- 241 | 242 | # Grouping the document tree into Texinfo files. List of tuples 243 | # (source start file, target name, title, author, 244 | # dir menu entry, description, category) 245 | texinfo_documents = [ 246 | ('index', 'catkin_pip', 247 | u'Catkin-pip Documentation', 248 | u'AlexV', 'catkin_pip', 'catkin_pip.', 249 | 'Miscellaneous'), 250 | ] 251 | 252 | # Documents to append as an appendix to all manuals. 253 | #texinfo_appendices = [] 254 | 255 | # If false, no module index is generated. 256 | #texinfo_domain_indices = True 257 | 258 | # How to display URL addresses: 'footnote', 'no', or 'inline'. 259 | #texinfo_show_urls = 'footnote' 260 | 261 | 262 | # Example configuration for intersphinx: refer to the Python standard library. 263 | intersphinx_mapping = {'http://docs.python.org/': None} 264 | -------------------------------------------------------------------------------- /doc/doc-requirements.txt: -------------------------------------------------------------------------------- 1 | catkin-pkg 2 | catkin-sphinx -------------------------------------------------------------------------------- /doc/from_catkin_to_python.rst: -------------------------------------------------------------------------------- 1 | ===================== 2 | From Catkin to Python 3 | ===================== 4 | 5 | This document should mirror the from_python_to_catkin document. 6 | 7 | Step 1 : Hybrid Package 8 | ----------------------- 9 | 10 | The goal is to generalize an existing catkin package into a python environment. 11 | However this project is only about build environments. For : 12 | 13 | - a solution to find dependencies at runtime, check pyros_setup 14 | - a solution to discover message type and convert them dynamically, check pyros 15 | 16 | In a catkin devel workspace, you should : 17 | 18 | - edit your CMakeLists.txt to use catkin_pip 19 | - edit your setup.py, in order to use latest setuptools, and not the obsolete distutils required by catkin. Note you can leave the dependencies in package.xml to be resolved by rosdep in this first step. We can deal with that in Step 2. 20 | 21 | You should compare the python package structure and the hybrid package structure to become familiar with the differences. 22 | 23 | Running `catkin_make` will trigger a workflow very similar to the usual catkin workflow. 24 | 25 | This makes it easier to : 26 | 27 | - write a generic setup.py without requiring catkin to parse it. 28 | - integrate recent python habits into catkin workflow. 29 | 30 | An example of the normal catkin package is the pyros_test package : https://github.com/asmodehn/pyros-test 31 | 32 | An example of the basic catkin_pip workflow is the pyros_utils package : https://github.com/asmodehn/pyros-utils 33 | 34 | For more details, you should check our reference python workflow there and compare it with the hybrid workflow there . 35 | 36 | After you successfully build your package with catkin_pip, your dependencies can be handled by pip in the devel workspace, so you can get started with adjusting your dependencies for python. 37 | 38 | Step 2 : Dependencies adjustments 39 | --------------------------------- 40 | 41 | You should refer to the python way of handling dependencies in package_catkin_pip, and start adding your dependencies in requirements.txt or in setup.py. 42 | 43 | This does mean there will be duplicated dependencies in package.xml and in setup.py. 44 | It might be unsuitable in some cases (same versions everywhere), but necessary in some others (different version on different systems), so this is currently the best option. 45 | 46 | Finally you should already be able to create a python package, and even publish it on pypi. Be careful to test it, in order to verify all python dependencies are working. 47 | 48 | For more details about setting up travis tests for a hybrid package, check . 49 | 50 | 51 | Step 3 : Python Enhancements (optional) 52 | --------------------------------------- 53 | 54 | There are multiple ways to improve your package, using recent python tools. 55 | In random order: 56 | 57 | - bump up your dependencies to use more recent version than the ones provided with your system or with ROS. 58 | - use a recent test framework like pytest. 59 | - use tox to test multiple python environment at once. 60 | - use read-the-docs to publish your documentation for all to see. 61 | - upgrade your workflow by using setup.py for preparing a release. 62 | - publish your package on Pypi for all to use. 63 | 64 | 65 | Step 4 : Third Party Package (optional) 66 | --------------------------------------- 67 | 68 | You can work with your current hybrid packge, if : 69 | 70 | - you have write access to the original catkin package repository, you don't mind adding a few files, and you can make the hybrid package structure there. 71 | - you have forked the original catkin package repository, and you are happy to do the maintenance of the versions in ROS versus the versions in pypi. 72 | 73 | However if you don't have write access to the original repository, or you don't want the hassle of maintaining all different versions between the ROS distributions and the python environments, you should consider building a Third Party package. 74 | Ref : http://wiki.ros.org/bloom/Tutorials/ReleaseThirdParty 75 | 76 | It does mean that the source repository will be the python code repository, as the python code should work cross-platform. 77 | What needs to be adjusted is the catkin build to make a ROS system package out of the python package. 78 | This is doable via small patches in the release repository, along with a more "generic code" handling all differences in the environment. 79 | 80 | For more details about this step, you should consult `Build a Third Party package from Hybrid Package`. 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /doc/from_python_to_catkin.rst: -------------------------------------------------------------------------------- 1 | ===================== 2 | From Python to Catkin 3 | ===================== 4 | 5 | This document should mirror the from_catkin_to_python document. 6 | 7 | Step 1 : Hybrid Package for devel 8 | --------------------------------- 9 | 10 | The goal is to integrate an existing python package into a catkin environment. 11 | This is available right away for a devel workspace, you just need to create a CMakeLists.txt using catkin_pip, and a matching package.xml for catkin to detect it. 12 | you should compare the python package structure and the hybrid package structure to become familiar with the differences. 13 | 14 | Running `catkin_make` will trigger a workflow very similar to the usual python workflow. 15 | 16 | This makes it easier to : 17 | 18 | - write a setup.py without requiring catkin to parse it. 19 | - fork an existing python code to integrate into a ROS package, provided that all its dependencies are available via rosdep. 20 | 21 | An example of the normal python package is the pyros_setup package : https://github.com/asmodehn/pyros-setup 22 | 23 | An example of the basic catkin_pip workflow is the pyros_utils package : https://github.com/asmodehn/pyros-utils 24 | 25 | For more details, you should check our reference python workflow there and compare it with the hybrid workflow there . 26 | 27 | Your dependencies are still handled by pip in the devel workspace, so you can get started with using your package in catkin quickly. 28 | 29 | 30 | Step 2 : Dependencies adjustments 31 | --------------------------------- 32 | 33 | Once your existing python package works fine in source, you can adjust your dependencies version to make sure all dependencies can be found on the system, or in ROS packages. 34 | All these dependencies should be resolvable from packages.xml, and installable via `rosdep`. 35 | 36 | This does mean there will be duplicated dependencies in package.xml and in setup.py. 37 | It might be unsuitable in some cases (same versions everywhere), but necessary in some others (different version on different systems), so this is currently the best option. 38 | 39 | Finally you should be able to create a ROS package. Be careful to test it, in order to verify all system dependencies are working. 40 | 41 | For more details about setting up travis tests for a hybrid package, check . 42 | 43 | 44 | Step 3 : Third Party Package (optional) 45 | --------------------------------------- 46 | 47 | You can work with your current hybrid package, if : 48 | 49 | - you have write access to the original python package repository, you don't mind adding a few files, and you can make the hybrid package structure there. 50 | - you have forked the original python package repository, and you are happy to do the maintenance of the versions in python versus the versions in ROS. 51 | 52 | However if you don't have write access to the original repository, or you don't want the hassle of maintaining all different versions between the ROS distributions and the python environments, you should consider building a Third Party package. 53 | Ref : http://wiki.ros.org/bloom/Tutorials/ReleaseThirdParty 54 | 55 | It is useful especially for all the python dependencies you might use in your project, but on which you have no control, except choosing the version you d like to use in you ROS distro. 56 | 57 | 58 | Build a Third Party package from Hybrid Package 59 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 60 | 61 | This is achieved by extracting the files useful only for catkin (CMakeLists.txt, package.xml, rosdoc.yml) from the hybrid package made before, and putting them in the rosrelease repository created by bloom when releasing a ROS package. 62 | 63 | Be aware that now, your source package cannot be built in a catkin workspace, and you should use: 64 | 65 | - The ROS package as a dependency in you parent catkin project, via rosdep (using depend keys in packages.xml) 66 | - The pip package as a dependency in you parent python project, via pip (using setup.py install_requires and requirements.txt) 67 | 68 | This makes it easier to : 69 | 70 | - write a ROS python package using recent python habits and dependencies 71 | - test your package with different version of packages available on pypi in your development environment. 72 | - test the package on multiple python environment from the source repo (using travis or other build providers) 73 | - test the package on multiple ROS distros from the release repo (using travis or other build providers) 74 | - synchronize release on pypi for python users and on ros buildfarm for ros users. 75 | 76 | An example of the ros/python hybrid workflow is the pyzmp package : https://github.com/asmodehn/pyzmp 77 | This is a pure python package, imported into ROS ecosystem as is, in a deb package so other ROS packages can depend on it. 78 | 79 | To check how the release repository itself can be checked with travis to ensure the package tests are still passing when in a ROS environment. 80 | A few examples from the pyros dependencies: 81 | 82 | - https://travis-ci.org/asmodehn/pyros-config-rosrelease 83 | - https://travis-ci.org/asmodehn/pyzmp-rosrelease 84 | 85 | Again, the third party package release is sometime not necessary. If your package doesnt have to be distributed via ROS package system, having a simple pip package is enough. 86 | https://github.com/asmodehn/pyros-setup is an example of this : it is a simple pip package, that is retrieved and used only via pip. 87 | Your package can use it as a dependency to access ROS modules from a python virtual env. 88 | For more user interaction with ROS from pure python, you want to have a look at https://github.com/asmodehn/pyros itself (provided as a pip package and a ROS package) 89 | 90 | 91 | -------------------------------------------------------------------------------- /doc/index.rst: -------------------------------------------------------------------------------- 1 | .. _index: 2 | 3 | Catkin Pip 4 | ========== 5 | 6 | This `ROS`_ package allows using pure python package in ROS Systems, from catkin workspaces. 7 | 8 | It was born from the need to interact with ROs from a pure python environment, along with pyros. 9 | Therefore the multiple workflows enabled by catkin_pip are workflows used by pyros and its dependencies. 10 | 11 | .. include:: weblinks.rst 12 | 13 | 14 | Overview 15 | -------- 16 | 17 | .. toctree:: 18 | :maxdepth: 1 19 | 20 | readme_link 21 | catkin_pip_overview 22 | catkin_pip_notes 23 | changelog_link 24 | 25 | 26 | Packages : Working with Catkin-pip 27 | ---------------------------------- 28 | 29 | Where we describe the different kind of package we can work with, and how catkin-pip makes the transition easier. 30 | 31 | .. toctree:: 32 | :maxdepth: 2 33 | 34 | catkin_package 35 | pip_package 36 | catkin_pip_package 37 | 38 | 39 | Conversion : From python to catkin to python 40 | -------------------------------------------- 41 | 42 | Where we follow a step by step process to convert your existing code to be used in both catkin and python at the same time. 43 | 44 | .. toctree:: 45 | :maxdepth: 2 46 | 47 | from_python_to_catkin 48 | from_catkin_to_python 49 | 50 | 51 | IDE setup 52 | --------- 53 | 54 | .. toctree:: 55 | :maxdepth: 2 56 | 57 | pycharm_setup 58 | 59 | 60 | Indices and tables 61 | ================== 62 | 63 | * :ref:`genindex` 64 | * :ref:`modindex` 65 | -------------------------------------------------------------------------------- /doc/pip_package.rst: -------------------------------------------------------------------------------- 1 | =========== 2 | Pip Package 3 | =========== 4 | 5 | Ref : https://packaging.python.org/ 6 | 7 | There have been historically many ways to package and distribute python code. 8 | While many of these are still usable, we are focusing here on the python packaging authority way to package python code. 9 | 10 | 11 | Package Structure 12 | ================= 13 | 14 | This is a generic example inspired by the pure pip package from Pyros dependencies: `pyros-setup `_ 15 | 16 | 17 | Files hierarchy 18 | --------------- 19 | 20 | 21 | The source file hierarchy is:: 22 | 23 | . 24 | ├── CHANGELOG.rst # A changelog, usually generated from git commit with gitchangelog 25 | ├── doc 26 | │   ├── changelog_link.rst # Documentation link to existing changelog 27 | │   ├── conf.py # Sphinx doc configuration 28 | │   ├── mydocs.rst # Documentation for Sphinx 29 | │   └── readme_link.rst # Documentation link to existing readme 30 | ├── requirements.txt 31 | ├── MANIFEST.in 32 | ├── pyros_setup 33 | │   ├── __init__.py 34 | │   └── module1.py 35 | ├── README.rst 36 | ├── setup.cfg 37 | ├── setup.py 38 | └── tox.ini 39 | 40 | 41 | Dependencies 42 | ------------ 43 | 44 | Dependencies are manage with pip, usually installed in a virtual environment. 45 | 46 | There are two kinds of dependencies : 47 | - The dependencies needed for the installed pacakge to work (in setuptools.setup install_requires parameter) 48 | - The dependencies needed for the developer to work with the package (in requirements.txt) 49 | 50 | For more detail about these, you should refer to : https://packaging.python.org/requirements/ 51 | 52 | 53 | Package Development Workflow 54 | ============================ 55 | 56 | This is a description of the generic python workflow to develop, build, test and release a python based package. 57 | We will use pyros-setup project as an example. 58 | **TODO : travis check these with doctest + running these in isolation in container** 59 | 60 | - Get the Source ie. clone a Repo:: 61 | 62 | $ git clone https://github.com/asmodehn/pyros-setup.git 63 | Cloning into 'pyros-setup'... 64 | remote: Counting objects: 718, done. 65 | remote: Compressing objects: 100% (64/64), done. 66 | remote: Total 718 (delta 29), reused 0 (delta 0), pack-reused 654 67 | Receiving objects: 100% (718/718), 134.89 KiB | 0 bytes/s, done. 68 | Resolving deltas: 100% (433/433), done. 69 | Checking connectivity... done. 70 | 71 | 72 | - Create a virtual environment and activate it (here using virtualenvwrapper). We also want a virtualenvironment that can use the ROS & system packages:: 73 | 74 | $ mkvirtualenv pyros-setup --system-site-packages 75 | New python executable in /home/alexv/.virtualenvs/pyros-setup/bin/python 76 | Installing setuptools, pip, wheel...done. 77 | 78 | 79 | - Install with pip:: 80 | 81 | $ pip install . 82 | Processing /home/alexv/doctest/pyros-setup 83 | Collecting six (from pyros-setup==0.1.2) 84 | /home/alexv/.virtualenvs/pyros-setup/local/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/util/ssl_.py:318: SNIMissingWarning: An HTTPS request has been made, but the SNI (Subject Name Indication) extension to TLS is not available on this platform. This may cause the server to present an incorrect TLS certificate, which can cause validation failures. You can upgrade to a newer version of Python to solve this. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#snimissingwarning. 85 | SNIMissingWarning 86 | /home/alexv/.virtualenvs/pyros-setup/local/lib/python2.7/site-packages/pip/_vendor/requests/packages/urllib3/util/ssl_.py:122: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. You can upgrade to a newer version of Python to solve this. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning. 87 | InsecurePlatformWarning 88 | Using cached six-1.10.0-py2.py3-none-any.whl 89 | Collecting pyros_config>=0.1.2 (from pyros-setup==0.1.2) 90 | Using cached pyros_config-0.1.3-py2-none-any.whl 91 | Collecting pytest>=2.5.1 (from pyros-setup==0.1.2) 92 | Using cached pytest-2.9.2-py2.py3-none-any.whl 93 | Collecting py>=1.4.29 (from pytest>=2.5.1->pyros-setup==0.1.2) 94 | Using cached py-1.4.31-py2.py3-none-any.whl 95 | Building wheels for collected packages: pyros-setup 96 | Running setup.py bdist_wheel for pyros-setup ... done 97 | Stored in directory: /home/alexv/.cache/pip/wheels/39/50/33/ab49df5cef0ef2ce4e23dabd0c9ea5d81f9af131c80d4b2523 98 | Successfully built pyros-setup 99 | Installing collected packages: six, py, pytest, pyros-config, pyros-setup 100 | Successfully installed py-1.4.31 pyros-config-0.1.3 pyros-setup-0.1.2 pytest-2.9.2 six-1.10.0 101 | 102 | 103 | 104 | - Run tests in current environment with nose or pytest. Note that to avoid import conflict, and for tests to pass, you might need to move to a directory where the module is not accessible from current working directory ( https://github.com/asmodehn/pyros-setup/issues/27 ) :: 105 | 106 | $ pyros_setup --pytest 107 | ============================= test session starts ============================== 108 | platform linux2 -- Python 2.7.6, pytest-2.9.2, py-1.4.31, pluggy-0.3.1 109 | rootdir: /home/alexv/doctest/pyros-setup, inifile: 110 | collected 3 items 111 | 112 | .. ... 113 | 114 | =========================== 3 passed in 0.06 seconds =========================== 115 | 116 | 117 | 118 | - Run tests on multiple python environments with tox:: 119 | 120 | $ tox 121 | GLOB sdist-make: /home/alexv/doctest/pyros-setup/setup.py 122 | py27 create: /home/alexv/doctest/pyros-setup/.tox/py27 123 | py27 inst: /home/alexv/doctest/pyros-setup/.tox/dist/pyros_setup-0.1.2.zip 124 | py27 installed: alembic==0.6.2,amqp==1.3.3,ansible==2.1.0.0,anyjson==0.3.3,apt-xapian-index==0.45,argh==0.26.1,args==0.1.0,autopep8==0.9.1,Babel==1.3,backports.ssl-match-hostname==3.5.0.1,beautifulsoup4==4.2.1,billiard==3.3.0.15,binaryornot==0.2.0,blinker==1.3,bloom==0.5.21,bzr==2.1.4,catkin-pkg==0.2.10,catkin-sphinx==0.2.2,catkin-tools==0.4.2,celery==3.1.6,chardet==2.0.1,Cheetah==2.4.4,cl==0.0.3,clint==0.5.1,cobbler==2.4.1,colorama==0.2.5,command-not-found==0.3,configobj==4.7.2,cookiecutter==0.6.4,coverage==3.7.1,debtagshw==0.1,defer==1.0.6,dirspec==13.10,distro-info==0.12,Django==1.6.1,docker-py==1.8.1,dockerpty==0.3.4,docopt==0.6.2,docutils==0.11,dulwich==0.9.4,empy==3.1,enum34==0.9.23,epydoc==3.0.1,fastimport==0.9.2,fig==1.0.1,Flask==0.10.1,futures==2.1.6,gbp==0.6.9,git-remote-helpers==0.1.0,gitchangelog==2.3.0,gunicorn==17.5,html5lib==0.999,httplib2==0.8,importlib==1.0.3,iotop==0.6,ipaddress==1.0.16,itsdangerous==0.22,Jinja2==2.7.2,jsonpickle==0.9.2,keyring==3.5,kitchen==1.1.1,kombu==3.0.7,launchpadlib==1.10.2,lazr.restfulclient==0.13.3,lazr.uri==1.0.3,libvirt-python==1.2.2,lxml==3.3.3,mailer==0.7,Mako==0.9.1,MarkupSafe==0.18,matplotlib==1.3.1,meld3==0.6.10,mercurial==1.4.2,mock==1.0.1,mod-python==3.3.1,MySQL-python==1.2.3,netaddr==0.7.10,netifaces==0.8,nose==1.3.1,numpy==1.8.2,oauth==1.0.1,oauthlib==0.6.1,oneconf==0.3.7.14.4.1,osrf-pycommon==0.1.2,PAM==0.4.2,paramiko==1.10.1,passlib==1.5.3,pathtools==0.1.2,pep8==1.4.6,pexpect==3.1,Pillow==2.3.0,piston-mini-client==0.7.5,pkginfo==1.3.2,pluggy==0.3.1,progressbar==2.3,protobuf==2.5.0,psutil==1.2.1,py==1.4.31,pyasn1==0.1.7,pycrypto==2.6.1,pycups==1.9.66,pycurl==7.19.3,pydot==1.0.28,pyflakes==0.8.1,Pygments==1.6,pygobject==3.12.0,pygpgme==0.3,pygraphviz==1.2,pyinotify==0.9.4,pymongo==2.6.3,PyOpenGL==3.0.2,pyOpenSSL==0.13,pyparsing==2.0.1,pyros-config==0.1.3,pyros-setup==0.1.2,pyserial==2.6,pysmbc==1.0.14.1,pytest==2.9.2,python-apt===0.9.3.5ubuntu2,python-dateutil==1.5,python-debian===0.1.21-nmu2ubuntu2,python-memcached==1.53,pytz==2012rc0,pyxdg==0.25,PyYAML==3.10,pyzmq==14.0.1,redis==2.7.2,reportlab==3.0,requests==2.10.0,requests-toolbelt==0.7.0,roman==2.0.0,ros-buildfarm==1.1.0,rosdep==0.11.5,rosdistro==0.4.7,rospkg==1.0.39,SecretStorage==2.0.0,sessioninstaller==0.0.0,simplejson==3.3.1,six==1.10.0,software-center-aptd-plugins==0.0.0,Sphinx==1.2.2,sphinx-rtd-theme==0.1.7,sphinxcontrib-plantuml==0.6,SQLAlchemy==0.8.4,ssh-import-id==3.21,stevedore==0.14.1,supervisor==3.0b2,termcolor==1.1.0,testfixtures==4.7.0,texttable==0.8.3,tornado==3.1.1,tox==2.3.1,transitions==0.2.7,trollius==2.1,twine==1.8.1,Twisted==13.2.0,Twisted-Conch==13.2.0,Twisted-Core==13.2.0,Twisted-Lore==13.2.0,Twisted-Mail==13.2.0,Twisted-Names==13.2.0,Twisted-News==13.2.0,Twisted-Runner==13.2.0,Twisted-Web==13.2.0,Twisted-Words==13.2.0,urlgrabber==3.9.1,urllib3==1.7.1,vboxapi==1.0,vcstools==0.1.38,virtinst==0.600.4,virtualenv==15.0.2,virtualenv-clone==0.2.4,virtualenvwrapper==4.1.1,VTK==5.8.0,wadllib==1.3.2,watchdog==0.8.3,websocket-client==0.37.0,Werkzeug==0.9.4,wstool==0.1.13,wstools==0.4.3,WTForms==1.0.1,wxPython==2.8.12.1,wxPython-common==2.8.12.1,xdot==0.5,yujin-tools==0.4.24,zenmap==6.40,zope.interface==4.0.5 125 | py27 runtests: PYTHONHASHSEED='473323988' 126 | py27 runtests: commands[0] | py.test --pyargs pyros_setup 127 | WARNING:test command found but not installed in testenv 128 | cmd: /home/alexv/.virtualenvs/pyros-setup/bin/py.test 129 | env: /home/alexv/doctest/pyros-setup/.tox/py27 130 | Maybe you forgot to specify a dependency? See also the whitelist_externals envconfig setting. 131 | ================================================================ test session starts ================================================================ 132 | platform linux2 -- Python 2.7.6, pytest-2.9.2, py-1.4.31, pluggy-0.3.1 133 | rootdir: /home/alexv/doctest/pyros-setup, inifile: 134 | collected 3 items 135 | 136 | pyros_setup/tests/test_setup.py ... 137 | 138 | ============================================================= 3 passed in 0.06 seconds ============================================================== 139 | ___________________________________ summary ____________________________________ 140 | py27: commands succeeded 141 | congratulations :) 142 | 143 | 144 | 145 | - Build a distribution 146 | 147 | - Release on Pypi with twine (you can also code a specific detailed workflow in your setup.py) 148 | 149 | 150 | Continuous Testing Workflow 151 | =========================== 152 | 153 | Because no software works until it has been tested, you should configure travis on your repository to run test with each commit and pull request. 154 | 155 | Catkin testing can be done with a simple `.travis.yml` file and a small shell script. 156 | 157 | A matrix build can be setup to test behavior in multiple python virtualenvs. 158 | Using tox for this is generally a good idea, an example is there . -------------------------------------------------------------------------------- /doc/pycharm_setup.rst: -------------------------------------------------------------------------------- 1 | PyCharm Setup 2 | ============= 3 | 4 | This describe how to setup pycharm to work on your ROS workspace(s) 5 | 6 | Basic ROS workflow 7 | ------------------ 8 | 9 | The environment for your project is not a specific environment per Project/Repository/Package, but rather one environment per Workspace. 10 | => The project for Pycharm is at the workspace level. 11 | 12 | - Basic ROS commands and python commands will work from the terminal, after sourcing the devel space as usual with ROS `source devel/setup.bash` 13 | - Pycharm integrated python tools will work, but only if you have sourced the devel space before launching PyCharm, which might not be convenient in some cases... 14 | 15 | BEWARE : PyCharm (and Python imports ?) have some issues with symlinks, so you should avoid them if possible when setting up your workspace. 16 | 17 | Hybrid workflow 18 | --------------- 19 | 20 | This assumes you are developing ROS packages at the same time as Python packages, in the same workspace. 21 | Both workflow need to be combined in order to develop and test with ROS and simultaneously develop and test with Python. 22 | 23 | - ROS still finds all modules after a `source devel/setup.bash` 24 | - Python (system python) configured in PyCharm will find all modules (from system or from workspaces) using pyros_setup. 25 | This is useful to use all PyCharm tools for python, even without sourcing the environment yourself, pyros_setup will do that for you. 26 | You will need to configure pyros_setup appropriately to describe your environment. 27 | 28 | TODO : check pip requirements to retrieve git clones. 29 | TODO : check working on ROS workspace + independent python projects in same Pycharm window. 30 | 31 | Python workflow (but still using ROS) 32 | ------------------------------------- 33 | 34 | You can work as usual with Python. Pyros_setup will use the configuration provided to setup your ROS environment and be able to import it. -------------------------------------------------------------------------------- /doc/readme_link.rst: -------------------------------------------------------------------------------- 1 | .. include:: ../README.rst 2 | -------------------------------------------------------------------------------- /doc/weblinks.rst: -------------------------------------------------------------------------------- 1 | .. 2 | This file contains a common collection of web links. Include it 3 | wherever these links are needed. 4 | 5 | It is explicitly excluded in ``conf.py``, because it does not 6 | appear anywhere in the TOC tree. 7 | 8 | .. _ROS: http://wiki.ros.org 9 | .. _Pyros: http://github.com/asmodehn/pyros 10 | .. _python.multiprocessing: https://docs.python.org/2/library/multiprocessing.html 11 | .. _python.threading: https://docs.python.org/2/library/threading.html 12 | .. _Entity Component Systems: https://en.wikipedia.org/wiki/Entity_component_system 13 | .. _jsonpickle: https://jsonpickle.github.io/ 14 | .. _imperative: https://en.wikipedia.org/wiki/Imperative_programming 15 | .. _functional: https://en.wikipedia.org/wiki/Functional_programming 16 | .. _Functional programming: https://en.wikipedia.org/wiki/Functional_programming 17 | .. _paradigms: https://en.wikipedia.org/wiki/Programming_paradigm 18 | .. _pickle: https://docs.python.org/2/library/pickle.html 19 | .. _pyzmq: https://pyzmq.readthedocs.org/en/latest/ 20 | .. _stream processing: https://en.wikipedia.org/wiki/Stream_processing 21 | .. _dataflow programming: https://en.wikipedia.org/wiki/Dataflow_programming 22 | .. _REST: https://en.wikipedia.org/wiki/Representational_state_transfer 23 | .. _remote procedure call: https://en.wikipedia.org/wiki/Remote_procedure_call 24 | .. _subroutine: https://en.wikipedia.org/wiki/Subroutine 25 | .. _asynchronous: https://en.wikipedia.org/wiki/Asynchronous_method_invocation 26 | .. _global variables: https://en.wikipedia.org/wiki/Global_variable 27 | .. _raft: https://raft.github.io/ 28 | .. _consensus: https://en.wikipedia.org/wiki/Consensus_(computer_science) 29 | .. _ROS 2: http://design.ros2.org/ 30 | .. _Standing on the shoulder of giants: https://en.wikipedia.org/wiki/Standing_on_the_shoulders_of_giants 31 | .. _Python package: http://python-packaging.readthedocs.org/en/latest/ 32 | .. _me: https://github.com/asmodehn -------------------------------------------------------------------------------- /package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | catkin_pip 4 | 0.2.3 5 | 6 | Catkin macros to allow using pure python packages in usual catkin workspaces with normal python workflow. 7 | 8 | 9 | AlexV 10 | 11 | BSD 12 | 13 | http://github.com/asmodehn/catkin_pip 14 | https://github.com/asmodehn/catkin_pip 15 | https://github.com/asmodehn/catkin_pip/issues 16 | 17 | catkin 18 | 19 | python 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | python-pip 30 | 31 | git 32 | 33 | -------------------------------------------------------------------------------- /rosdoc.yaml: -------------------------------------------------------------------------------- 1 | - builder: sphinx 2 | sphinx_root_dir: doc 3 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.3) 2 | # 3 | # Here we generate a set of python projects with different structures 4 | # and use them as tests for catkin_pip, in same workspace. 5 | # This CMakeLists is just a way to gather all subprojects 6 | # We assume here that the global workspace setup is already done by the parent CMakeLists.txt 7 | # 8 | 9 | find_package(catkin REQUIRED) 10 | 11 | # Setting up catkin-pip from source via symlink 12 | add_subdirectory(catkin_pip) 13 | 14 | # include the extras (as a catkin components / find_package() would normally do) 15 | # Just because we need to install pip requirements here 16 | include(${CATKIN_DEVEL_PREFIX}/share/catkin_pip/cmake/catkin-pip.cmake) 17 | # note : including only the catkin-pip-requirements cmake here will break because some required variables are not set 18 | 19 | # We need to install the common pip dependencies in the workspace being created 20 | # For now we ignore existing platform setup. (might not be best choice ?) 21 | catkin_pip_requirements(${CMAKE_CURRENT_SOURCE_DIR}/test_requirements.txt --ignore-installed) 22 | 23 | message(STATUS "PATH $ENV{PATH}") 24 | message(STATUS "PYTHONPATH $ENV{PYTHONPATH}") 25 | message(STATUS "ROS_PACKAGE_PATH $ENV{ROS_PACKAGE_PATH}") 26 | 27 | # Make sure we get the right cookiecutter 28 | find_program( CATKIN_COOKIECUTTER NAMES cookiecutter PATHS ${CATKIN_DEVEL_PREFIX}/${CATKIN_GLOBAL_BIN_DESTINATION} NO_DEFAULT_PATH) 29 | if( NOT CATKIN_COOKIECUTTER ) 30 | message( FATAL_ERROR "cookiecutter pip command not found. Make sure you have installed the cookiecutter pip package on your workspace.") 31 | else() 32 | message(STATUS "cookiecutter found at ${CATKIN_COOKIECUTTER}") 33 | endif() 34 | 35 | if (NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/pipproject/mypippkg") 36 | catkin_pip_runcmd(${CATKIN_COOKIECUTTER} --no-input https://github.com/wdm0006/cookiecutter-pipproject.git -o pipproject) 37 | endif() 38 | 39 | if (NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/pylibrary/python-nameless") 40 | catkin_pip_runcmd(${CATKIN_COOKIECUTTER} --no-input https://github.com/ionelmc/cookiecutter-pylibrary -o pylibrary) 41 | endif() 42 | 43 | if (NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/pypackage/python_boilerplate") 44 | catkin_pip_runcmd( ${CATKIN_COOKIECUTTER} --no-input https://github.com/audreyr/cookiecutter-pypackage -o pypackage) 45 | endif() 46 | 47 | if (NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/pypackage-minimal/cookiecutter_pypackage_minimal") 48 | catkin_pip_runcmd( ${CATKIN_COOKIECUTTER} --no-input https://github.com/kragniz/cookiecutter-pypackage-minimal -o pypackage-minimal) 49 | endif() 50 | 51 | 52 | # 53 | # and make sure they still work with catkin by building them all as subprojects 54 | # 55 | 56 | # Testing project itself 57 | catkin_pip_runcmd(rosdep install --from-paths "distutils-setup" --ignore-src -y) 58 | add_subdirectory(distutils-setup) 59 | 60 | # Testing project itself 61 | catkin_pip_runcmd(rosdep install --from-paths "setuptools-setup" --ignore-src -y) 62 | add_subdirectory(setuptools-setup) 63 | 64 | # Testing project itself 65 | # We need to call rosdep for each packages (to install dependencies if there are any) 66 | # note $ROS_DISTRO must be already defined in the environment 67 | catkin_pip_runcmd(rosdep install --from-paths "pipproject" --ignore-src -y) 68 | add_subdirectory(pipproject) 69 | 70 | # Testing project itself 71 | catkin_pip_runcmd(rosdep install --from-paths "pylibrary" --ignore-src -y) 72 | add_subdirectory(pylibrary) 73 | 74 | # Testing project itself 75 | catkin_pip_runcmd(rosdep install --from-paths "pypackage" --ignore-src -y) 76 | add_subdirectory(pypackage) 77 | 78 | # Testing project itself 79 | catkin_pip_runcmd(rosdep install --from-paths "pypackage-minimal" --ignore-src -y) 80 | add_subdirectory(pypackage-minimal) 81 | 82 | 83 | if (CATKIN_ENABLE_TESTING) 84 | 85 | ######### 86 | # Pytests 87 | ######### 88 | 89 | # Testing one by one to make sure pyros_setup import 90 | # doesnt influence tests that should not be influenced... 91 | catkin_add_pytests(catkin_pip_pytest/test_easyinstallpth.py 92 | --build-dir ${CMAKE_BINARY_DIR} 93 | DEPENDENCIES 94 | ${distutils_setup_PIP_TARGET} # from distutils-setup 95 | ${setuptools_setup_PIP_TARGET} # from setuptools-setup 96 | ${mypippkg_PIP_TARGET} # from pipproject 97 | ${nameless_PIP_TARGET} # from pylibrary 98 | ${python_boilerplate_PIP_TARGET} # from pypackage 99 | ${cookiecutter_pypackage_minimal_PIP_TARGET} # from pypackage-minimal 100 | ) 101 | catkin_add_pytests(catkin_pip_pytest/test_path.py 102 | --build-dir ${CMAKE_BINARY_DIR} 103 | DEPENDENCIES 104 | ${distutils_setup_PIP_TARGET} # from distutils-setup 105 | ${setuptools_setup_PIP_TARGET} # from setuptools-setup 106 | ${mypippkg_PIP_TARGET} # from pipproject 107 | ${nameless_PIP_TARGET} # from pylibrary 108 | ${python_boilerplate_PIP_TARGET} # from pypackage 109 | ${cookiecutter_pypackage_minimal_PIP_TARGET} # from pypackage-minimal 110 | ) 111 | catkin_add_pytests(catkin_pip_pytest/test_site.py 112 | --build-dir ${CMAKE_BINARY_DIR} 113 | DEPENDENCIES 114 | ${distutils_setup_PIP_TARGET} # from distutils-setup 115 | ${setuptools_setup_PIP_TARGET} # from setuptools-setup 116 | ${mypippkg_PIP_TARGET} # from pipproject 117 | ${nameless_PIP_TARGET} # from pylibrary 118 | ${python_boilerplate_PIP_TARGET} # from pypackage 119 | ${cookiecutter_pypackage_minimal_PIP_TARGET} # from pypackage-minimal 120 | ) 121 | catkin_add_pytests(catkin_pip_pytest/test_import.py 122 | --build-dir ${CMAKE_BINARY_DIR} 123 | DEPENDENCIES 124 | ${distutils_setup_PIP_TARGET} # from distutils-setup 125 | ${setuptools_setup_PIP_TARGET} # from setuptools-setup 126 | ${mypippkg_PIP_TARGET} # from pipproject 127 | ${nameless_PIP_TARGET} # from pylibrary 128 | ${python_boilerplate_PIP_TARGET} # from pypackage 129 | ${cookiecutter_pypackage_minimal_PIP_TARGET} # from pypackage-minimal 130 | ) 131 | catkin_add_pytests(catkin_pip_pytest/test_syspath.py 132 | --build-dir ${CMAKE_BINARY_DIR} 133 | DEPENDENCIES 134 | ${distutils_setup_PIP_TARGET} # from distutils-setup 135 | ${setuptools_setup_PIP_TARGET} # from setuptools-setup 136 | ${mypippkg_PIP_TARGET} # from pipproject 137 | ${nameless_PIP_TARGET} # from pylibrary 138 | ${python_boilerplate_PIP_TARGET} # from pypackage 139 | ${cookiecutter_pypackage_minimal_PIP_TARGET} # from pypackage-minimal 140 | ) 141 | 142 | # Because we need to validate that pyros fixes editable pkg path ordering for us 143 | catkin_add_pytests(catkin_pip_pytest/test_syspath_pyros.py 144 | --capture=no --build-dir ${CMAKE_BINARY_DIR} 145 | DEPENDENCIES 146 | ${distutils_setup_PIP_TARGET} # from distutils-setup 147 | ${setuptools_setup_PIP_TARGET} # from setuptools-setup 148 | ${mypippkg_PIP_TARGET} # from pipproject 149 | ${nameless_PIP_TARGET} # from pylibrary 150 | ${python_boilerplate_PIP_TARGET} # from pypackage 151 | ${cookiecutter_pypackage_minimal_PIP_TARGET} # from pypackage-minimal 152 | ) 153 | 154 | #TODO : a way to verified installed files from cmake ??? 155 | 156 | endif() -------------------------------------------------------------------------------- /test/README.md: -------------------------------------------------------------------------------- 1 | Valdating catkin_pip 2 | ============================ 3 | 4 | This directory aims at gathering tests to validate the behavior of catkin_pip by : 5 | * working with __unmodified__ state of the art python packages 6 | * "building" them (in catkin terminology) 7 | * make sure we can use them (somehow - run tests) 8 | 9 | Project examples to use : 10 | * [cookiecutter-pipproject](https://github.com/wdm0006/cookiecutter-pipproject) 11 | * [cookiecutter-pypackage-minimal](https://github.com/kragniz/cookiecutter-pypackage-minimal) 12 | * [cookiecutter-pypa](https://github.com/audreyr/cookiecutter-pypackage) 13 | * 14 | * TODO : find more python package references 15 | * TODO : add a ros package to prove it doesnt disturb normal ros process either (at least not too much...). 16 | 17 | More tests will be added when we find more use cases that fit catkin_pip purpose 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /test/catkin_pip: -------------------------------------------------------------------------------- 1 | .. -------------------------------------------------------------------------------- /test/catkin_pip_pytest/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyros-dev/catkin_pip/440004356798491d347cc81b809b22968be8741c/test/catkin_pip_pytest/__init__.py -------------------------------------------------------------------------------- /test/catkin_pip_pytest/conftest.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import pytest 4 | 5 | # Imports CANNOT be in fixtues (pytest would cleanup modules, preventing re-import...) 6 | import pyros_setup 7 | 8 | 9 | def pytest_addoption(parser): 10 | parser.addoption("--build-dir", action="store", default="build", help="the build directory") 11 | 12 | 13 | @pytest.fixture 14 | def build_dir(request): 15 | return request.config.getoption("--build-dir") 16 | 17 | 18 | @pytest.fixture 19 | def build_dir(request): 20 | # current dir should be the build directory (binary dir for cmake) 21 | # otherwise cmake tests commands are broken 22 | return os.getcwd() 23 | 24 | 25 | @pytest.fixture 26 | def catkin_pip_env_dir(request): 27 | # lets find catkin_pip_env space in current dir (cwd should be the build directory) 28 | # expected setup.sh 29 | cpe = os.path.join(build_dir(request), 'catkin_pip_env') 30 | return cpe 31 | 32 | 33 | @pytest.fixture 34 | def git_working_tree(request): 35 | 36 | mod_path_split = os.path.abspath(__file__).split(os.sep) 37 | # file should be absolute : we replace the first term 38 | if mod_path_split[0] == '': 39 | mod_path_split[0] = os.sep 40 | #print(mod_path_split) 41 | 42 | last_idx = len(mod_path_split) - 2 43 | #print(mod_path_split[:-last_idx]) 44 | 45 | # lets find the git working tree 46 | while not os.path.exists(os.path.join(*(mod_path_split[:-last_idx] + ['.git']))) and last_idx > 0: 47 | last_idx -= 1 48 | 49 | assert last_idx > 0, "No git working tree found while walking up to {0}".format(os.path.join(*mod_path_split)) 50 | gs = os.path.join(*(mod_path_split[:-last_idx])) 51 | 52 | return gs 53 | 54 | 55 | @pytest.fixture 56 | def devel_space(): 57 | # lets find devel space in current dir (cwd should be the build directory) 58 | # expected setup.sh 59 | assert os.path.exists(os.path.abspath(os.path.join('devel', 'setup.sh'))), "devel/setup.bash not found in {0}".format(os.getcwd()) 60 | ws = os.path.abspath('devel') 61 | return ws 62 | 63 | 64 | @pytest.fixture 65 | def install_space(): 66 | # lets find devel space in current dir (cwd should be the build directory) 67 | # expected setup.sh 68 | assert os.path.exists(os.path.abspath(os.path.join('install', 'setup.sh'))), "install/setup.bash not found in {0}".format(os.getcwd()) 69 | ws = os.path.abspath('install') 70 | return ws 71 | 72 | @pytest.fixture 73 | def pyros(): 74 | # IMPORTANT : Without pyros_setup configuration activated, 75 | # the develop packages are set in sys.path AFTER the site-packages and dist-packages 76 | # This is because of incompatibilities between ROS and python ways of handling PYTHONPATH. 77 | # It is usually not a problem, unless : 78 | # - you are working in a devel space with catkin_pip and expect to use a editable package from there 79 | # - you have the same package installed somewhere else in the PYTHONPATH 80 | # And in that case it might end up being *before* the source dir in sys.path 81 | # 82 | # => Without pyros_setup, the installed version will be preferred 83 | # This is the python (and tools) way of working, since PYTHONPATH purpose is to override file-based setup, 84 | # like editable packages. 85 | # 86 | # => With pyros_setup, the devel version will be preferred 87 | # This is the ROS way of working, since PYTHONPATH order determine the order of folder when looking for a package. 88 | # 89 | # Both will work fine in most cases, but one might want to keep this corner case in mind... 90 | 91 | # TODO : get rid of this. See https://github.com/asmodehn/catkin_pip/issues/106 92 | 93 | print("sys.path before pyros_setup {pyros_setup.__file__} :\n{sys.path}".format(**globals())) 94 | 95 | # We need to pass the proper workspace here 96 | pyros_setup.configurable_import().configure({ 97 | 'WORKSPACES': [ 98 | devel_space() 99 | ], # This should be the same as pytest devel_space fixture 100 | 'DISTRO': pyros_setup.DETECTED_DISTRO, 101 | }).activate() 102 | 103 | # We cannot move pyros_setup outside the fixture (pytest would clean it up and break module imports) 104 | -------------------------------------------------------------------------------- /test/catkin_pip_pytest/test_easyinstallpth.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | from __future__ import print_function 3 | 4 | import os 5 | 6 | 7 | def test_easyinstall_content(devel_space, git_working_tree): 8 | easy_install_pth_path = os.path.join(devel_space, 'lib', 'python2.7', 'site-packages', 'easy-install.pth') 9 | assert os.path.exists(easy_install_pth_path) 10 | with open(easy_install_pth_path) as easy_install_pth: 11 | editable_paths = easy_install_pth.read().splitlines() 12 | print(editable_paths) 13 | for python_pkg in [ 14 | os.path.join('pipproject', 'mypippkg'), 15 | os.path.join('pylibrary', 'python-nameless', 'src'), 16 | os.path.join('pypackage', 'python_boilerplate'), 17 | os.path.join('pypackage-minimal', 'cookiecutter_pypackage_minimal'), 18 | ]: 19 | assert os.path.join(git_working_tree, 'test', python_pkg) in editable_paths, "{0} not in easy-install.pth".format(os.path.join(git_working_tree, 'test', python_pkg)) 20 | 21 | # Note if not in the file, it means it s already in PYTHONPATH : Ref https://github.com/pypa/pip/issues/4261 22 | # Fix this test for it, at least until pip fixes goes in... 23 | -------------------------------------------------------------------------------- /test/catkin_pip_pytest/test_import.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | from __future__ import print_function 3 | 4 | import os 5 | import sys 6 | import importlib 7 | 8 | 9 | # If all package dependencies are in the sys.path, we can import them 10 | def test_dynamic_import_devel_space_pkgs(): 11 | importlib.import_module('click') # dependency from python_boilerplate 12 | 13 | 14 | # If all packages are in the sys.path, we can import them 15 | def test_dynamic_import_devel_pkg(): 16 | importlib.import_module('mypippkg') 17 | importlib.import_module('nameless') 18 | importlib.import_module('python_boilerplate') 19 | importlib.import_module('cookiecutter_pypackage_minimal') 20 | 21 | 22 | # If all catkin_pip dependencies are in the sys.path, we can import them 23 | def test_dynamic_import_catkin_pip_env_pkgs(): 24 | importlib.import_module('setuptools') 25 | importlib.import_module('pip') 26 | importlib.import_module('nose') 27 | importlib.import_module('pytest') 28 | -------------------------------------------------------------------------------- /test/catkin_pip_pytest/test_path.py: -------------------------------------------------------------------------------- 1 | # TODO : verify the position of the catkin_pip_env bin in path 2 | # It has to be before the devel/bin path... -------------------------------------------------------------------------------- /test/catkin_pip_pytest/test_site.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | from __future__ import print_function 3 | 4 | import os 5 | import sys 6 | import site 7 | 8 | 9 | def test_site(): 10 | for p in site.getsitepackages(): 11 | assert p in sys.path, "site packages directory {p} not found in {sys.path}".format(**locals()) 12 | 13 | # TODO : verify that site module behavior (HOW ? API limited,a nd sys.path is taken care of in another test file) 14 | 15 | # TODO : verify that "python -m site" from the shell actually would return something, after sourcing setup.sh => HOW ? 16 | -------------------------------------------------------------------------------- /test/catkin_pip_pytest/test_syspath.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | from __future__ import print_function 3 | 4 | import os 5 | import pytest 6 | import sys 7 | 8 | 9 | """ 10 | This module is a test for catkin_pip. 11 | It is expected to run FROM CMAKE with pytest, from the build directory 12 | Ex : If you ran ./travis_checks.bash that is /home/alexv/Projects/ros_pyros_ws/src/catkin_pip/testbuild 13 | """ 14 | 15 | 16 | def in_sys_path_ordered(*arg_paths): 17 | """ 18 | Checks if arg_paths are listed int he same order as in sys.path 19 | :param arg_paths: the arguments are a list of path 20 | :return: True if all paths appear in sys.path, and in the arguments order. False otherwise. 21 | """ 22 | return all(p in sys.path for p in arg_paths) and \ 23 | all([sys.path.index(p) < sys.path.index(q) for p, q in zip(arg_paths, arg_paths[1:])] 24 | if len(arg_paths) else True) 25 | 26 | 27 | # 28 | # TESTS 29 | # 30 | 31 | def test_catkin_pip_env_dir_in_sys_path(catkin_pip_env_dir): 32 | print(sys.path) 33 | assert in_sys_path_ordered( 34 | os.path.join(catkin_pip_env_dir, 'lib/python2.7/site-packages'), 35 | ), "{site_pkgs} not appearing in sys.path".format( 36 | site_pkgs=os.path.join(catkin_pip_env_dir, 'lib/python2.7/site-packages') 37 | ) 38 | 39 | 40 | def test_devel_site_in_sys_path(devel_space): 41 | print(sys.path) 42 | assert in_sys_path_ordered( 43 | os.path.join(devel_space, 'lib/python2.7/site-packages'), 44 | ), "{site_pkgs} not in sys.path".format( 45 | site_pkgs=os.path.join(devel_space, 'lib/python2.7/site-packages') 46 | ) 47 | 48 | 49 | @pytest.mark.xfail(strict=True, reason="dist-packages does not exist in our example since all packages use catkin_pip") 50 | def test_devel_dist_in_sys_path(devel_space): 51 | print(sys.path) 52 | assert in_sys_path_ordered( 53 | os.path.join(devel_space, 'lib/python2.7/dist-packages'), 54 | ), "{dist_pkgs} in sys.path".format( 55 | dist_pkgs=os.path.join(devel_space, 'lib/python2.7/dist-packages') 56 | ) 57 | 1/0 58 | 59 | 60 | @pytest.mark.xfail(strict=True, reason="dist-packages does not exist in our example since all packages use catkin_pip") 61 | def test_devel_site_before_devel_dist_in_sys_path(devel_space): 62 | print(sys.path) 63 | 64 | # Verifying relative path order 65 | assert in_sys_path_ordered( 66 | os.path.join(devel_space, 'lib/python2.7/site-packages'), 67 | os.path.join(devel_space, 'lib/python2.7/dist-packages'), 68 | ), "{site_pkgs} not appearing before {dist_pkgs} in sys.path".format( 69 | site_pkgs=os.path.join(devel_space, 'lib/python2.7/site-packages'), 70 | dist_pkgs=os.path.join(devel_space, 'lib/python2.7/dist-packages') 71 | ) 72 | 73 | 74 | def test_devel_site_before_catkin_pip_site_in_sys_path(catkin_pip_env_dir, devel_space): 75 | print(sys.path) 76 | assert in_sys_path_ordered( 77 | os.path.join(devel_space, 'lib/python2.7/site-packages'), 78 | os.path.join(catkin_pip_env_dir, 'lib/python2.7/site-packages'), 79 | ), "{site_pkgs} not appearing before {catkin_pkgs} in sys.path".format( 80 | site_pkgs=os.path.join(devel_space, 'lib/python2.7/site-packages'), 81 | catkin_pkgs=os.path.join(catkin_pip_env_dir, 'lib/python2.7/site-packages') 82 | ) 83 | 84 | 85 | @pytest.mark.xfail(strict=True, reason="dist-packages does not exist in our example since all packages use catkin_pip") 86 | def test_devel_dist_before_catkin_pip_site_in_sys_path(catkin_pip_env_dir, devel_space): 87 | print(sys.path) 88 | assert in_sys_path_ordered( 89 | os.path.join(devel_space, 'lib/python2.7/dist-packages'), 90 | os.path.join(catkin_pip_env_dir, 'lib/python2.7/site-packages'), 91 | ), "{dist_pkgs} not appearing before {catkin_pkgs} in sys.path".format( 92 | dist_pkgs=os.path.join(devel_space, 'lib/python2.7/dist-packages'), 93 | catkin_pkgs=os.path.join(catkin_pip_env_dir, 'lib/python2.7/site-packages') 94 | ) 95 | 96 | 97 | @pytest.mark.xfail(strict=True, reason="With usual python and catkin cmake scripts, editable links are added so sys.path after pythonpath.") 98 | def test_sys_path_editable(git_working_tree, devel_space): 99 | print(sys.path) 100 | 101 | def pkg_path_in_sys_path(pkg_path, before=[]): 102 | assert os.path.exists(pkg_path), "{pkg_path} does not exist".format(**locals()) 103 | 104 | # By default the egg-links path are added after the pythonpaths. 105 | # We need opposite behavior for ROS python (due to how devel workspace and underlays work) 106 | # This is handle by both catkin_pip for ROS usage and pyros_setup for python usage. 107 | 108 | assert in_sys_path_ordered(*([pkg_path] + before)),\ 109 | "paths not appearing in sys.path in the expected order : {p}".format(p=([pkg_path] + before)) 110 | 111 | # Verifying the pip editable installed package location is in python path 112 | for python_pkg in [ 113 | os.path.join('pipproject', 'mypippkg'), 114 | os.path.join('pylibrary', 'python-nameless', 'src'), 115 | os.path.join('pypackage', 'python_boilerplate'), 116 | os.path.join('pypackage-minimal', 'cookiecutter_pypackage_minimal'), 117 | ]: 118 | 119 | ss = os.path.join(git_working_tree, 'test', python_pkg) 120 | 121 | pkg_path_in_sys_path(ss, [ 122 | os.path.join(devel_space, 'lib/python2.7/site-packages'), 123 | # os.path.join(devel_space, 'lib/python2.7/dist-packages') # no dist-packages folder since all our examples are using catkin_pip 124 | ]) 125 | -------------------------------------------------------------------------------- /test/catkin_pip_pytest/test_syspath_pyros.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | from __future__ import print_function 3 | 4 | import pytest 5 | import sys 6 | 7 | """ 8 | This module is a test for catkin_pip, with pyros_setup. 9 | It is expected to run DIRECTLY with pytest, from the build directory 10 | Ex : If you ran ./travis_checks.bash that is /home/alexv/Projects/ros_pyros_ws/src/catkin_pip/testbuild 11 | 12 | It is here to make testing/debugging sys.path issues from IDE easier : 13 | - run ./travis_checks 14 | - setup a test target (careful with the working directory) 15 | - run it (and you can debug inside...) 16 | 17 | Note however that this test module is run with catkin_pip tests as well 18 | to make sure pyros_setup fixes our catkin import problems. 19 | """ 20 | 21 | from . import test_syspath 22 | 23 | # 24 | # Tests importing pyros_setup via fixture and automatically setting configuration 25 | # All these should PASS in any case. 26 | # 27 | 28 | 29 | @pytest.mark.xfail(reason="this has no meaning without catkin_pip, since pyros_setup does not rely and has no knowledge of catkin_pip") 30 | def test_catkin_pip_env_dir_in_sys_path(catkin_pip_env_dir): 31 | return test_syspath.test_catkin_pip_env_dir_in_sys_path(catkin_pip_env_dir) 32 | 33 | 34 | def test_devel_site_in_sys_path(pyros, devel_space): 35 | return test_syspath.test_devel_site_in_sys_path(devel_space) 36 | 37 | 38 | # this fails since dist-packages does not exists 39 | @pytest.mark.xfail(reason="dist-packages does not exist in our example since all packages use catkin_pip") 40 | def test_devel_dist_in_sys_path(pyros, devel_space): 41 | return test_syspath.test_devel_dist_in_sys_path(devel_space) 42 | 43 | 44 | # this fails since dist-packages does not exists 45 | @pytest.mark.xfail(strict=True, reason="dist-packages does not exist in our example since all packages use catkin_pip") 46 | def test_devel_site_before_devel_dist_in_sys_path(pyros, devel_space): 47 | return test_syspath.test_devel_site_before_devel_dist_in_sys_path(devel_space) 48 | 49 | 50 | @pytest.mark.xfail(reason="this has no meaning without catkin_pip, since pyros_setup does not rely and has no knowledge of catkin_pip") 51 | def test_devel_site_before_catkin_pip_site_in_sys_path(pyros, catkin_pip_env_dir, devel_space): 52 | return test_syspath.test_devel_site_before_catkin_pip_site_in_sys_path(catkin_pip_env_dir, devel_space) 53 | 54 | 55 | @pytest.mark.xfail(reason="this has no meaning without catkin_pip, since pyros_setup does not rely and has no knowledge of catkin_pip") 56 | def test_devel_dist_before_catkin_pip_site_in_sys_path(pyros, catkin_pip_env_dir, devel_space): 57 | return test_syspath.test_devel_dist_before_catkin_pip_site_in_sys_path(catkin_pip_env_dir, devel_space) 58 | 59 | 60 | # Using Pyros_setup is the only way to get this to work as expected. 61 | # That is getting devel packages in sys.path before ROS workspaces from PYTHONPATH. 62 | def test_sys_path_editable(pyros, git_working_tree, devel_space): 63 | return test_syspath.test_sys_path_editable(git_working_tree, devel_space) 64 | -------------------------------------------------------------------------------- /test/distutils-setup/.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | *.egg-info 3 | -------------------------------------------------------------------------------- /test/distutils-setup/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.12) 2 | project(distutils_setup) 3 | 4 | # This is a full project CMakeLists (in case we call it independently for tests or so) 5 | set (PIP_PROJECT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/distutils_setup) 6 | 7 | find_package(catkin REQUIRED COMPONENTS catkin_pip) 8 | 9 | # This replace catkin_python_setup() 10 | # For devel, this will install all your unsatisfied pip dependencies. 11 | # Upon install, this will bark if some dependencies are not already satisfied (by ROS). 12 | catkin_pip_target(dstest ${PIP_PROJECT_DIR}) 13 | 14 | catkin_package() 15 | 16 | # CAREFUL : all projects for test here will share the same workspace. pip might have conflicts... 17 | 18 | # Testing potential extra files installation 19 | install(FILES extra_installs/bin.txt DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}) 20 | install(FILES extra_installs/etc.txt DESTINATION ${CATKIN_PACKAGE_ETC_DESTINATION}) 21 | install(FILES extra_installs/include.txt DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}) 22 | install(FILES extra_installs/lib.txt DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}) 23 | install(FILES extra_installs/python.txt DESTINATION ${CATKIN_PACKAGE_PYTHON_DESTINATION}) 24 | install(FILES extra_installs/share.txt DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}) 25 | 26 | ## Unit tests 27 | if (CATKIN_ENABLE_TESTING) 28 | catkin_add_nosetests(${PIP_PROJECT_DIR}/test DEPENDENCIES dstest) 29 | catkin_add_pytests(${PIP_PROJECT_DIR}/test DEPENDENCIES dstest) 30 | # Running embedded test from devel space 31 | catkin_add_nosetests(${PIP_PROJECT_DIR}/dstest/test DEPENDENCIES dstest) 32 | endif() 33 | -------------------------------------------------------------------------------- /test/distutils-setup/catkin_pip: -------------------------------------------------------------------------------- 1 | ../catkin_pip -------------------------------------------------------------------------------- /test/distutils-setup/distutils_setup/dstest/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyros-dev/catkin_pip/440004356798491d347cc81b809b22968be8741c/test/distutils-setup/distutils_setup/dstest/__init__.py -------------------------------------------------------------------------------- /test/distutils-setup/distutils_setup/dstest/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyros-dev/catkin_pip/440004356798491d347cc81b809b22968be8741c/test/distutils-setup/distutils_setup/dstest/test/__init__.py -------------------------------------------------------------------------------- /test/distutils-setup/distutils_setup/dstest/test/test_install.py: -------------------------------------------------------------------------------- 1 | import os 2 | import nose 3 | 4 | 5 | def test_nose(): 6 | # making sure we use nose from system package (installed by rosdep) for install tests 7 | if os.environ.get('ROS_FLOW') == 'install': 8 | assert nose.__file__ == '/usr/lib/python2.7/dist-packages/nose/__init__.pyc', nose.__file__ 9 | else: 10 | # and from devel space otherwise (setup as dependency) 11 | assert 'devel/lib/python2.7/site-packages/nose/__init__.pyc' in nose.__file__ 12 | 13 | 14 | def test_content(): 15 | # make sure everything is there 16 | file_abs_path = __file__ 17 | test_pkg_abs_path = os.path.dirname(file_abs_path) 18 | pkg_abs_path = os.path.dirname(test_pkg_abs_path) 19 | assert 'lib/python2.7/site-packages' or 'lib/python2.7/dist-packages' in pkg_abs_path 20 | assert os.path.exists(os.path.join(pkg_abs_path, '__init__.py')) 21 | assert os.path.exists(os.path.join(test_pkg_abs_path, '__init__.py')) 22 | 23 | 24 | def test_installed(): 25 | # make sure we are installed properly 26 | file_abs_path = __file__ 27 | test_pkg_abs_path = os.path.dirname(file_abs_path) 28 | pkg_abs_path = os.path.dirname(test_pkg_abs_path) 29 | 30 | if not any(pkgdir in pkg_abs_path for pkgdir in ['site-packages', 'dist-packages']): # we assume we are in an installed package 31 | raise nose.SkipTest("this is not an installed package") 32 | 33 | # check we have an *.egg-info along side us (it means we are not inside an egg) 34 | assert os.path.exists(os.path.join(os.path.dirname(pkg_abs_path), 'distutils_setup-0.0.1.egg-info')) 35 | 36 | # check there is no easy_install.pth or site.py, like for a normal install 37 | assert not os.path.exists(os.path.join(os.path.dirname(pkg_abs_path), 'easy-install.pth')) 38 | assert not os.path.exists(os.path.join(os.path.dirname(pkg_abs_path), 'site.py')) 39 | 40 | # TODO : add more, enough to make sure our package is installed as catkin expects it (without pip tracking version we should be useing --single-version-externally-managed) -------------------------------------------------------------------------------- /test/distutils-setup/distutils_setup/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from distutils.core import setup 4 | 5 | setup(name='distutils_setup', 6 | version='0.0.1', 7 | description='A python package that manages setup.py with distutils.', 8 | author='AlexV', 9 | author_email='asmodehn@gmail.com', 10 | packages=['dstest', 'dstest.test'], 11 | ) 12 | 13 | -------------------------------------------------------------------------------- /test/distutils-setup/distutils_setup/test/test_dstest.py: -------------------------------------------------------------------------------- 1 | # Sample Test passing with nose and pytest 2 | 3 | def test_pass(): 4 | assert True, "dummy sample test" 5 | -------------------------------------------------------------------------------- /test/distutils-setup/extra_installs/bin.txt: -------------------------------------------------------------------------------- 1 | # Test file that should be installed in ${CATKIN_PACKAGE_BIN_DESTINATION} 2 | # Ref : http://docs.ros.org/kinetic/api/catkin/html/user_guide/variables.html -------------------------------------------------------------------------------- /test/distutils-setup/extra_installs/etc.txt: -------------------------------------------------------------------------------- 1 | # Test file that should be installed in ${CATKIN_PACKAGE_ETC_DESTINATION} 2 | # Ref : http://docs.ros.org/kinetic/api/catkin/html/user_guide/variables.html -------------------------------------------------------------------------------- /test/distutils-setup/extra_installs/include.txt: -------------------------------------------------------------------------------- 1 | # Test file that should be installed in ${CATKIN_PACKAGE_INCLUDE_DESTINATION} 2 | # Ref : http://docs.ros.org/kinetic/api/catkin/html/user_guide/variables.html 3 | -------------------------------------------------------------------------------- /test/distutils-setup/extra_installs/lib.txt: -------------------------------------------------------------------------------- 1 | # Test file that should be installed in ${CATKIN_PACKAGE_LIB_DESTINATION} 2 | # Ref : http://docs.ros.org/kinetic/api/catkin/html/user_guide/variables.html -------------------------------------------------------------------------------- /test/distutils-setup/extra_installs/python.txt: -------------------------------------------------------------------------------- 1 | # Test file that should be installed in ${CATKIN_PACKAGE_PYTHON_DESTINATION} 2 | # Ref : http://docs.ros.org/kinetic/api/catkin/html/user_guide/variables.html -------------------------------------------------------------------------------- /test/distutils-setup/extra_installs/share.txt: -------------------------------------------------------------------------------- 1 | # Test file that should be installed in ${CATKIN_PACKAGE_SHARE_DESTINATION} 2 | # Ref : http://docs.ros.org/kinetic/api/catkin/html/user_guide/variables.html -------------------------------------------------------------------------------- /test/distutils-setup/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | distutils_setup 4 | 0.0.1 5 | 6 | A python package that manages setup.py with distutils. 7 | 8 | AlexV 9 | AlexV 10 | BSD 11 | 12 | catkin 13 | catkin_pip 14 | 15 | 16 | python-nose 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /test/pipproject/.gitignore: -------------------------------------------------------------------------------- 1 | mypippkg 2 | -------------------------------------------------------------------------------- /test/pipproject/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.12) 2 | project(mypippkg) 3 | 4 | # This is a full project CMakeLists (in case we call it independently for tests or so) 5 | set (PIP_PROJECT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/mypippkg) 6 | 7 | find_package(catkin REQUIRED COMPONENTS catkin_pip) 8 | 9 | # For development, we need to install the pip dependencies in the workspace being created 10 | # Upon install, this will not do anything. All requirements should be satisfied by ROS dependencies system. 11 | # => pip dependencies will work from source only 12 | # => to release a pip dependency in a ROS system, you need to catkinize all dependencies. 13 | catkin_pip_requirements(${PIP_PROJECT_DIR}/requirements.txt --ignore-installed) 14 | # Here we ignore already installed packages, to avoid conflicts with system installed packages (pygments for example) 15 | # However this also means that existing packages in the workspace will not be used to satisfy requirements, 16 | # and will be reinstalled everytime... 17 | 18 | # This replace catkin_python_setup() 19 | # For devel, this will install all your unsatisfied pip dependencies. 20 | # Upon install, this will bark if some dependencies are not already satisfied (by ROS). 21 | catkin_pip_target(mypippkg ${PIP_PROJECT_DIR}) 22 | 23 | catkin_package() 24 | 25 | # CAREFUL : all projects for test here will share the same workspace. pip might have conflicts... 26 | 27 | ## Unit tests 28 | if (CATKIN_ENABLE_TESTING) 29 | catkin_add_nosetests(${PIP_PROJECT_DIR}/tests DEPENDENCIES mypippkg) 30 | catkin_add_pytests(${PIP_PROJECT_DIR}/tests DEPENDENCIES mypippkg) 31 | endif() 32 | -------------------------------------------------------------------------------- /test/pipproject/catkin_pip: -------------------------------------------------------------------------------- 1 | ../catkin_pip -------------------------------------------------------------------------------- /test/pipproject/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | mypippkg 4 | 0.0.1 5 | 6 | A python package that can be installed with pip. 7 | 8 | AlexV 9 | Will McGinnis 10 | BSD 11 | https://github.com/wdm0006/cookiecutter-pipproject.git 12 | 13 | catkin 14 | catkin_pip 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /test/pylibrary/.gitignore: -------------------------------------------------------------------------------- 1 | python-nameless 2 | -------------------------------------------------------------------------------- /test/pylibrary/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.12) 2 | project(python_nameless) 3 | 4 | # This is a full project CMakeLists (in case we call it independently for tests or so) 5 | set (PIP_PROJECT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/python-nameless) 6 | 7 | # NEEDED ONLY FOR TESTING INDEPENDENTLY : Setting up catkin-pip from source via symlink 8 | # add_subdirectory(catkin_pip) 9 | 10 | find_package(catkin REQUIRED COMPONENTS catkin_pip) 11 | 12 | # no requirements file in this project template 13 | 14 | # This replace catkin_python_setup() 15 | # For devel, this will install all your unsatisfied pip dependencies. 16 | # Upon install, this will bark if some dependencies are not already satisfied (by ROS). 17 | catkin_pip_target(nameless ${PIP_PROJECT_DIR}) 18 | 19 | catkin_package() 20 | 21 | # CAREFUL : all projects for test here will share the same workspace. pip might have conflicts... 22 | 23 | ## Unit tests 24 | if (CATKIN_ENABLE_TESTING) 25 | catkin_add_nosetests(${PIP_PROJECT_DIR}/tests DEPENDENCIES nameless) 26 | catkin_add_pytests(${PIP_PROJECT_DIR}/tests DEPENDENCIES nameless) 27 | endif() 28 | -------------------------------------------------------------------------------- /test/pylibrary/catkin_pip: -------------------------------------------------------------------------------- 1 | ../catkin_pip -------------------------------------------------------------------------------- /test/pylibrary/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | python_nameless 4 | 0.0.1 5 | 6 | Enhanced cookiecutter template for Python libraries. 7 | 8 | AlexV 9 | Ionel Cristian Mărieș 10 | BSD 11 | https://github.com/ionelmc/cookiecutter-pylibrary.git 12 | 13 | catkin 14 | catkin_pip 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /test/pypackage-minimal/.gitignore: -------------------------------------------------------------------------------- 1 | cookiecutter_pypackage_minimal 2 | -------------------------------------------------------------------------------- /test/pypackage-minimal/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.12) 2 | project(cookiecutter_pypackage_minimal) 3 | 4 | # This is a full project CMakeLists (in case we call it independently for tests or so) 5 | set (PIP_PROJECT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/cookiecutter_pypackage_minimal) 6 | 7 | # NEEDED ONLY FOR TESTING INDEPENDENTLY : Setting up catkin-pip from source via symlink 8 | add_subdirectory(catkin_pip) 9 | 10 | find_package(catkin REQUIRED COMPONENTS catkin_pip) 11 | 12 | # no requirements file here 13 | 14 | # This replace catkin_python_setup() 15 | # For devel, this will install all your unsatisfied pip dependencies. 16 | # Upon install, this will bark if some dependencies are not already satisfied (by ROS). 17 | catkin_pip_target(cookiecutter_pypackage_minimal ${PIP_PROJECT_DIR}) 18 | 19 | catkin_package() 20 | 21 | # CAREFUL : all projects for test here will share the same workspace. pip might have conflicts... 22 | 23 | ## Unit tests 24 | if (CATKIN_ENABLE_TESTING) 25 | catkin_add_nosetests(${PIP_PROJECT_DIR}/tests DEPENDENCIES cookiecutter_pypackage_minimal) 26 | catkin_add_pytests(${PIP_PROJECT_DIR}/tests DEPENDENCIES cookiecutter_pypackage_minimal) 27 | endif() 28 | -------------------------------------------------------------------------------- /test/pypackage-minimal/catkin_pip: -------------------------------------------------------------------------------- 1 | ../catkin_pip -------------------------------------------------------------------------------- /test/pypackage-minimal/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | cookiecutter_pypackage_minimal 4 | 0.0.1 5 | 6 | An opinionated, minimal cookiecutter template for Python packages 7 | 8 | AlexV 9 | Louis Taylor 10 | MIT 11 | https://github.com/asmodehn/cookiecutter-pypackage-minimal.git 12 | 13 | 14 | catkin 15 | catkin_pip 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /test/pypackage/.gitignore: -------------------------------------------------------------------------------- 1 | python_boilerplate 2 | -------------------------------------------------------------------------------- /test/pypackage/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.12) 2 | project(python_boilerplate) 3 | 4 | # This is a full project CMakeLists (in case we call it independently for tests or so) 5 | set (PIP_PROJECT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/python_boilerplate) 6 | 7 | # NEEDED ONLY FOR TESTING INDEPENDENTLY : Setting up catkin-pip from source via symlink 8 | # add_subdirectory(catkin_pip) 9 | 10 | find_package(catkin REQUIRED COMPONENTS catkin_pip) 11 | 12 | # For development, we need to install the pip dependencies in the workspace being created 13 | # Upon install, this will not do anything. All requirements should be satisfied by ROS dependencies system. 14 | # => pip dependencies will work from source only 15 | # => to release a pip dependency in a ROS system, you need to catkinize all dependencies. 16 | catkin_pip_requirements(${PIP_PROJECT_DIR}/requirements_dev.txt --ignore-installed) 17 | # Here we ignore already installed packages, to avoid conflicts with system installed packages (pygments for example) 18 | # However this also means that existing packages in the workspace will not be used to satisfy requirements, 19 | # and will be reinstalled everytime... 20 | 21 | # This replace catkin_python_setup() 22 | # For devel, this will install all your unsatisfied pip dependencies. 23 | # Upon install, this will bark if some dependencies are not already satisfied (by ROS). 24 | catkin_pip_target(python_boilerplate ${PIP_PROJECT_DIR}) 25 | 26 | catkin_package() 27 | 28 | # CAREFUL : all projects for test here will share the same workspace. pip might have conflicts... 29 | 30 | ## Unit tests 31 | if (CATKIN_ENABLE_TESTING) 32 | catkin_add_nosetests(${PIP_PROJECT_DIR}/tests DEPENDENCIES python_boilerplate) 33 | catkin_add_pytests(${PIP_PROJECT_DIR}/tests DEPENDENCIES python_boilerplate) 34 | endif() 35 | -------------------------------------------------------------------------------- /test/pypackage/catkin_pip: -------------------------------------------------------------------------------- 1 | ../catkin_pip -------------------------------------------------------------------------------- /test/pypackage/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | python_boilerplate 4 | 0.0.1 5 | 6 | Cookiecutter template for a Python package. 7 | 8 | AlexV 9 | Audrey Roy Greenfeld 10 | BSD 11 | https://github.com/audreyr/cookiecutter-pypackage.git 12 | 13 | catkin 14 | catkin_pip 15 | 16 | 17 | libffi-dev 18 | libssl-dev 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /test/setuptools-setup/.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | *.egg-info 3 | -------------------------------------------------------------------------------- /test/setuptools-setup/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.12) 2 | project(setuptools_setup) 3 | 4 | # This is a full project CMakeLists (in case we call it independently for tests or so) 5 | set (PIP_PROJECT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/setuptools_setup) 6 | 7 | find_package(catkin REQUIRED COMPONENTS catkin_pip) 8 | 9 | # This replace catkin_python_setup() 10 | # For devel, this will install all your unsatisfied pip dependencies. 11 | # Upon install, this will bark if some dependencies are not already satisfied (by ROS). 12 | catkin_pip_target(sstest ${PIP_PROJECT_DIR}) 13 | 14 | catkin_package() 15 | 16 | # CAREFUL : all projects for test here will share the same workspace. pip might have conflicts... 17 | 18 | # Testing potential extra files installation 19 | install(FILES extra_installs/bin.txt DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}) 20 | install(FILES extra_installs/etc.txt DESTINATION ${CATKIN_PACKAGE_ETC_DESTINATION}) 21 | install(FILES extra_installs/include.txt DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}) 22 | install(FILES extra_installs/lib.txt DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}) 23 | install(FILES extra_installs/python.txt DESTINATION ${CATKIN_PACKAGE_PYTHON_DESTINATION}) 24 | install(FILES extra_installs/share.txt DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}) 25 | 26 | ## Unit tests 27 | if (CATKIN_ENABLE_TESTING) 28 | catkin_add_nosetests(${PIP_PROJECT_DIR}/test DEPENDENCIES sstest) 29 | catkin_add_pytests(${PIP_PROJECT_DIR}/test DEPENDENCIES sstest) 30 | # Running embedded test from devel space 31 | catkin_add_pytests(${PIP_PROJECT_DIR}/sstest/test DEPENDENCIES sstest) 32 | endif() 33 | -------------------------------------------------------------------------------- /test/setuptools-setup/catkin_pip: -------------------------------------------------------------------------------- 1 | ../catkin_pip -------------------------------------------------------------------------------- /test/setuptools-setup/extra_installs/bin.txt: -------------------------------------------------------------------------------- 1 | # Test file that should be installed in ${CATKIN_PACKAGE_BIN_DESTINATION} 2 | # Ref : http://docs.ros.org/kinetic/api/catkin/html/user_guide/variables.html -------------------------------------------------------------------------------- /test/setuptools-setup/extra_installs/etc.txt: -------------------------------------------------------------------------------- 1 | # Test file that should be installed in ${CATKIN_PACKAGE_ETC_DESTINATION} 2 | # Ref : http://docs.ros.org/kinetic/api/catkin/html/user_guide/variables.html -------------------------------------------------------------------------------- /test/setuptools-setup/extra_installs/include.txt: -------------------------------------------------------------------------------- 1 | # Test file that should be installed in ${CATKIN_PACKAGE_INCLUDE_DESTINATION} 2 | # Ref : http://docs.ros.org/kinetic/api/catkin/html/user_guide/variables.html 3 | -------------------------------------------------------------------------------- /test/setuptools-setup/extra_installs/lib.txt: -------------------------------------------------------------------------------- 1 | # Test file that should be installed in ${CATKIN_PACKAGE_LIB_DESTINATION} 2 | # Ref : http://docs.ros.org/kinetic/api/catkin/html/user_guide/variables.html -------------------------------------------------------------------------------- /test/setuptools-setup/extra_installs/python.txt: -------------------------------------------------------------------------------- 1 | # Test file that should be installed in ${CATKIN_PACKAGE_PYTHON_DESTINATION} 2 | # Ref : http://docs.ros.org/kinetic/api/catkin/html/user_guide/variables.html -------------------------------------------------------------------------------- /test/setuptools-setup/extra_installs/share.txt: -------------------------------------------------------------------------------- 1 | # Test file that should be installed in ${CATKIN_PACKAGE_SHARE_DESTINATION} 2 | # Ref : http://docs.ros.org/kinetic/api/catkin/html/user_guide/variables.html -------------------------------------------------------------------------------- /test/setuptools-setup/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | setuptools_setup 4 | 0.0.1 5 | 6 | A python package that manages setup.py with setuptools. 7 | 8 | AlexV 9 | AlexV 10 | BSD 11 | 12 | catkin 13 | catkin_pip 14 | 15 | python-pytest 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /test/setuptools-setup/setuptools_setup/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from setuptools import setup 4 | 5 | setup(name='setuptools_setup', 6 | version='0.0.1', 7 | description='A python package that manages setup.py with setuptools.', 8 | author='AlexV', 9 | author_email='asmodehn@gmail.com', 10 | install_requires=['pytest'], # since we are using it for testing inside this package 11 | # It will be installed by rosdep, and installation on devel space will depend on --ignore-installed option, 12 | # but it would NOT be installed on install space. 13 | # Yet the travis check will work, by using the one installed previously on the system by rosdep. 14 | packages=['sstest', 'sstest.test'], 15 | ) 16 | 17 | -------------------------------------------------------------------------------- /test/setuptools-setup/setuptools_setup/sstest/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyros-dev/catkin_pip/440004356798491d347cc81b809b22968be8741c/test/setuptools-setup/setuptools_setup/sstest/__init__.py -------------------------------------------------------------------------------- /test/setuptools-setup/setuptools_setup/sstest/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pyros-dev/catkin_pip/440004356798491d347cc81b809b22968be8741c/test/setuptools-setup/setuptools_setup/sstest/test/__init__.py -------------------------------------------------------------------------------- /test/setuptools-setup/setuptools_setup/sstest/test/test_install.py: -------------------------------------------------------------------------------- 1 | import os 2 | import pytest 3 | 4 | 5 | def test_pytest(): 6 | # making sure we use pytest from system packages, installed by rosdep for install tests 7 | if os.environ.get('ROS_FLOW') == 'install': 8 | assert pytest.__file__ == '/usr/lib/python2.7/dist-packages/pytest.pyc', pytest.__file__ 9 | else: 10 | # and the one installed in devel space otherwise 11 | assert 'devel/lib/python2.7/site-packages/pytest.pyc' in pytest.__file__ 12 | 13 | 14 | def test_content(): 15 | # makes sure everything is there 16 | file_abs_path = __file__ 17 | test_pkg_abs_path = os.path.dirname(file_abs_path) 18 | pkg_abs_path = os.path.dirname(test_pkg_abs_path) 19 | 20 | assert 'lib/python2.7/site-packages' or 'lib/python2.7/dist-packages' in pkg_abs_path 21 | assert os.path.exists(os.path.join(pkg_abs_path, '__init__.py')) 22 | assert os.path.exists(os.path.join(test_pkg_abs_path, '__init__.py')) 23 | 24 | 25 | def test_installed(): 26 | # make sure we are installed properly 27 | file_abs_path = __file__ 28 | test_pkg_abs_path = os.path.dirname(file_abs_path) 29 | pkg_abs_path = os.path.dirname(test_pkg_abs_path) 30 | if not any(pkgdir in pkg_abs_path for pkgdir in ['site-packages', 'dist-packages']): # we assume we are in an installed package 31 | raise pytest.xfail("this is not an installed package") 32 | 33 | # check we have an *.egg-info along side us (it means we are not inside an egg) 34 | assert os.path.exists(os.path.join(os.path.dirname(pkg_abs_path), 'setuptools_setup-0.0.1-py2.7.egg-info')) 35 | 36 | # check there is no easy_install.pth or site.py, like for a normal install 37 | assert not os.path.exists(os.path.join(os.path.dirname(pkg_abs_path), 'easy-install.pth')) 38 | assert not os.path.exists(os.path.join(os.path.dirname(pkg_abs_path), 'site.py')) 39 | 40 | # TODO : add more, enough to make sure our package is installed as catkin expects it (without pip tracking version we should be useing --single-version-externally-managed) -------------------------------------------------------------------------------- /test/setuptools-setup/setuptools_setup/test/test_sstest.py: -------------------------------------------------------------------------------- 1 | # Sample Test passing with nose and pytest 2 | 3 | def test_pass(): 4 | assert True, "dummy sample test" 5 | -------------------------------------------------------------------------------- /test/test_requirements.txt: -------------------------------------------------------------------------------- 1 | cookiecutter==1.6.0 2 | pyros-setup>=0.2.0 3 | -------------------------------------------------------------------------------- /travis_checks.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | # first we ensure we change to the directory where this script is. 5 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 6 | cd $DIR 7 | 8 | # This script run basic checks on this project. 9 | # It is used by travis and can also be used by a developer for checking his current working tree. 10 | # 11 | # These variables need to be setup before calling this script: 12 | # CI_ROS_DISTRO [indigo | jade | kinetic] 13 | # ROS_FLOW [devel | install] 14 | 15 | # For travis docker, this is already done by the entrypoint in docker image. 16 | # However when using 'docker exec' we still need to source it ourselves. 17 | # Also it is mandatory when this script is run directly by the developer. 18 | source /opt/ros/$ROS_DISTRO/setup.bash 19 | 20 | mkdir -p testbuild 21 | cd testbuild 22 | cmake ../test -DCMAKE_INSTALL_PREFIX=./install 23 | if [ "$ROS_FLOW" == "devel" ]; then 24 | make -j1 25 | echo PYTHONPATH = $PYTHONPATH 26 | source devel/setup.bash 27 | echo PYTHONPATH = $PYTHONPATH 28 | rospack profile 29 | echo PYTHONPATH = $PYTHONPATH 30 | make -j1 tests 31 | echo PYTHONPATH = $PYTHONPATH 32 | make -j1 run_tests 33 | echo PYTHONPATH = $PYTHONPATH 34 | catkin_test_results . 35 | elif [ "$ROS_FLOW" == "install" ]; then 36 | make -j1 install 37 | source install/setup.bash 38 | echo PYTHONPATH = $PYTHONPATH 39 | rospack profile 40 | # some test packages have embedded tests to validate installed package structure 41 | python -m nose dstest 42 | python -m pytest --pyargs sstest 43 | fi 44 | --------------------------------------------------------------------------------