Skip to content

Commit

Permalink
Convert to use epicscorelibs
Browse files Browse the repository at this point in the history
  • Loading branch information
coretl committed Feb 25, 2021
1 parent f603e8d commit 69cdf52
Show file tree
Hide file tree
Showing 22 changed files with 938 additions and 202 deletions.
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*/_version_git.py export-subst
20 changes: 13 additions & 7 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
/bin
/dbd
/lib
/db
/docs/html
/pythonIoc
/.vscode
/venv
*.pyc
O.*
/docs/html/
/softioc/_extension.*

# Dist build output
/build
/dist
/softioc.egg-info/

# Coverage reports
.coverage
cov.xml

/docs/papers/*/*.aux
/docs/papers/*/*.pdf
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "iocStats"]
path = softioc/iocStats
url = https://github.com/epics-modules/iocStats.git
22 changes: 22 additions & 0 deletions Pipfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true

[dev-packages]
pytest-cov = "*"
pytest-flake8 = "*"
sphinx-rtd-theme = "*"
# switch to main repo after PR https://github.com/Holzhaus/sphinx-multiversion/pull/60 is merged
sphinx-multiversion = {editable = true,git = "https://github.com/dls-controls/sphinx-multiversion.git",ref = "only-arg"}
setuptools-dso = "*"

[packages]
# All other package requirements from setup.py
softioc = {editable = true,path = "."}

[scripts]
# Put coverage here so we don't interfere with debugging in the IDE
tests = "python -m pytest --cov=epicsdbbuilder --cov-report term"
docs = "sphinx-build -EWT --keep-going docs build/html"
clean = "rm -rf build prefix */__pycache__ .coverage cov.xml *.egg-info .mypy_cache .pytest_cache"
491 changes: 491 additions & 0 deletions Pipfile.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions epicscorelibs
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[build-system]
requires = ["setuptools", "wheel", "setuptools_dso", "epicscorelibs>=7.0.4.99.0.0a1"]
build-backend = "setuptools.build_meta"
41 changes: 0 additions & 41 deletions pythonIoc.in

This file was deleted.

50 changes: 50 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
[metadata]
name = softioc
description = EPICS IOC with Python Device Support
url = https://github.com/dls-controls/pythonIoc
author = Michael Abbott
author_email = [email protected]
license = Apache License 2.0
long_description = file: README.rst
long_description_content_type = text/x-rst
classifiers =
Development Status :: 5 - Production/Stable
License :: OSI Approved :: Apache Software License
Programming Language :: Python :: 2.7
Programming Language :: Python :: 3.6
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8

[options]
packages = find:

[options.packages.find]
# Don't include our test directory in the distribution
exclude = tests

[options.entry_points]
# Include a command line script
console_scripts =
pythonIoc = softioc.__main__:main

[options.package_data]
softioc =
softioc/access.acf
softioc/device.dbd
softioc/iocStats/devIocStats/src/devIocStats.dbd
softioc/iocStats/iocAdmin/Db/*.template

[flake8]
max-line-length = 80
extend-ignore =
F401 F403 F405 # Allow from module import *
E251 # Allow call(param = value)
E301 E302 E303 E305 # Allow any number of blank lines

[tool:pytest]
# Run pytest with all our checkers, and don't spam us with massive tracebacks on error
addopts = --tb=native -vv --flake8 --doctest-modules

[coverage:run]
# This is covered in the versiongit test suite so exclude it here
omit = */_version_git.py
95 changes: 95 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import os
import sys

from setuptools.command.develop import develop
import epicscorelibs.path
import epicscorelibs.version
from setuptools_dso import DSO, Extension, setup
from epicscorelibs.config import get_config_var

# Place the directory containing _version_git on the path
for path, _, filenames in os.walk(os.path.dirname(os.path.abspath(__file__))):
if "_version_git.py" in filenames:
sys.path.append(path)
break

from _version_git import __version__, get_cmdclass # noqa

devIocStats_OSI = [
"devIocStatsAnalog.c",
"devIocStatsString.c",
"devIocStatsWaveform.c",
"devIocStatsSub.c",
"devIocStatsTest.c"
]

devIocStats_OSD = [
"osdCpuUsage.c",
"osdCpuUtilization.c",
"osdFdUsage.c",
"osdMemUsage.c",
"osdWorkspaceUsage.c",
"osdClustInfo.c",
"osdSuspTasks.c",
"osdIFErrors.c",
"osdBootInfo.c",
"osdSystemInfo.c",
"osdHostInfo.c",
"osdPIDInfo.c",
]

devIocStats_srcs = []
devIocStats_src = os.path.join("softioc", "iocStats", "devIocStats")
devIocStats_default = os.path.join(devIocStats_src, "os", "default")
devIocStats_os = os.path.join(devIocStats_src, "os", get_config_var('OS_CLASS'))

for f in devIocStats_OSI:
devIocStats_srcs.append(os.path.join(devIocStats_src, f))
for f in devIocStats_OSD:
if os.path.exists(os.path.join(devIocStats_os, f)):
devIocStats_srcs.append(os.path.join(devIocStats_os, f))
else:
devIocStats_srcs.append(os.path.join(devIocStats_default, f))

#dso = DSO(
# 'softioc.lib.devIocStats',
# devIocStats_srcs,
# include_dirs=[epicscorelibs.path.include_path, devIocStats_src, devIocStats_os, devIocStats_default],
# dsos=['epicscorelibs.lib.Com']
#)

# Extension with all our C code
ext = Extension(
name='softioc._extension',
sources = ['softioc/extension.c'] + devIocStats_srcs,
include_dirs=[epicscorelibs.path.include_path, devIocStats_src, devIocStats_os, devIocStats_default],
dsos = ['epicscorelibs.lib.dbCore', 'epicscorelibs.lib.Com'],
define_macros = get_config_var('CPPFLAGS'),
extra_compile_args = get_config_var('CXXFLAGS'),
extra_link_args = get_config_var('LDFLAGS'),
)

# Add custom develop to add soft link to epicscorelibs in .
class Develop(develop):
def install_for_development(self):
develop.install_for_development(self)
# Make a link here to epicscorelibs so `pip install -e .` works
# If we don't do this dbCore can't be found when _extension is
# built into .
link = os.path.join(self.egg_path, "epicscorelibs")
if not os.path.exists(link):
os.symlink(os.path.join(self.install_dir, "epicscorelibs"), link)

setup(
cmdclass=dict(develop=Develop, **get_cmdclass()),
version=__version__,
ext_modules = [ext],
install_requires = [
"epicscorelibs==7.0.4.99.0.0a1",
#epicscorelibs.version.abi_requires(),
"numpy>=1.18",
"epicsdbbuilder>=1.4"
],
#x_dsos = [dso],
zip_safe = False, # setuptools_dso is not compatible with eggs!
)
2 changes: 2 additions & 0 deletions softioc/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
'''Python soft IOC module.'''

from ._version_git import __version__
25 changes: 25 additions & 0 deletions softioc/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import os
import sys
from argparse import ArgumentParser

from softioc import __version__


def main(args=None):
parser = ArgumentParser()
parser.add_argument("--version", action="version", version=__version__)
parser.add_argument("script", help="The python script to run")
parsed_args = parser.parse_args(args)
# Insert the directory containing script onto the path in case we do
# any imports
sys.path.insert(0, os.path.dirname(os.path.abspath(parsed_args.script)))
if sys.version_info < (3, 0):
# Python 2
execfile(parsed_args.script)
else:
# Python 3
exec(open(parsed_args.script).read())


if __name__ == "__main__":
main()
97 changes: 97 additions & 0 deletions softioc/_version_git.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Compute a version number from a git repo or archive

# This file is released into the public domain. Generated by:
# versiongit-1.0 (https://github.com/dls-controls/versiongit)
import os
import re
import sys
from subprocess import STDOUT, CalledProcessError, check_output

# These will be filled in if git archive is run or by setup.py cmdclasses
GIT_REFS = "$Format:%D$"
GIT_SHA1 = "$Format:%h$"

# Git describe gives us sha1, last version-like tag, and commits since then
CMD = "git describe --tags --dirty --always --long --match=[0-9]*[-.][0-9]*"


def get_version_from_git(path=None):
"""Try to parse version from git describe, fallback to git archive tags"""
tag, plus, suffix = "0.0", "untagged", ""
if not GIT_SHA1.startswith("$"):
# git archive or the cmdclasses below have filled in these strings
sha1 = GIT_SHA1
for ref_name in GIT_REFS.split(", "):
if ref_name.startswith("tag: "):
# git from 1.8.3 onwards labels archive tags "tag: TAGNAME"
tag, plus = ref_name[5:], "0"
else:
if path is None:
# If no path to git repo, choose the directory this file is in
path = os.path.dirname(os.path.abspath(__file__))
# output is TAG-NUM-gHEX[-dirty] or HEX[-dirty]
try:
cmd_out = check_output(CMD.split(), stderr=STDOUT, cwd=path)
except Exception as e:
sys.stderr.write("%s: %s\n" % (type(e).__name__, str(e)))
if isinstance(e, CalledProcessError):
sys.stderr.write("-> %s" % e.output.decode())
return "0.0+unknown", None, e
else:
out = cmd_out.decode().strip()
if out.endswith("-dirty"):
out = out[:-6]
suffix = ".dirty"
if "-" in out:
# There is a tag, extract it and the other pieces
match = re.search(r"^(.+)-(\d+)-g([0-9a-f]+)$", out)
tag, plus, sha1 = match.groups()
else:
# No tag, just sha1
sha1 = out
# Replace dashes in tag for dots
tag = tag.replace("-", ".")
if plus != "0" or suffix:
# Not on a tag, add additional info
tag = "%(tag)s+%(plus)s.g%(sha1)s%(suffix)s" % locals()
return tag, sha1, None


__version__, git_sha1, git_error = get_version_from_git()


def get_cmdclass(build_py=None, sdist=None):
"""Create cmdclass dict to pass to setuptools.setup that will write a
_version_static.py file in our resultant sdist, wheel or egg"""
if build_py is None:
from setuptools.command.build_py import build_py
if sdist is None:
from setuptools.command.sdist import sdist

def make_version_static(base_dir, pkg):
vg = os.path.join(base_dir, pkg.split(".")[0], "_version_git.py")
if os.path.isfile(vg):
lines = open(vg).readlines()
with open(vg, "w") as f:
for line in lines:
# Replace GIT_* with static versions
if line.startswith("GIT_SHA1 = "):
f.write("GIT_SHA1 = '%s'\n" % git_sha1)
elif line.startswith("GIT_REFS = "):
f.write("GIT_REFS = 'tag: %s'\n" % __version__)
else:
f.write(line)

class BuildPy(build_py):
def run(self):
build_py.run(self)
for pkg in self.packages:
make_version_static(self.build_lib, pkg)

class Sdist(sdist):
def make_release_tree(self, base_dir, files):
sdist.make_release_tree(self, base_dir, files)
for pkg in self.distribution.packages:
make_version_static(base_dir, pkg)

return dict(build_py=BuildPy, sdist=Sdist)
Loading

0 comments on commit 69cdf52

Please sign in to comment.