Skip to content
Snippets Groups Projects
Commit c6706b84 authored by Daniel Lyons's avatar Daniel Lyons
Browse files

Merge branch 'main' into SSA-6324-pytest-branch2-scode-update

parents 0db5075a f34ff7dd
No related branches found
No related tags found
No related merge requests found
Showing
with 77 additions and 341 deletions
...@@ -46,3 +46,16 @@ docs/_build ...@@ -46,3 +46,16 @@ docs/_build
/workflow-all/workflow-jobs/src/main/resources/edu/nrao/archive/workflow/scripts/open-permissions.sh /workflow-all/workflow-jobs/src/main/resources/edu/nrao/archive/workflow/scripts/open-permissions.sh
/archiveIface/archiveIface/webpack/stats.json /archiveIface/archiveIface/webpack/stats.json
/git-info.txt /git-info.txt
develop-eggs
build/metadata
#**/build/**
apps/**/build/**
services/**/build/**
shared/**/build/**
projects_checklist.txt
.installed.cfg
.ipynb_checkpoints
deps.png
build/pkgs
eggs
parts
\ No newline at end of file
include conda.mk all: ${HOME}/miniconda3 ${HOME}/miniconda3/envs/data metadata build
include setuptools.mk
include alma_fetch.mk
SHELL := /bin/bash ${HOME}/miniconda3:
@echo Please install miniconda to ${HOME}/miniconda3
@exit 1
build-base: ${HOME}/miniconda3/envs/data: environment.yml
@echo "Building..." conda env update
make miniconda-installed touch $@
make build-python
@echo "Finished build."
build-almafetch: .PHONY: metadata
@echo "Building ALMA fetcher." metadata:
make build-alma buildout parts=gen_metadata
.PHONY: build
build:
buildout parts=build_pkgs name=all
%% Cell type:code id: tags:
``` python
import os
from pathlib import Path
import platform
import sys
from typing import List, Optional, TextIO
```
%% Cell type:markdown id: tags:
A directory contains a project if there is a `setup.py` file in it.
%% Cell type:code id: tags:
``` python
projects = list(proj for (proj, subdirs, files) in os.walk(Path()) if 'setup.py' in files)
projects
```
%% Output
['./shared/schema',
'./shared/support',
'./shared/messaging/events',
'./apps/cli/executables/ingestion',
'./apps/cli/executables/weblog_thumbs',
'./apps/cli/executables/alma_reingester',
'./apps/cli/executables/alma_product_fetch',
'./apps/cli/executables/epilogue',
'./apps/cli/executables/datafetcher',
'./apps/cli/executables/vlba_grabber',
'./apps/cli/utilities/s_code_project_updater',
'./apps/cli/utilities/proprietary_setter',
'./apps/cli/utilities/mr_clean',
'./apps/cli/utilities/faultchecker',
'./apps/cli/utilities/mr_books',
'./apps/cli/utilities/dumplogs',
'./apps/cli/utilities/datafinder',
'./apps/cli/utilities/qa_results',
'./apps/cli/launchers/pymygdala',
'./apps/cli/launchers/wf',
'./services/archive']
%% Cell type:markdown id: tags:
Here are some things we know about projects:
- Every project has a name, which is the same as the name of the directory that contains it.
- Every project has a version, which happens to be in a file in `src/$PROJECT/_version.py` in the same format
- Every project has certain dependencies, which are enumerated in the setup.py as `install_requires`
Let's build up this abstraction.
%% Cell type:code id: tags:
``` python
class Project:
def __init__(self, path: Path):
self.path = path
self.name = path.name
@property
def version(self) -> str:
"""Compute and return the version in the _version.py file under the project."""
# to compute the version, we must locate and parse the _version.py file
version_file = self.path / 'src' / self.name / '_version.py'
# this line is basically cribbed from the standard setup.py file
return version_file.open().readlines()[-1].split()[-1].strip("\"'")
@property
def dependencies(self) -> List[str]:
"""Returns the list of dependencies under this project"""
# to compute the dependencies, we have to do something a bit more gross
# we have to open the setup.py file and look for a line with "install_requires"
# once we have that line, we have to parse out the Python list
# we can go ahead and cheat here with eval() for today.
#
# Unfortunately, this doesn't work if they span multiple lines, which is a
# frequent occurrence
setup_file = self.path / 'setup.py'
for line in setup_file.open().readlines():
if 'install_requires' in line:
return eval(line.split('=')[1].strip().strip(','))
# if we made it here, we never found that line, so this project
# has no dependencies; let's make life easy on ourselves and
# keep the API simple
return []
def __repr__(self) -> str:
return f'<Project name={self.name} version={self.version}>'
p1 = Project(Path('apps/cli/executables/datafetcher'))
p1
```
%% Output
<Project name=datafetcher version=4.0.0a1.dev1>
%% Cell type:code id: tags:
``` python
p1.dependencies
```
%% Output
['requests', 'pycapo']
%% Cell type:markdown id: tags:
The Makefile we want to build is going to have a certain structure. Namely, it should:
- Have a top-level entry point, probably a `.PHONY` that is easy for a parent Makefile to target
- The top-level entry point is going to depend on all the projects we have located
- Each project will be a target, a dependency of the top-level entry point
Based on the project structure we also know this:
- A project rule will depend on that project's dependencies
This should cause the build order to fall out rather naturally.
%% Cell type:code id: tags:
``` python
alma_product_fetch-4.0.0a1.dev1.macosx-10.9-x86_64.tar.gz
```
%% Output
'x86_64'
%% Cell type:code id: tags:
``` python
class Makefile:
def __init__(self, projects: List[Project]):
self.projects = projects
def build(self):
output = sys.stdout
self.build_entry_point(output)
self.build_projects(output)
def build_entry_point(self, output: TextIO):
"""This builds the toplevel entry point, ready for inclusion in another Makefile"""
toplevels = ' '.join(self.project_target(project) for project in self.projects)
output.write('.PHONY: all-python-projects\n')
output.write(f'all-python-projects: {toplevels}\n\n')
def project_target(self, project: Project) -> str:
"""This converts a project to a distfile name, so that Make can know if it is up to date"""
return f'{project.path}/dist/{project.name}-{project.version}.macosx-10.9-x86_64.tar.gz'
def build_projects(self, output: TextIO):
"""This generates all of the targets for each project we know about."""
for project in self.projects:
self.build_project(project, output)
def build_project(self, project: Project, output: TextIO):
dependencies = [self.lookup_dependency(dep) for dep in project.dependencies]
target_dependencies = ' '.join(self.project_target(dep) for dep in dependencies if dep)
output.write(f'{self.project_target(project)}: {target_dependencies}\n')
output.write(f'\tcd {project.path} && python setup.py bdist\n\n')
def lookup_dependency(self, project_name: str) -> Optional[Project]:
return next((project for project in self.projects if project.name == project_name), None)
def load_projects() -> List[Project]:
# the next line is commented out due to the fragility of the setup.py parsing logic
# return [Project(Path(proj)) for (proj, subdirs, files) in os.walk(Path()) if 'setup.py' in files]
return [Project(Path('shared/schema')), Project(Path('apps/cli/executables/alma_reingester')), Project(Path('shared/messaging/events'))]
m = Makefile(load_projects())
m.build()
```
%% Output
.PHONY: all-python-projects
all-python-projects: shared/schema/dist/schema-4.0.0a1.dev1.macosx-10.9-x86_64.tar.gz apps/cli/executables/alma_reingester/dist/alma_reingester-4.0.0a1.dev1.macosx-10.9-x86_64.tar.gz shared/messaging/events/dist/events-4.0.0a1.dev1.macosx-10.9-x86_64.tar.gz
shared/schema/dist/schema-4.0.0a1.dev1.macosx-10.9-x86_64.tar.gz:
cd shared/schema && python setup.py bdist
apps/cli/executables/alma_reingester/dist/alma_reingester-4.0.0a1.dev1.macosx-10.9-x86_64.tar.gz: shared/messaging/events/dist/events-4.0.0a1.dev1.macosx-10.9-x86_64.tar.gz shared/schema/dist/schema-4.0.0a1.dev1.macosx-10.9-x86_64.tar.gz
cd apps/cli/executables/alma_reingester && python setup.py bdist
shared/messaging/events/dist/events-4.0.0a1.dev1.macosx-10.9-x86_64.tar.gz:
cd shared/messaging/events && python setup.py bdist
import os
from pathlib import Path
def setup_project(target, source, env):
dir = str(source[0])[:-9]
home = os.getcwd()
env.Execute("cd {} && python3 setup.py bdist && cd {}".format(dir, home))
builder = Builder(action = setup_project)
env = Environment(BUILDERS = {'Setup' : builder})
projects = list(proj for (proj, subdirs, files) in os.walk(Path()) if "setup.py" in files)
output = []
for path in projects:
name = path.split('/')[-1]
output.append("{}/dist/{}".format(path.replace('.', os.getcwd()), name + "-4.0.0a1.dev1.macosx-10.15-x86_64.tar.gz"))
for src, out in zip(projects, output):
env.Setup(source=src + "/setup.py", target=out)
SHELL := /bin/bash
alma_product_fetch_sources := $(shell find apps/cli/executables/alma_product_fetch -type f)
build-alma: apps/cli/executables/alma_product_fetch/dist/alma_product_fetch-4.0.0a1.dev1.macosx-10.9-x86_64.tar.gz
@echo "built"
apps/cli/executables/alma_product_fetch/dist/alma_product_fetch-4.0.0a1.dev1.macosx-10.9-x86_64.tar.gz: $(alma_product_fetch_sources)
@echo building alma product fetch
cd apps/cli/executables/alma_product_fetch && \
python setup.py bdist
clean-alma:
rm -f apps/cli/executables/alma_product_fetch/dist/alma_product_fetch-4.0.0a1.dev1.macosx-10.9-x86_64.tar.gz
\ No newline at end of file
File moved
r"""
An import of the Joint Alma Observatories listfiles.py into the AAT/PPI system.
Given an MOUS Status UID (the most common identifier for a processing unit),
perform a database query to obtain the list of files required for a restore
and proceed to obtain them from the NAASC NGAS machines.
Initially written to use wget, this is rewritten to use requests and to
attempt to validate the data retrieved.
"""
...@@ -10,7 +10,7 @@ import cx_Oracle as almadb ...@@ -10,7 +10,7 @@ import cx_Oracle as almadb
import requests import requests
import sys import sys
from ._version import ___version___ as version from ._version import ___version___ as version
from pymygdala import LogHandler from pymygdala.models import LogHandler
from pycapo import CapoConfig from pycapo import CapoConfig
""" """
......
...@@ -16,7 +16,7 @@ setup( ...@@ -16,7 +16,7 @@ setup(
author_email='dms-ssa@nrao.edu', author_email='dms-ssa@nrao.edu',
url='TBD', url='TBD',
license="GPL", license="GPL",
install_requires=['cx-Oracle', 'pycapo', 'psycopg2', 'events', 'schema'], install_requires=['cx_Oracle', 'pycapo', 'psycopg2', 'events', 'schema'],
keywords=[], keywords=[],
packages=['alma_reingester'], packages=['alma_reingester'],
package_dir={'':'src'}, package_dir={'':'src'},
......
...@@ -7,11 +7,12 @@ package: ...@@ -7,11 +7,12 @@ package:
build: build:
entry_points: entry_points:
- datafetcher = datafetcher.commands:main - datafetcher = work.datafetcher.commands:main
script: {{ PYTHON }} setup.py install script: {{ PYTHON }} setup.py develop
source: source:
path: ../../../apps/cli/executables/datafetcher path: ../../apps/cli/executables/datafetcher
# - path: ../../apps/cli/executables/datafetcher/src/datafetcher
requirements: requirements:
build: build:
...@@ -25,23 +26,23 @@ requirements: ...@@ -25,23 +26,23 @@ requirements:
- requests>=2.23,<3.0 - requests>=2.23,<3.0
run: run:
- python==3.8 - python==3.8
- pika>=1.1,<2 # - pika>=1.1,<2
- pycapo>=0.3.0,<1.0 # - pycapo>=0.3.0,<1.0
- beautifulsoup4>=4.9.1,<5.0 # - beautifulsoup4>=4.9.1,<5.0
- lxml>=4.3.2,<5.0 # - lxml>=4.3.2,<5.0
- psycopg2>=2.8.5,<3.0 # - psycopg2>=2.8.5,<3.0
- pyopenssl>=19.1.0,<20.0 # - pyopenssl>=19.1.0,<20.0
- requests>=2.23,<3.0 # - requests>=2.23,<3.0
test: #test:
source_files: # source_files:
- test/ # - test/
requires: # requires:
- pytest>=5.4,<6.0 # - pytest>=5.4,<6.0
commands: # commands:
- pytest -vv --log-level=DEBUG --showlocals test/datafetcher_test.py # - pytest -vv --log-level=DEBUG --showlocals test/datafetcher_test.py
about: about:
license: "GPL" license: "GPL"
license_family: "GPL" license_family: "GPL"
summary: "NRAO Archive Data Fetcher Script" summary: "NRAO Archive Data Fetcher Script"
\ No newline at end of file
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
from pathlib import Path from pathlib import Path
from setuptools import setup, find_packages from setuptools import setup, find_packages
VERSION = open('src/_version.py').readlines()[-1].split()[-1].strip("\"'") VERSION = open('src/epilogue/_version.py').readlines()[-1].split()[-1].strip("\"'")
README = Path('README.md').read_text() README = Path('README.md').read_text()
setup( setup(
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment