Skip to content

Commit

Permalink
Runtime deployer example (conan-io#25)
Browse files Browse the repository at this point in the history
* Create runtime_zip_deploy.py

* add new runtime_zip_deploy.py

* Update README.md

Co-authored-by: Rubén Rincón Blanco <[email protected]>

* add a readme to the deploy folder

* quick pass at making a test

* fix: missing profile and bad option

* fix deployer name

* comments

* Update test_deploy_runtime_zip.py

* Create runtime_zip_deploy.py

* fix folder name typo

* Apply suggestions from code review

Co-authored-by: James <[email protected]>

* add example to readme

Co-authored-by: Rubén Rincón Blanco <[email protected]>

* use new folder name since it pooped a warning

* add some actual tests

* use cpp_info instead of hardcoding folders

Co-authored-by: Rubén Rincón Blanco <[email protected]>

* fixup: links to renamed folder

---------

Co-authored-by: Rubén Rincón Blanco <[email protected]>
Co-authored-by: James <[email protected]>
Co-authored-by: Rubén Rincón Blanco <[email protected]>
  • Loading branch information
4 people authored Jun 9, 2023
1 parent 91dc2f7 commit 8c7ae80
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 0 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ Commands useful in Conan Center Index or its forks

Commands useful for managing BuildInfos and properties in Artifactory

### [Deployers](extensions/deployers)

These are the current custom deployers. Recall they are experimental and can experience breaking changes, use them as a base to create your own under your control for stability.

#### [Runtime Zipper](extensions/deployers/runtime_zip_deploy.py)

Makes a ZIP with all the executables

### Testing

To validate a new extension, it's possible to write a test that exercises its usage.
Expand Down
22 changes: 22 additions & 0 deletions extensions/deployers/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Deployers

- Runtime Zipper

```sh
$ conan install --requires=fmt/10.0.0 -o="fmt/*:shared=True" --deploy=runtime_zip_deploy
# ...
======== Computing necessary packages ========
Requirements
fmt/10.0.0#dd5e3eb81b512a1bb34a5aab88a07e82:a54b21e862b2638e704927807d06df018d4514c5#df013771a6193a12440274931cd966e8 - Cache

======== Installing packages ========
fmt/10.0.0: Already installed! (1 of 1)

======== Finalizing install (deploy, generators) ========
Install finished successfully
$ unzip runtime.zip
Archive: runtime.zip
inflating: libfmt.dylib
inflating: libfmt.10.0.0.dylib
inflating: libfmt.10.dylib
```
26 changes: 26 additions & 0 deletions extensions/deployers/runtime_zip_deploy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import os, shutil
import zipfile

# USE **KWARGS to be robust against changes
def deploy(graph, output_folder, **kwargs):
conanfile = graph.root.conanfile
files = []
for r, d in conanfile.dependencies.items():
if d.package_folder is None:
continue
# look for .dlls and .exes in the bin folder
for dir in [d.cpp_info.bindir, d.cpp_info.libdir]:
search_dir = os.path.join(d.package_folder, dir)
if not os.path.isdir(search_dir):
continue
for f in os.listdir(search_dir):
src = os.path.join(search_dir, f)
if f.endswith(".dll") or f.endswith(".exe") or f.endswith(".dylib") or os.access(src, os.X_OK):
dst = os.path.join(output_folder, f)
shutil.copy2(src, dst)
files.append(dst)

with zipfile.ZipFile(os.path.join(output_folder, 'runtime.zip'), 'w') as myzip:
for f in files:
myzip.write(f, os.path.basename(f), compress_type=zipfile.ZIP_DEFLATED)
os.remove(f)
39 changes: 39 additions & 0 deletions tests/test_deploy_runtime_zip.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import shutil
import tempfile
import os

import pytest

from tools import run


@pytest.fixture(autouse=True)
def conan_test():
old_env = dict(os.environ)
env_vars = {"CONAN_HOME": tempfile.mkdtemp(suffix='conans')}
os.environ.update(env_vars)
current = tempfile.mkdtemp(suffix="conans")
cwd = os.getcwd()
os.chdir(current)
try:
yield
finally:
os.chdir(cwd)
os.environ.clear()
os.environ.update(old_env)

def test_deploy_runtime_zip():
repo = os.path.join(os.path.dirname(__file__), "..")
run(f"conan config install {repo}")
run("conan --help")

# Let's build a application to bundle
run("conan new cmake_exe --define name=hello --define version=0.1")
run("conan profile detect")
run("conan create .")

run("conan install --requires hello/0.1 --deploy=runtime_zip_deploy")
shutil.unpack_archive("runtime.zip", "zip_contents")
dir_list = os.listdir("zip_contents")
assert len(dir_list) == 1
assert isinstance(dir_list[0], str) and dir_list[0].startswith("hello")

0 comments on commit 8c7ae80

Please sign in to comment.