Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add verb for tracking and staging source changes in workspace #428

Closed
wants to merge 14 commits into from
138 changes: 138 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
.pybuilder/
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version

# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock

# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat.pid

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/

# pytype static type analyzer
.pytype/

# Cython debug symbols
cython_debug/
6 changes: 6 additions & 0 deletions bin/colcon
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,14 @@ from colcon_core.shell.bat import BatShell # noqa: E402
from colcon_core.shell.dsv import DsvShell # noqa: E402
from colcon_core.shell.sh import ShShell # noqa: E402
from colcon_core.task.python.build import PythonBuildTask # noqa: E402
from colcon_core.task.python.stage import PythonStageTask # noqa: E402
from colcon_core.task.python.test import PythonTestTask # noqa: E402
from colcon_core.task.python.test.pytest \
import PytestPythonTestingStep # noqa: E402
from colcon_core.task.python.test.setuppy_test \
import SetuppyPythonTestingStep # noqa: E402
from colcon_core.verb.build import BuildVerb # noqa: E402
from colcon_core.verb.stage import StageVerb # noqa: E402
from colcon_core.verb.test import TestVerb # noqa: E402


Expand Down Expand Up @@ -127,11 +129,15 @@ custom_entry_points.update({
'colcon_core.task.build': {
'python': PythonBuildTask,
},
'colcon_core.task.stage': {
'python': PythonStageTask,
},
'colcon_core.task.test': {
'python': PythonTestTask,
},
'colcon_core.verb': {
'build': BuildVerb,
'stage': StageVerb,
'test': TestVerb,
},
})
Expand Down
77 changes: 77 additions & 0 deletions colcon_core/task/python/stage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Copyright 2016-2018 Dirk Thomas
# Copyright 2021 Ruffin White
# Licensed under the Apache License, Version 2.0

from contextlib import suppress
# with suppress(ImportError):
# # needed before importing distutils
# # to avoid warning introduced in setuptools 49.2.0
# import setuptools # noqa: F401
# from distutils.sysconfig import get_python_lib
# import locale
import os
from pathlib import Path
# import shutil
# import sys
# from sys import executable

# from colcon_core.environment import create_environment_hooks
# from colcon_core.environment import create_environment_scripts
from colcon_core.logging import colcon_logger
from colcon_core.plugin_system import satisfies_version
# from colcon_core.shell import create_environment_hook
# from colcon_core.shell import get_command_environment
# from colcon_core.subprocess import check_output
# from colcon_core.task import run
from colcon_core.task import TaskExtensionPoint
# from colcon_core.task.python import get_data_files_mapping
# from colcon_core.task.python import get_setup_data
from dirhash import dirhash

logger = colcon_logger.getChild(__name__)


class PythonStageTask(TaskExtensionPoint):
"""Stage Python packages."""

def __init__(self): # noqa: D107
super().__init__()
satisfies_version(TaskExtensionPoint.EXTENSION_POINT_VERSION, '^1.0')

async def stage(self, *, additional_hooks=None): # noqa: D102
pkg = self.context.pkg
args = self.context.args

logger.info(
"Staging Python package in '{args.path}'".format_map(locals()))

# Use the number of CPU cores
jobs = os.cpu_count()
with suppress(AttributeError):
# consider restricted set of CPUs if applicable
jobs = min(jobs, len(os.sched_getaffinity(0)))
if jobs is None:
# the number of cores can't be determined
jobs = 1

# ignore all . files and . folders
current_checksum = dirhash(args.path, 'md5', ignore=['.*'], jobs=jobs)

# os.makedirs(args.build_base, exist_ok=True)
stage_base = Path(args.build_base, 'stage')
stage_base.mkdir(parents=True, exist_ok=True)
current_path = Path(stage_base, 'colcon_stage_current.txt')
previous_path = Path(stage_base, 'colcon_stage_previous.txt')

current_path.write_text(str(current_checksum) + '\n')

previous_checksum = None
if previous_path.exists():
previous_checksum = previous_path.read_text().rstrip()

if args.tare_changes:
previous_path.write_text(str(current_checksum) + '\n')
return 0
elif previous_checksum == current_checksum:
return 0
return 'changed'
Loading