Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,10 +163,10 @@ Runs CMake's configure step.
- options:
- `src_dir`: path to the source directory
- `build_dir`: path to the build directory
- `generator`: cmake project generator name (cmake option -G) (e.g. "Unix Makefiles")
- `generator` (optional): cmake project generator name (cmake option -G) (e.g. "Unix Makefiles")
- `toolset` (0.5.0+, optional): cmake toolset (cmake option -T) (e.g. v141 will use VS 2017 toolset, regardless of the generator)
- `*`: all the other options will be passed to the `cmake` as `-{parameter}=value`


###### Build

Runs CMake's build step.
Expand Down
12 changes: 12 additions & 0 deletions pydevops/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,17 @@ def apply_aliases(options: dict, aliases: dict):
result[target] = alias_value
return result

def apply_transforms(options: dict, transforms: set):
# A transform lambda takes in all options and returns a set of options to override.
# For example, take in build_type and output some_stage_build_type=STAGE_[lowercase(build_type)]:
# lambda options: {f"some_stage_build_type": f"STAGE_{options['build_type'].lower()}"}
result = options.copy()
for transform in transforms:
if callable(transform):
new_options = transform(options)
if new_options:
result.update(new_options)
return result

@dataclass(frozen=True)
class DevopsCfgContext:
Expand Down Expand Up @@ -74,6 +85,7 @@ def create_context(env, args, options, cfg):
defaults = expand_defaults(cfg.defaults, DevopsCfgContext(options))
options = {**defaults, **options}
options = apply_aliases(options, cfg.aliases)
options = apply_transforms(options, cfg.transforms)
return Context(env=env, args=args, options=options)


Expand Down
33 changes: 28 additions & 5 deletions pydevops/cmake.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,21 @@ def execute(self, ctx: Context):
src_dir = ctx.get_param("src_dir")
build_dir = ctx.get_param("build_dir")
options = ctx.get_options()
generator = options.pop("generator")
generator_options = ""
generator = options.pop("generator", None)
if generator:
generator_options = f"-G {generator}"
toolset = options.pop("toolset", None)
if toolset:
generator_options += f" -T {toolset}"
preset = options.pop("preset", None)
if preset:
generator_options += f" --preset {preset}"
else:
# This is a very simplified behavior, but it works for us
generator_options += f"-B {build_dir}"
others = _convert_dict_to_kv_params(options)
ctx.sh(f"cmake -S {src_dir} -B {build_dir} -G {generator} {others}")
ctx.sh(f"cmake -S {src_dir} {generator_options} {others}")


class Build(Step):
Expand All @@ -30,7 +42,13 @@ def execute(self, ctx: Context):
config = ctx.get_option("config")
n_jobs = ctx.get_option_default("j", 1)
verbose = ctx.get_option_default("verbose", False)
cmd = f"cmake --build {build_dir} --config {config} -j {n_jobs}"
preset_or_build_dir = ""
preset = ctx.get_option_default("preset", None)
if preset:
preset_or_build_dir = f" --preset {preset}"
else:
preset_or_build_dir = f" {build_dir}"
cmd = f"cmake --build {preset_or_build_dir} --config {config} -j {n_jobs}"
if verbose:
cmd += " --verbose"
if ctx.has_option("target"):
Expand All @@ -45,13 +63,17 @@ def execute(self, ctx: Context):
build_dir = ctx.get_param("build_dir")
config = ctx.get_option("C")
verbose = ctx.get_option_default("verbose", False)
preset = ctx.get_option_default("preset", None)
# Note: tests have to be run from the build dir
cwd = os.getcwd()
try:
os.chdir(build_dir)
if not preset:
os.chdir(build_dir)
cmd = f"ctest -C {config}"
if verbose:
cmd += " --verbose"
if preset:
cmd += f" --preset {preset}"
ctx.sh(cmd)
finally:
os.chdir(cwd)
Expand All @@ -62,8 +84,9 @@ def execute(self, ctx: Context):
build_dir = ctx.get_param("build_dir")
config = ctx.get_option("config")
prefix = ctx.get_option("prefix")
build_dir_suffix = ctx.get_option_default("build_dir_suffix", "")
# Note: tests have to be run from the build dir
ctx.sh(f"cmake --install {build_dir} "
ctx.sh(f"cmake --install {build_dir}{build_dir_suffix} "
f"--prefix {prefix} "
f"--config {config}")

Expand Down
21 changes: 17 additions & 4 deletions pydevops/conan.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
from pydevops.base import Step, Context
import os

class AddLocalIndex(Step):
def execute(self, context: Context):
path_relative = context.get_option("path")
if path_relative is None:
raise ValueError("Option 'path' must be provided for conan.AddLocalIndex step.")

build_dir = context.get_param("build_dir")
path = os.path.join(build_dir, path_relative)

cmd = f"conan remote add local-{path_relative} {path} --force"

context.sh(cmd)

class Install(Step):

Expand All @@ -10,10 +23,10 @@ def execute(self, context: Context):
build = context.get_option_default("build", None)
profile_file = context.get_option_default("profile", None)
conan_home = context.get_option_default("conan_home", None)
cmd = f"conan install --build=missing {src_dir} -if {build_dir} " \
f"-s build_type={build_type} "
if build:
cmd += f"--build={build} "
cmd = f"conan install --build=missing {src_dir} --update " \
f"-s build_type={build_type}"
#if build:
# cmd += f"--build={build} "
if profile_file:
cmd += f"--profile={profile_file}"
if conan_home:
Expand Down
29 changes: 29 additions & 0 deletions pydevops/gitdep.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from pydevops.base import Step, Context
import os
import shutil

class Fetch(Step):

def execute(self, context: Context):
repo = context.get_option("repo")
if repo is None:
raise ValueError("Option 'repo' must be provided for gitdeps.Fetch step.")

revision = context.get_option("revision")
if revision is None:
raise ValueError("Option 'revision' must be provided for gitdeps.Fetch step.")
path_relative = context.get_option("path")
if path_relative is None:
raise ValueError("Option 'path' must be provided for gitdeps.Fetch step.")

remove_old = context.get_option_default("remove_old", True)

build_dir = context.get_param("build_dir")

path = os.path.join(build_dir, path_relative)

if remove_old and os.path.exists(path):
shutil.rmtree(path)

cmd = f"git clone --depth 1 --branch {revision} {repo} {path}"
context.sh(cmd)
11 changes: 11 additions & 0 deletions pydevops/utils.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
import logging
import inspect

import pydevops.version as version

LOGGING_FORMAT = "[%(asctime)s][%(name)s][%(levelname)s] %(message)s"
ERROR_FORMAT = LOGGING_FORMAT + " (%(filename)s:%(lineno)d)"

LOGGING_LEVEL=logging.DEBUG

def is_version_at_least(minimum_version):
version_parts = [int(part) for part in version.__version__.split('.')]
minimum_parts = [int(part) for part in minimum_version.split('.')]
for v, m in zip(version_parts, minimum_parts):
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please simplify that to:

def is_version_at_least(minimum_version):
    version_parts = [int(part) for part in version.__version__.split('.')]
    minimum_parts = [int(part) for part in minimum_version.split('.')]
    return version_parts >= minimum_parts

or even:

from packaging import version

def is_version_at_least(minimum_version):
    return version.parse(version.__version__) >= version.parse(minimum_version)

if v < m:
return False
elif v > m:
return True
return True

# Credits:
# https://stackoverflow.com/questions/384076/
Expand Down
2 changes: 1 addition & 1 deletion pydevops/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.4.0"
__version__ = "0.5.0"