From e63e2be7b4cb30dc94134ca078390a918e0b1a66 Mon Sep 17 00:00:00 2001 From: muryanto1 Date: Wed, 1 Jul 2020 13:32:07 -0700 Subject: [PATCH 01/15] replace numpy.rank() with numpy.ndim(), and add testPercentiles() --- Lib/statistics.py | 2 +- tests/test_genutil_statistics.py | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Lib/statistics.py b/Lib/statistics.py index fd12988..90cdbd9 100644 --- a/Lib/statistics.py +++ b/Lib/statistics.py @@ -1696,7 +1696,7 @@ def _percentiles(out, percent): pass Aii = numpy.where(numpy.equal(ns, 1), 100., tmp) ii = numpy.where(numpy.equal(ii, ns), ns - 1, ii) - if numpy.rank(ii) > 0: + if numpy.ndim(ii) > 0: ii = ii.astype(numpy.int) # tmp = (p-Ai)/(Aii-Ai)*array_indexing.extract(out,ii) + \ # (Aii-p)/(Aii-Ai)*array_indexing.extract(out,i) diff --git a/tests/test_genutil_statistics.py b/tests/test_genutil_statistics.py index bd87283..e6501c9 100644 --- a/tests/test_genutil_statistics.py +++ b/tests/test_genutil_statistics.py @@ -17,6 +17,11 @@ def assertArraysEqual(self,A,nm,skip=False, dump=dump): if not skip: self.assertTrue(numpy.ma.allclose(A,B)) + def testPercentiles(self): + a = numpy.array([1.0,2.0,3.0,4.0,5.0]) + p = genutil.statistics.percentiles(a,percentiles=[1]) + # REVISIT + def testStatisitcs(self): f=cdms2.open(os.path.join(cdat_info.get_sampledata_path(),'clt.nc')) From 872b55f00f8c9d086d7686b52b9df614fa304783 Mon Sep 17 00:00:00 2001 From: Jason Boutte Date: Wed, 1 Jul 2020 20:02:52 -0700 Subject: [PATCH 02/15] Cleans up setup.py formatting --- setup.py | 66 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 35 insertions(+), 31 deletions(-) diff --git a/setup.py b/setup.py index f555538..e9001b0 100755 --- a/setup.py +++ b/setup.py @@ -1,36 +1,40 @@ -from distutils.core import setup, Extension -import os,sys +from setuptools import setup, Extension + +# from distutils.core import setup, Extension +import os +import sys import numpy + try: import cdat_info - Version=cdat_info.Version -except: - Version="???" -print("VERSION:",Version) -setup (name = "genutil", - version=Version, - author='LLNL', - description = "General utilities for scientific computing", - url = "http://uvcdat.llnl.gov/software", - packages = ['genutil','unidata'], - package_dir = {'genutil': 'Lib', 'unidata':"unidata"}, - include_dirs = ['Include', numpy.lib.utils.get_include()], - ext_modules = [ - Extension('genutil.array_indexing', - ['Src/array_indexing.c',] - ), - Extension('genutil.udunits_wrap', - ['Src/udunits_wrap.c', - ## 'Src/utparse.c', - ## 'Src/utlib.c', - ## 'Src/utscan.c', - ], - include_dirs = [os.path.join(sys.prefix,'include')], - library_dirs = [os.path.join(sys.prefix,'lib')], - libraries=['udunits2','expat'] - ) - + Version = cdat_info.Version +except Exception: + Version = "???" +print("VERSION:", Version) +setup( + name="genutil", + version=Version, + author="LLNL", + description="General utilities for scientific computing", + url="http://uvcdat.llnl.gov/software", + packages=["genutil", "unidata"], + package_dir={"genutil": "Lib", "unidata": "unidata"}, + include_dirs=["Include", numpy.lib.utils.get_include()], + ext_modules=[ + Extension("genutil.array_indexing", ["Src/array_indexing.c"]), + Extension( + "genutil.udunits_wrap", + [ + "Src/udunits_wrap.c", + # 'Src/utparse.c', + # 'Src/utlib.c', + # 'Src/utscan.c', + ], + include_dirs=[os.path.join(sys.prefix, "include")], + library_dirs=[os.path.join(sys.prefix, "lib")], + libraries=["udunits2", "expat"], + ), ], - data_files=[('share/genutil', ('share/test_data_files.txt',))] - ) + data_files=[("share/genutil", ("share/test_data_files.txt",))], +) From a483a45e758b12b0967882274f9bf57f1199e8e6 Mon Sep 17 00:00:00 2001 From: Jason Boutte Date: Thu, 2 Jul 2020 21:03:41 -0700 Subject: [PATCH 03/15] Fixes converting 1d to 2d array --- Lib/statistics.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Lib/statistics.py b/Lib/statistics.py index 90cdbd9..7affef3 100644 --- a/Lib/statistics.py +++ b/Lib/statistics.py @@ -1668,6 +1668,10 @@ def geometricmean(x, axis=0, max_pct_missing=100.): def _percentiles(out, percent): + # change 1d to 2d array + if out.ndim == 1: + out = out.reshape((1,)+out.shape) + if cdms2.isVariable(out): out = MV2.sort(out, axis=0).asma() ns = MV2.count(out, axis=0).asma() @@ -1698,8 +1702,6 @@ def _percentiles(out, percent): ii = numpy.where(numpy.equal(ii, ns), ns - 1, ii) if numpy.ndim(ii) > 0: ii = ii.astype(numpy.int) -# tmp = (p-Ai)/(Aii-Ai)*array_indexing.extract(out,ii) + \ -# (Aii-p)/(Aii-Ai)*array_indexing.extract(out,i) tmp = (p - Ai) / (Aii - Ai) * arrayindexing.get(out, ii) + \ (Aii - p) / (Aii - Ai) * arrayindexing.get(out, i) From bed83554d6e09feed79625b93d7f06036164ca56 Mon Sep 17 00:00:00 2001 From: Jason Boutte Date: Thu, 2 Jul 2020 21:05:27 -0700 Subject: [PATCH 04/15] Fixes raising error when axis is out of bounds and adds some unittests for percentile --- Lib/stats_checker.py | 102 ++++++++++++++++-------- tests/test_genutil_statistics.py | 129 ++++++++++++++++++++++--------- 2 files changed, 162 insertions(+), 69 deletions(-) diff --git a/Lib/stats_checker.py b/Lib/stats_checker.py index 4740337..4b8eff1 100644 --- a/Lib/stats_checker.py +++ b/Lib/stats_checker.py @@ -4,7 +4,7 @@ from .averager import __check_weightoptions -class StatisticsError (Exception): +class StatisticsError(Exception): def __init__(self, args=None): """Create an exception""" self.args = args @@ -12,6 +12,7 @@ def __init__(self, args=None): def __str__(self): """Calculate the string representation""" return str(self.args) + __repr__ = __str__ @@ -32,10 +33,10 @@ def __makeweights(x, w, axes): if not numpy.ma.isarray(w): # Ok Krishna returned a list of 1D arrays.... Let's put it together axs = x.getAxisList() - axes = cdms2.order2index(axs, axes)[:len(cdms2.orderparse(axes))] + axes = cdms2.order2index(axs, axes)[: len(cdms2.orderparse(axes))] endax = [] for i in range(len(axes)): - if w[i] == 'unweighted': + if w[i] == "unweighted": w[i] = numpy.ma.ones(len(axs[axes[i]]), dtype=x.dtype.char) if i == 0: wo = w[i] @@ -45,8 +46,8 @@ def __makeweights(x, w, axes): endax.append(axs[axes[i]]) w = cdms2.MV2.array(wo) w.setAxisList(endax) -# else: -# w.setAxisList(x.getAxisList()) + # else: + # w.setAxisList(x.getAxisList()) return w @@ -64,20 +65,21 @@ def __checker(x, y, w, axes, smally=0): x = numpy.ma.array(x, copy=0) if not numpy.ma.isarray(y) and y is not None: y = numpy.ma.array(y, copy=0) - if not numpy.ma.isarray( - w) and w is not None and not isinstance(w, type('')): - if not isinstance(w[0], type('')): + if not numpy.ma.isarray(w) and w is not None and not isinstance(w, type("")): + if not isinstance(w[0], type("")): w = numpy.ma.array(w, copy=0) else: if not xismv: raise StatisticsError( - 'Error if weights are a list then x must be an MV2 !!!') + "Error if weights are a list then x must be an MV2 !!!" + ) w = __makeweights(x, w, axes) wismv = 1 elif w is not None: if not xismv: raise StatisticsError( - 'Error if weights are a list then x must be an MV2 !!!') + "Error if weights are a list then x must be an MV2 !!!" + ) w = __makeweights(x, w, axes) wismv = 1 @@ -85,8 +87,12 @@ def __checker(x, y, w, axes, smally=0): # We didn't pass all MV2s shapes have to match (unless None) if smally == 0: if x.shape != numpy.ma.shape(y) and y is not None: - raise StatisticsError('Error x and y shape do not match !' + - str(x.shape) + ',' + str(numpy.ma.shape(y))) + raise StatisticsError( + "Error x and y shape do not match !" + + str(x.shape) + + "," + + str(numpy.ma.shape(y)) + ) else: shy = list(y.shape) shy2 = y.shape @@ -96,7 +102,9 @@ def __checker(x, y, w, axes, smally=0): for i in axes: myaxes.append(eval(i)) elif isinstance(axes, int): - myaxes = [axes, ] + myaxes = [ + axes, + ] else: myaxes = list(axes) for anaxis in myaxes[::-1]: @@ -109,25 +117,42 @@ def __checker(x, y, w, axes, smally=0): sh[i] = myaxes[i] y = numpy.ma.transpose(y, sh) if x.shape != numpy.ma.shape(y) and y is not None: - raise StatisticsError('Error x and y shape do not match (y shouldbe 1D less than x) !' + - str(x.shape) + ',' + str(shy2) + ' Remember y must be 1D less than x') + raise StatisticsError( + "Error x and y shape do not match (y shouldbe 1D less than x) !" + + str(x.shape) + + "," + + str(shy2) + + " Remember y must be 1D less than x" + ) if x.shape != numpy.ma.shape(w) and w is not None: - raise StatisticsError('Error x and weights shape do not match !' + - str(x.shape) + ',' + str(numpy.ma.shape(w)) + - ' ATTENTION if you are trynig to pass a list of 1D arrays' + - 'for each dim, then x must be an MV2 !!!') + raise StatisticsError( + "Error x and weights shape do not match !" + + str(x.shape) + + "," + + str(numpy.ma.shape(w)) + + " ATTENTION if you are trynig to pass a list of 1D arrays" + + "for each dim, then x must be an MV2 !!!" + ) if not isinstance(axes, type([])): axes = cdms2.orderparse(str(axes)) for i in axes: if len(x.shape) < i: - raise StatisticsError('Error you have ' + str(len(x.shape)) + - ' dimensions and try to work on dim:' + str(i)) + raise StatisticsError( + "Error you have " + + str(len(x.shape)) + + " dimensions and try to work on dim:" + + str(i) + ) else: if y is not None: x, y = grower(x, y) if x.shape != y.shape: raise StatisticsError( - 'Error x and y have different shapes' + str(x.shape) + ', ' + str(y.shape)) + "Error x and y have different shapes" + + str(x.shape) + + ", " + + str(y.shape) + ) ax = x.getAxisList() xorder = x.getOrder(ids=1) # Now grows w @@ -136,11 +161,16 @@ def __checker(x, y, w, axes, smally=0): for o in worder: if o not in xorder: raise StatisticsError( - 'Error weights have a dimension that is neither in x or y:' + o) + "Error weights have a dimension that is neither in x or y:" + o + ) x, w = grower(x, w) if x.shape != w.shape: raise StatisticsError( - 'Error x and weights have different shapes' + str(x.shape) + ', ' + str(w.shape)) + "Error x and weights have different shapes" + + str(x.shape) + + ", " + + str(w.shape) + ) # Last thing convert the axes input to numbers if isinstance(axes, type(1)): axes = str(axes) @@ -149,24 +179,24 @@ def __checker(x, y, w, axes, smally=0): naxes = len(axesparse) for i in range(naxes): o = axesparse[i] - if isinstance(o, type('')): + if isinstance(o, type("")): for j in range(len(xorder)): if xorder[j] == o: axesparse[i] = j # Well it must be a name for x y t.... - if isinstance(axesparse[i], type('')): + if isinstance(axesparse[i], type("")): for j in range(len(x.shape)): if o[1:-1] == x.getAxis(j).id: axesparse[i] = j # Everything failed the axis id must be not existing in the # slab... - if isinstance(axesparse[i], type('')): + if isinstance(axesparse[i], type("")): raise StatisticsError( - 'Error axis id :' + - o + - ' not found in first slab: ' + - x.getOrder( - ids=1)) + "Error axis id :" + + o + + " not found in first slab: " + + x.getOrder(ids=1) + ) axes = axesparse # Now we have array those shape match, and a nice list of axes let's keep # going @@ -176,8 +206,12 @@ def __checker(x, y, w, axes, smally=0): xorder = list(range(len(x.shape))) forder = [] for i in range(naxes): - forder.append(axes[i]) - n0 = n0 * xsh[axes[i]] + a = axes[i] + forder.append(a) + try: + n0 = n0 * xsh[a] + except IndexError: + raise Exception("Axis {} is out of bounds for dimension {}".format(a, len(xsh))) fsh = [n0] ax2 = [] for i in range(len(x.shape)): diff --git a/tests/test_genutil_statistics.py b/tests/test_genutil_statistics.py index e6501c9..fb6f888 100644 --- a/tests/test_genutil_statistics.py +++ b/tests/test_genutil_statistics.py @@ -1,63 +1,122 @@ from __future__ import print_function -import cdms2,genutil,os,sys +import cdms2 +import genutil +import os import unittest import cdat_info import numpy + dump = False + class GENUTIL(unittest.TestCase): - def assertArraysEqual(self,A,nm,skip=False, dump=dump): + def assertArraysEqual(self, A, nm, skip=False, dump=dump): B = self.good(nm) - print("A-B max difference", numpy.abs(A-B).max(), skip) - print("A-B % difference", numpy.abs((A-B)/A).max(), skip) + print("A-B max difference", numpy.abs(A - B).max(), skip) + print("A-B % difference", numpy.abs((A - B) / A).max(), skip) if dump: self.out.write(A, id=nm) self.out.sync() if not skip: - self.assertTrue(numpy.ma.allclose(A,B)) + self.assertTrue(numpy.ma.allclose(A, B)) def testPercentiles(self): - a = numpy.array([1.0,2.0,3.0,4.0,5.0]) - p = genutil.statistics.percentiles(a,percentiles=[1]) - # REVISIT + a = numpy.arange(1.0, 6.0) + p = genutil.statistics.percentiles(a) + + assert (p == a).all() + + with self.assertRaises(Exception): + p = genutil.statistics.percentiles(a, axis=1) + + aa = numpy.array([a for _ in range(10)]) + + p = genutil.statistics.percentiles(aa) + + assert (p == aa).all() + + p = genutil.statistics.percentiles(aa, axis=1) + + assert (p == numpy.full((1, 10), 3.0)).all() + + p = genutil.statistics.percentiles(aa, [0, 50, 100], axis=1) + + assert (p == numpy.array([numpy.full((10,), x) for x in (1.0, 3.0, 5.0)])).all() + + a = numpy.arange(1.0, 6.0).reshape((5, 1)) + + p = genutil.statistics.percentiles(a) + + assert (p == numpy.array([[3.0]])).all() def testStatisitcs(self): - f=cdms2.open(os.path.join(cdat_info.get_sampledata_path(),'clt.nc')) + f = cdms2.open(os.path.join(cdat_info.get_sampledata_path(), "clt.nc")) - u=f('u',time=slice(0,1),level=slice(0,1),squeeze=1) - v=f('v',time=slice(0,1),plev1=slice(0,1),squeeze=1) + u = f("u", time=slice(0, 1), level=slice(0, 1), squeeze=1) + v = f("v", time=slice(0, 1), plev1=slice(0, 1), squeeze=1) - self.good = cdms2.open(os.path.join(cdat_info.get_sampledata_path(),"genutil_statistics.nc")) + self.good = cdms2.open( + os.path.join(cdat_info.get_sampledata_path(), "genutil_statistics.nc") + ) if dump: - self.out = cdms2.open("genutil_statistics_new.nc","w") - print('Lagged correlation') + self.out = cdms2.open("genutil_statistics_new.nc", "w") + print("Lagged correlation") nm = "lagged_corr" - self.assertArraysEqual(genutil.statistics.laggedcorrelation(u,v,axis=0), nm+"_1") - self.assertArraysEqual(genutil.statistics.laggedcorrelation(u,v,axis=0,lag=4), nm+"_2") - self.assertArraysEqual(genutil.statistics.laggedcorrelation(u,v,axis=0,lag=4,noloop=1), nm+"_3") - self.assertArraysEqual(genutil.statistics.laggedcorrelation(u,v,axis=0,lag=[4,8,10]), nm+"_4") + self.assertArraysEqual( + genutil.statistics.laggedcorrelation(u, v, axis=0), nm + "_1" + ) + self.assertArraysEqual( + genutil.statistics.laggedcorrelation(u, v, axis=0, lag=4), nm + "_2" + ) + self.assertArraysEqual( + genutil.statistics.laggedcorrelation(u, v, axis=0, lag=4, noloop=1), + nm + "_3", + ) + self.assertArraysEqual( + genutil.statistics.laggedcorrelation(u, v, axis=0, lag=[4, 8, 10]), + nm + "_4", + ) - - print('Lagged covariance') + print("Lagged covariance") nm = "lagged_cov" - self.assertArraysEqual(genutil.statistics.laggedcovariance(u,v,axis=0), nm+"_1") - self.assertArraysEqual(genutil.statistics.laggedcovariance(u,v,axis=0,lag=4), nm+"_2") - self.assertArraysEqual(genutil.statistics.laggedcovariance(u,v,axis=0,lag=4,noloop=1), nm+"_3") - self.assertArraysEqual(genutil.statistics.laggedcovariance(u,v,axis=0,lag=[4,8,10]), nm+"_4") + self.assertArraysEqual( + genutil.statistics.laggedcovariance(u, v, axis=0), nm + "_1" + ) + self.assertArraysEqual( + genutil.statistics.laggedcovariance(u, v, axis=0, lag=4), nm + "_2" + ) + self.assertArraysEqual( + genutil.statistics.laggedcovariance(u, v, axis=0, lag=4, noloop=1), + nm + "_3", + ) + self.assertArraysEqual( + genutil.statistics.laggedcovariance(u, v, axis=0, lag=[4, 8, 10]), nm + "_4" + ) - print('Auto correlation') + print("Auto correlation") nm = "auto_corr" - self.assertArraysEqual(genutil.statistics.autocorrelation(u,axis=0), nm+"_1") - self.assertArraysEqual(genutil.statistics.autocorrelation(u,axis=0,lag=4), nm+"_2") - self.assertArraysEqual(genutil.statistics.autocorrelation(u,axis=0,lag=4,noloop=1), nm+"_3") - self.assertArraysEqual(genutil.statistics.autocorrelation(u,axis=0,lag=[4,8,10]), nm+"_4") + self.assertArraysEqual(genutil.statistics.autocorrelation(u, axis=0), nm + "_1") + self.assertArraysEqual( + genutil.statistics.autocorrelation(u, axis=0, lag=4), nm + "_2" + ) + self.assertArraysEqual( + genutil.statistics.autocorrelation(u, axis=0, lag=4, noloop=1), nm + "_3" + ) + self.assertArraysEqual( + genutil.statistics.autocorrelation(u, axis=0, lag=[4, 8, 10]), nm + "_4" + ) - print('Auto covariance') + print("Auto covariance") nm = "auto_cov" - self.assertArraysEqual(genutil.statistics.autocovariance(u,axis=0), nm+"_1") - self.assertArraysEqual(genutil.statistics.autocovariance(u,axis=0,lag=4), nm+"_2") - self.assertArraysEqual(genutil.statistics.autocovariance(u,axis=0,lag=4,noloop=1), nm+"_3") - self.assertArraysEqual(genutil.statistics.autocovariance(u,axis=0,lag=[4,8,10]), nm+"_4") + self.assertArraysEqual(genutil.statistics.autocovariance(u, axis=0), nm + "_1") + self.assertArraysEqual( + genutil.statistics.autocovariance(u, axis=0, lag=4), nm + "_2" + ) + self.assertArraysEqual( + genutil.statistics.autocovariance(u, axis=0, lag=4, noloop=1), nm + "_3" + ) + self.assertArraysEqual( + genutil.statistics.autocovariance(u, axis=0, lag=[4, 8, 10]), nm + "_4" + ) f.close() - From 78599fdc20e4d7f79ebe03814945a1af947ad74a Mon Sep 17 00:00:00 2001 From: Jason Boutte Date: Thu, 2 Jul 2020 23:31:17 -0700 Subject: [PATCH 05/15] Adds a few targets and documents all targets --- Makefile | 48 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/Makefile b/Makefile index e5e2a4b..4a470c7 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ .PHONY: conda-info conda-list setup-build setup-tests conda-rerender \ conda-build conda-upload conda-dump-env \ - run-tests run-coveralls + run-tests run-coveralls dev-install dev-environment help -SHELL = /bin/bash +.DEFAULT_GOAL: help os = $(shell uname) pkg_name = genutil @@ -36,48 +36,70 @@ ifndef $(local_repo) local_repo = $(dir $(realpath $(firstword $(MAKEFILE_LIST)))) endif -conda-info: +help: ## Prints help + @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \ + sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' + +dev-environment: export conda_env := build-genutil +dev-environment: export numpy_ver := 1.18 +dev-environment: export py_ver := 3.7 +dev-environment: ## Creates development environment using local conda + source $(conda_activate) base; conda create -y -n $(conda_env) \ + $(foreach x,$(extra_channels),-c $(x)) \ + "python=$(py_ver)" "numpy=$(numpy_ver)" gcc_$(os)-64 \ + cdat_info udunits2 cdms2 cdutil testsrunner + + source $(conda_activate) $(conda_env); \ + conda remove genutil --force + + $(MAKE) dev-install + +dev-install: ## Installs package in development environment + source $(conda_activate) $(conda_env); \ + python setup.py build -g; \ + python setup.py install --record files.txt --force + +conda-info: ## Prints conda info for environment source $(conda_activate) $(conda_env); conda info -conda-list: +conda-list: ## Prints packages installed in environment source $(conda_activate) $(conda_env); conda list -setup-build: +setup-build: ## Setup build ifeq ($(wildcard $(workdir)/conda-recipes),) git clone -b $(conda_recipes_branch) https://github.com/CDAT/conda-recipes $(workdir)/conda-recipes else cd $(workdir)/conda-recipes; git pull endif -setup-tests: +setup-tests: ## Setup test environment source $(conda_activate) base; conda create -y -n $(conda_env) --use-local \ $(foreach x,$(extra_channels),-c $(x)) $(pkg_name) $(foreach x,$(test_pkgs),"$(x)") \ $(foreach x,$(extra_pkgs),"$(x)") -conda-rerender: setup-build +conda-rerender: setup-build ## Rerender conda recipe using conda-smithy python $(workdir)/$(build_script) -w $(workdir) -l $(last_stable) -B 0 -p $(pkg_name) -r $(repo_name) \ -b $(branch) --do_rerender --conda_env $(conda_env) --ignore_conda_missmatch \ --conda_activate $(conda_activate) -conda-build: +conda-build: ## Builds conda recipe mkdir -p $(artifact_dir) python $(workdir)/$(build_script) -w $(workdir) -p $(pkg_name) --build_version $(build_version) \ --do_build --conda_env $(conda_env) --extra_channels $(extra_channels) \ --conda_activate $(conda_activate) $(conda_build_extra) -conda-upload: +conda-upload: ## Upload conda packages in artifcat directory source $(conda_activate) $(conda_env); \ anaconda -t $(conda_upload_token) upload -u $(user) -l $(label) --force $(artifact_dir)/*.tar.bz2 - -conda-dump-env: +conda-dump-env: ## Dumps conda environment mkdir -p $(artifact_dir) source $(conda_activate) $(conda_env); conda list --explicit > $(artifact_dir)/$(conda_env_filename).txt -run-tests: +run-tests: ## Runs the tests using environment source $(conda_activate) $(conda_env); python run_tests.py -H -v2 $(coverage) -run-coveralls: +run-coveralls: ## Runs coveralls using environment source $(conda_activate) $(conda_env); coveralls; From 1831b724c016fad847ffe1f5e1aa3e5bacb3e8c8 Mon Sep 17 00:00:00 2001 From: muryanto1 Date: Mon, 6 Jul 2020 10:04:42 -0700 Subject: [PATCH 06/15] fixed flake8 failures and temporarily upload from this branch --- .circleci/config.yml | 6 +++--- Lib/stats_checker.py | 46 +++++++++++--------------------------------- 2 files changed, 14 insertions(+), 38 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ac7f944..b36af64 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -197,6 +197,6 @@ workflows: - upload: requires: - test - filters: - branches: - only: master +# filters: +# branches: +# only: master diff --git a/Lib/stats_checker.py b/Lib/stats_checker.py index 4b8eff1..b663919 100644 --- a/Lib/stats_checker.py +++ b/Lib/stats_checker.py @@ -88,10 +88,7 @@ def __checker(x, y, w, axes, smally=0): if smally == 0: if x.shape != numpy.ma.shape(y) and y is not None: raise StatisticsError( - "Error x and y shape do not match !" - + str(x.shape) - + "," - + str(numpy.ma.shape(y)) + "Error x and y shape do not match !" + str(x.shape) + "," + str(numpy.ma.shape(y)) ) else: shy = list(y.shape) @@ -117,41 +114,26 @@ def __checker(x, y, w, axes, smally=0): sh[i] = myaxes[i] y = numpy.ma.transpose(y, sh) if x.shape != numpy.ma.shape(y) and y is not None: + err_msg = "Error x and y shape do not match (y shouldbe 1D less than x) !" raise StatisticsError( - "Error x and y shape do not match (y shouldbe 1D less than x) !" - + str(x.shape) - + "," - + str(shy2) - + " Remember y must be 1D less than x" + err_msg + str(x.shape) + "," + str(shy2) + " Remember y must be 1D less than x" ) if x.shape != numpy.ma.shape(w) and w is not None: - raise StatisticsError( - "Error x and weights shape do not match !" - + str(x.shape) - + "," - + str(numpy.ma.shape(w)) - + " ATTENTION if you are trynig to pass a list of 1D arrays" - + "for each dim, then x must be an MV2 !!!" - ) + msg1 = "Error x and weights shape do not match !" + msg2 = " ATTENTION if you are trying to pass a list of 1D arrays for each dim, then x must be an MV2 !!!" + raise StatisticsError(msg1 + str(x.shape) + "," + str(numpy.ma.shape(w)) + msg2) if not isinstance(axes, type([])): axes = cdms2.orderparse(str(axes)) for i in axes: if len(x.shape) < i: - raise StatisticsError( - "Error you have " - + str(len(x.shape)) - + " dimensions and try to work on dim:" - + str(i) - ) + err_msg = "Error you have " + str(len(x.shape)) + " dimensions and try to work on dim:" + str(i) + raise StatisticsError(err_msg) else: if y is not None: x, y = grower(x, y) if x.shape != y.shape: raise StatisticsError( - "Error x and y have different shapes" - + str(x.shape) - + ", " - + str(y.shape) + "Error x and y have different shapes" + str(x.shape) + ", " + str(y.shape) ) ax = x.getAxisList() xorder = x.getOrder(ids=1) @@ -166,10 +148,7 @@ def __checker(x, y, w, axes, smally=0): x, w = grower(x, w) if x.shape != w.shape: raise StatisticsError( - "Error x and weights have different shapes" - + str(x.shape) - + ", " - + str(w.shape) + "Error x and weights have different shapes" + str(x.shape) + ", " + str(w.shape) ) # Last thing convert the axes input to numbers if isinstance(axes, type(1)): @@ -192,10 +171,7 @@ def __checker(x, y, w, axes, smally=0): # slab... if isinstance(axesparse[i], type("")): raise StatisticsError( - "Error axis id :" - + o - + " not found in first slab: " - + x.getOrder(ids=1) + "Error axis id :" + o + " not found in first slab: " + x.getOrder(ids=1) ) axes = axesparse # Now we have array those shape match, and a nice list of axes let's keep From 7226d7189cf391cb011cbf841b36b9ff3766a263 Mon Sep 17 00:00:00 2001 From: Jason Boutte Date: Wed, 8 Jul 2020 22:22:50 -0700 Subject: [PATCH 07/15] Updates dev-environment and dev-install targets --- Makefile | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/Makefile b/Makefile index 4a470c7..704f590 100644 --- a/Makefile +++ b/Makefile @@ -4,6 +4,7 @@ .DEFAULT_GOAL: help +SHELL := /bin/bash os = $(shell uname) pkg_name = genutil repo_name = genutil @@ -40,24 +41,20 @@ help: ## Prints help @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \ sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' -dev-environment: export conda_env := build-genutil -dev-environment: export numpy_ver := 1.18 -dev-environment: export py_ver := 3.7 -dev-environment: ## Creates development environment using local conda - source $(conda_activate) base; conda create -y -n $(conda_env) \ - $(foreach x,$(extra_channels),-c $(x)) \ - "python=$(py_ver)" "numpy=$(numpy_ver)" gcc_$(os)-64 \ - cdat_info udunits2 cdms2 cdutil testsrunner - - source $(conda_activate) $(conda_env); \ - conda remove genutil --force +dev-environment: conda_channels := -c conda-forge +dev-environment: gcc := $(or $(if $(findstring $(shell uname),Darwin),clang_osx-64), gcc_linux-64) +dev-environment: conda_pkgs := $(gcc) "numpy>=1.18" udunits expat pytest ipython cdms2 +dev-environment: export conda_env := genutil-dev +dev-environment: ## Creates dev environment and installs genutil in "Development Mode". If you modify c code you will need to run "make dev-install". + source $(conda_activate) base; conda create -n $(conda_env) \ + $(conda_channels) $(conda_pkgs) $(MAKE) dev-install -dev-install: ## Installs package in development environment +dev-install: ## Installs genutil in "Development Mode", will recompile c code each invocation." source $(conda_activate) $(conda_env); \ - python setup.py build -g; \ - python setup.py install --record files.txt --force + python setup.py build -gf; \ + python setup.py develop conda-info: ## Prints conda info for environment source $(conda_activate) $(conda_env); conda info From 76e4e15ebec40dcda8ec8f2589d9f209203b7f6c Mon Sep 17 00:00:00 2001 From: Jason Boutte Date: Thu, 9 Jul 2020 01:09:29 -0700 Subject: [PATCH 08/15] Disables dev-evnironment for OSX and adds dev-docker that will create dev-environment in docker container. --- Makefile | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 704f590..317563d 100644 --- a/Makefile +++ b/Makefile @@ -13,11 +13,11 @@ build_script = conda-recipes/build_tools/conda_build.py test_pkgs = testsrunner last_stable ?= 8.2 -conda_env ?= base +conda_env ?= genutil-build workdir ?= $(PWD)/workspace branch ?= $(shell git rev-parse --abbrev-ref HEAD) extra_channels ?= cdat/label/nightly conda-forge -conda ?= $(or $(CONDA_EXE),$(shell find /opt/*conda*/bin $(HOME)/*conda* -type f -iname conda)) +conda ?= $(or $(CONDA_EXE),$(shell find /opt/*conda*/bin $(HOME)/*conda*/bin -type f -iname conda)) artifact_dir ?= $(PWD)/artifacts conda_env_filename ?= spec-file build_version ?= 3.7 @@ -41,20 +41,33 @@ help: ## Prints help @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \ sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' +dev-docker: + docker run -d --name genutil-dev -v $(PWD):/src -w /src continuumio/miniconda3 /bin/sleep infinity || exit 0 + docker start genutil-dev + docker exec -it genutil-dev /bin/bash -c "apt update; apt install -y make" + docker exec -it genutil-dev /bin/bash -c "make dev-environment" + docker exec -it genutil-dev /bin/bash -c "conda init bash; echo 'conda activate genutil-dev' >> ~/.bashrc" + docker exec -it genutil-dev /bin/bash + dev-environment: conda_channels := -c conda-forge -dev-environment: gcc := $(or $(if $(findstring $(shell uname),Darwin),clang_osx-64), gcc_linux-64) +dev-environment: gcc := $(or $(if $(findstring os,Darwin),clang_osx-64), gcc_linux-64) dev-environment: conda_pkgs := $(gcc) "numpy>=1.18" udunits expat pytest ipython cdms2 dev-environment: export conda_env := genutil-dev dev-environment: ## Creates dev environment and installs genutil in "Development Mode". If you modify c code you will need to run "make dev-install". - source $(conda_activate) base; conda create -n $(conda_env) \ +ifeq ($(os),Darwin) + $(error dev-environment on OSX is not support) +endif + + source $(conda_activate) base; conda create -y -n $(conda_env) \ $(conda_channels) $(conda_pkgs) $(MAKE) dev-install +dev-install: export conda_env := genutil-dev dev-install: ## Installs genutil in "Development Mode", will recompile c code each invocation." source $(conda_activate) $(conda_env); \ python setup.py build -gf; \ - python setup.py develop + python setup.py install conda-info: ## Prints conda info for environment source $(conda_activate) $(conda_env); conda info From 8cbbff309cfb23b1aabb4120614bc597ac021053 Mon Sep 17 00:00:00 2001 From: Jason Boutte Date: Thu, 9 Jul 2020 17:38:33 -0700 Subject: [PATCH 09/15] Updates makefile --- Makefile | 51 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/Makefile b/Makefile index 317563d..2368155 100644 --- a/Makefile +++ b/Makefile @@ -13,8 +13,9 @@ build_script = conda-recipes/build_tools/conda_build.py test_pkgs = testsrunner last_stable ?= 8.2 -conda_env ?= genutil-build -workdir ?= $(PWD)/workspace +conda_build_env = genutil-build +conda_test_env = genutil-test + branch ?= $(shell git rev-parse --abbrev-ref HEAD) extra_channels ?= cdat/label/nightly conda-forge conda ?= $(or $(CONDA_EXE),$(shell find /opt/*conda*/bin $(HOME)/*conda*/bin -type f -iname conda)) @@ -22,6 +23,18 @@ artifact_dir ?= $(PWD)/artifacts conda_env_filename ?= spec-file build_version ?= 3.7 +# Only populate if workdir is not defined +ifeq ($(origin workdir),undefined) +# Create .tempdir if it doesn't exist +ifeq ($(wildcard $(PWD)/.tempdir),) +workdir := $(shell mktemp -d -t "build_$(pkg_name).XXXXXXXX") +$(shell echo $(workdir) > $(PWD)/.tempdir) +endif + +# Read tempdir +workdir := $(shell cat $(PWD)/.tempdir) +endif + ifneq ($(coverage),) coverage = -c tests/coverage.json --coverage-from-egg endif @@ -33,9 +46,10 @@ conda_activate = $(conda_base)/bin/activate conda_build_extra = --copy_conda_package $(artifact_dir)/ -ifndef $(local_repo) -local_repo = $(dir $(realpath $(firstword $(MAKEFILE_LIST)))) -endif +# Is this needed? +# ifndef $(local_repo) +# local_repo = $(dir $(realpath $(firstword $(MAKEFILE_LIST)))) +# endif help: ## Prints help @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \ @@ -51,9 +65,9 @@ dev-docker: dev-environment: conda_channels := -c conda-forge dev-environment: gcc := $(or $(if $(findstring os,Darwin),clang_osx-64), gcc_linux-64) -dev-environment: conda_pkgs := $(gcc) "numpy>=1.18" udunits expat pytest ipython cdms2 +dev-environment: conda_pkgs := $(gcc) "numpy>=1.18" udunits expat pytest ipython cdms2 $(test_pkgs) dev-environment: export conda_env := genutil-dev -dev-environment: ## Creates dev environment and installs genutil in "Development Mode". If you modify c code you will need to run "make dev-install". +dev-environment: ## Creates dev environment and installs genutil. Will need to run dev-install after any code change. ifeq ($(os),Darwin) $(error dev-environment on OSX is not support) endif @@ -64,16 +78,19 @@ endif $(MAKE) dev-install dev-install: export conda_env := genutil-dev -dev-install: ## Installs genutil in "Development Mode", will recompile c code each invocation." +dev-install: ## Installs genutil in conda environment "genutil-dev" source $(conda_activate) $(conda_env); \ python setup.py build -gf; \ python setup.py install +dev-conda-build: conda_build_extra := --local_repo $(PWD) +dev-conda-build: setup-build conda-rerender conda-build ## Build conda package + conda-info: ## Prints conda info for environment - source $(conda_activate) $(conda_env); conda info + source $(conda_activate) base; conda info conda-list: ## Prints packages installed in environment - source $(conda_activate) $(conda_env); conda list + source $(conda_activate) $(conda_test_env); conda list setup-build: ## Setup build ifeq ($(wildcard $(workdir)/conda-recipes),) @@ -83,33 +100,33 @@ else endif setup-tests: ## Setup test environment - source $(conda_activate) base; conda create -y -n $(conda_env) --use-local \ + source $(conda_activate) base; conda create -y -n $(conda_test_env) --use-local \ $(foreach x,$(extra_channels),-c $(x)) $(pkg_name) $(foreach x,$(test_pkgs),"$(x)") \ $(foreach x,$(extra_pkgs),"$(x)") conda-rerender: setup-build ## Rerender conda recipe using conda-smithy python $(workdir)/$(build_script) -w $(workdir) -l $(last_stable) -B 0 -p $(pkg_name) -r $(repo_name) \ - -b $(branch) --do_rerender --conda_env $(conda_env) --ignore_conda_missmatch \ + -b $(branch) --do_rerender --conda_env $(conda_build_env) --ignore_conda_missmatch \ --conda_activate $(conda_activate) conda-build: ## Builds conda recipe mkdir -p $(artifact_dir) python $(workdir)/$(build_script) -w $(workdir) -p $(pkg_name) --build_version $(build_version) \ - --do_build --conda_env $(conda_env) --extra_channels $(extra_channels) \ + --do_build --conda_env $(conda_build_env) --extra_channels $(extra_channels) \ --conda_activate $(conda_activate) $(conda_build_extra) conda-upload: ## Upload conda packages in artifcat directory - source $(conda_activate) $(conda_env); \ + source $(conda_activate) $(conda_build_env); \ anaconda -t $(conda_upload_token) upload -u $(user) -l $(label) --force $(artifact_dir)/*.tar.bz2 conda-dump-env: ## Dumps conda environment mkdir -p $(artifact_dir) - source $(conda_activate) $(conda_env); conda list --explicit > $(artifact_dir)/$(conda_env_filename).txt + source $(conda_activate) $(conda_test_env); conda list --explicit > $(artifact_dir)/$(conda_env_filename).txt run-tests: ## Runs the tests using environment - source $(conda_activate) $(conda_env); python run_tests.py -H -v2 $(coverage) + source $(conda_activate) $(conda_test_env); python run_tests.py -H -v2 $(coverage) run-coveralls: ## Runs coveralls using environment - source $(conda_activate) $(conda_env); coveralls; + source $(conda_activate) $(conda_test_env); coveralls; From b568452ae212e3ed4ee3762c4795324372aac85d Mon Sep 17 00:00:00 2001 From: muryanto1 Date: Fri, 10 Jul 2020 11:05:25 -0700 Subject: [PATCH 10/15] cleanup Makefile and .circleci/config.yml --- .circleci/config.yml | 49 +++++++------------------------------------- Makefile | 20 +++++++++++------- 2 files changed, 20 insertions(+), 49 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b36af64..a0f8877 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,25 +1,5 @@ version: 2.1 -parameters: - pkg_name: - type: string - default: "genutil" - repo_name: - type: string - default: "genutil" - last_stable: - type: string - default: "8.2" - user: - type: string - default: "cdat" - label: - type: string - default: "nightly" - env_name: - type: string - default: "test_genutil" - aliases: - &setup_env name: setup_env @@ -31,7 +11,6 @@ aliases: export PROJECT_DIR=/home/circleci/project/workdir/linux fi echo "export WORKDIR=$PROJECT_DIR/$PY_VER" >> $BASH_ENV - cat $BASH_ENV source $BASH_ENV mkdir -p $WORKDIR @@ -39,20 +18,17 @@ aliases: name: setup_miniconda command: | source $BASH_ENV - mkdir -p $WORKDIR git clone https://github.com/CDAT/cdat.git $WORKDIR/cdat # install_miniconda.py installs miniconda3 under $WORKDIR/miniconda python $WORKDIR/cdat/scripts/install_miniconda.py -w $WORKDIR -p 'py3' - - &conda_rerender name: conda_rerender command: | source $BASH_ENV source $WORKDIR/miniconda/etc/profile.d/conda.sh conda activate base - echo "make conda-rerender conda=$WORKDIR/miniconda/bin/conda workdir=$WORKDIR last_stable=$LAST_STABLE branch=$CIRCLE_BRANCH" - make conda-rerender conda=$WORKDIR/miniconda/bin/conda workdir=$WORKDIR last_stable=$LAST_STABLE branch=$CIRCLE_BRANCH + make conda-rerender workdir=$WORKDIR branch=$CIRCLE_BRANCH - &conda_build name: conda_build @@ -62,7 +38,7 @@ aliases: conda activate base os=`uname` artifacts_dir="artifacts/artifacts.${os}.py_${PY_VER}" - make conda-build conda=$WORKDIR/miniconda/bin/conda workdir=$WORKDIR artifact_dir=$PWD/$artifacts_dir build_version=$PY_VER + make conda-build workdir=$WORKDIR artifact_dir=$artifacts_dir build_version=$PY_VER - &setup_run_tests name: setup_run_tests @@ -72,19 +48,15 @@ aliases: conda activate base export CONDA_PY_VER="python=$PY_VER" export LIBNETCDF_VER="libnetcdf=*=${LIBNETCDF}_*" - - echo "make setup-tests conda=$WORKDIR/miniconda/bin/conda conda_env=$ENV_NAME extra_pkgs=\"$CONDA_PY_VER $LIBNETCDF_VER $COVERAGE_PKGS\"" - make setup-tests conda=$WORKDIR/miniconda/bin/conda conda_env=$ENV_NAME extra_pkgs="$CONDA_PY_VER $LIBNETCDF_VER $COVERAGE_PKGS" - - make conda-dump-env conda=$WORKDIR/miniconda/bin/conda conda_env=$ENV_NAME artifact_dir=$PWD/spec_artifacts conda_env_filename=$CIRCLE_JOB + make setup-tests workdir=$WORKDIR extra_pkgs="$CONDA_PY_VER $LIBNETCDF_VER $COVERAGE_PKGS" + make conda-dump-env workdir=$WORKDIR artifact_dir=$PWDspec_artifacts conda_env_filename=$CIRCLE_JOB - &run_tests name: run_tests command: | source $BASH_ENV source $WORKDIR/miniconda/etc/profile.d/conda.sh - conda activate $ENV_NAME - make run-tests conda=$WORKDIR/miniconda/bin/conda conda_env=$ENV_NAME workdir=$WORKDIR + make run-tests workdir=$WORKDIR no_output_timeout: 10m - &conda_upload @@ -93,8 +65,8 @@ aliases: source $BASH_ENV source $WORKDIR/miniconda/etc/profile.d/conda.sh conda activate base - UPLOAD_OPTIONS="conda_upload_token=$CONDA_UPLOAD_TOKEN user=$USER label=$LABEL" - make conda-upload $UPLOAD_OPTIONS conda=$WORKDIR/miniconda/bin/conda artifact_dir="$PWD/artifacts/*/" + UPLOAD_OPTIONS="conda_upload_token=$CONDA_UPLOAD_TOKEN" + make conda-upload workdir=$WORKDIR $UPLOAD_OPTIONS artifact_dir="artifacts/*/" executors: linux: @@ -113,9 +85,6 @@ jobs: type: string executor: << parameters.os >> environment: - PKG_NAME: << pipeline.parameters.pkg_name >> - REPO_NAME: << pipeline.parameters.repo_name >> - LAST_STABLE: << pipeline.parameters.last_stable >> PY_VER: << parameters.py_ver >> steps: - checkout @@ -141,8 +110,6 @@ jobs: type: string executor: << parameters.os >> environment: - PKG_NAME: << pipeline.parameters.pkg_name >> - ENV_NAME: << pipeline.parameters.env_name >> PY_VER: << parameters.py_ver >> LIBNETCDF: << parameters.libnetcdf >> steps: @@ -164,8 +131,6 @@ jobs: machine: image: circleci/classic:latest environment: - USER: << pipeline.parameters.user >> - LABEL: << pipeline.parameters.label >> PY_VER: "3.7" steps: - checkout diff --git a/Makefile b/Makefile index 2368155..6f61cad 100644 --- a/Makefile +++ b/Makefile @@ -8,18 +8,22 @@ SHELL := /bin/bash os = $(shell uname) pkg_name = genutil repo_name = genutil + +user ?= cdat +label ?= nightly + build_script = conda-recipes/build_tools/conda_build.py test_pkgs = testsrunner last_stable ?= 8.2 -conda_build_env = genutil-build -conda_test_env = genutil-test +conda_test_env = test-$(pkg_name) +conda_build_env = build-$(pkg_name) branch ?= $(shell git rev-parse --abbrev-ref HEAD) extra_channels ?= cdat/label/nightly conda-forge conda ?= $(or $(CONDA_EXE),$(shell find /opt/*conda*/bin $(HOME)/*conda*/bin -type f -iname conda)) -artifact_dir ?= $(PWD)/artifacts + conda_env_filename ?= spec-file build_version ?= 3.7 @@ -35,6 +39,8 @@ endif workdir := $(shell cat $(PWD)/.tempdir) endif +artif_dir = $(workdir)/$(artifact_dir) + ifneq ($(coverage),) coverage = -c tests/coverage.json --coverage-from-egg endif @@ -44,7 +50,7 @@ conda_recipes_branch ?= master conda_base = $(patsubst %/bin/conda,%,$(conda)) conda_activate = $(conda_base)/bin/activate -conda_build_extra = --copy_conda_package $(artifact_dir)/ +conda_build_extra = --copy_conda_package $(artif_dir)/ # Is this needed? # ifndef $(local_repo) @@ -66,7 +72,7 @@ dev-docker: dev-environment: conda_channels := -c conda-forge dev-environment: gcc := $(or $(if $(findstring os,Darwin),clang_osx-64), gcc_linux-64) dev-environment: conda_pkgs := $(gcc) "numpy>=1.18" udunits expat pytest ipython cdms2 $(test_pkgs) -dev-environment: export conda_env := genutil-dev +dev-environment: export conda_env := dev-$(pkg_name) dev-environment: ## Creates dev environment and installs genutil. Will need to run dev-install after any code change. ifeq ($(os),Darwin) $(error dev-environment on OSX is not support) @@ -110,7 +116,7 @@ conda-rerender: setup-build ## Rerender conda recipe using conda-smithy --conda_activate $(conda_activate) conda-build: ## Builds conda recipe - mkdir -p $(artifact_dir) + mkdir -p $(artif_dir) python $(workdir)/$(build_script) -w $(workdir) -p $(pkg_name) --build_version $(build_version) \ --do_build --conda_env $(conda_build_env) --extra_channels $(extra_channels) \ @@ -118,7 +124,7 @@ conda-build: ## Builds conda recipe conda-upload: ## Upload conda packages in artifcat directory source $(conda_activate) $(conda_build_env); \ - anaconda -t $(conda_upload_token) upload -u $(user) -l $(label) --force $(artifact_dir)/*.tar.bz2 + anaconda -t $(conda_upload_token) upload -u $(user) -l $(label) --force $(artif_dir)/*.tar.bz2 conda-dump-env: ## Dumps conda environment mkdir -p $(artifact_dir) From 1686d51b7a662a18f54aa8397f056d7ca0e95ace Mon Sep 17 00:00:00 2001 From: Jason Boutte Date: Fri, 10 Jul 2020 13:22:13 -0700 Subject: [PATCH 11/15] Fixes chenking if workdir is defined --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 6f61cad..ac7c757 100644 --- a/Makefile +++ b/Makefile @@ -28,7 +28,7 @@ conda_env_filename ?= spec-file build_version ?= 3.7 # Only populate if workdir is not defined -ifeq ($(origin workdir),undefined) +ifeq ($(workdir),) # Create .tempdir if it doesn't exist ifeq ($(wildcard $(PWD)/.tempdir),) workdir := $(shell mktemp -d -t "build_$(pkg_name).XXXXXXXX") From c27ab814e27761ba4565c516d17403f5ec0840cb Mon Sep 17 00:00:00 2001 From: Jason Boutte Date: Fri, 10 Jul 2020 13:22:44 -0700 Subject: [PATCH 12/15] Fixes dev environment name --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index ac7c757..f9c26aa 100644 --- a/Makefile +++ b/Makefile @@ -66,7 +66,7 @@ dev-docker: docker start genutil-dev docker exec -it genutil-dev /bin/bash -c "apt update; apt install -y make" docker exec -it genutil-dev /bin/bash -c "make dev-environment" - docker exec -it genutil-dev /bin/bash -c "conda init bash; echo 'conda activate genutil-dev' >> ~/.bashrc" + docker exec -it genutil-dev /bin/bash -c "conda init bash; echo 'conda activate dev-$(pkg_name)' >> ~/.bashrc" docker exec -it genutil-dev /bin/bash dev-environment: conda_channels := -c conda-forge @@ -83,7 +83,7 @@ endif $(MAKE) dev-install -dev-install: export conda_env := genutil-dev +dev-install: export conda_env := dev-$(pkg_name) dev-install: ## Installs genutil in conda environment "genutil-dev" source $(conda_activate) $(conda_env); \ python setup.py build -gf; \ From c7ab64515e580c52ddf10da76f6b7995207cad7e Mon Sep 17 00:00:00 2001 From: Jason Boutte Date: Fri, 10 Jul 2020 13:23:07 -0700 Subject: [PATCH 13/15] Fixes add cdat nighly channel for test_pkgs --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index f9c26aa..6323971 100644 --- a/Makefile +++ b/Makefile @@ -69,7 +69,7 @@ dev-docker: docker exec -it genutil-dev /bin/bash -c "conda init bash; echo 'conda activate dev-$(pkg_name)' >> ~/.bashrc" docker exec -it genutil-dev /bin/bash -dev-environment: conda_channels := -c conda-forge +dev-environment: conda_channels := -c cdat/label/nightly -c conda-forge dev-environment: gcc := $(or $(if $(findstring os,Darwin),clang_osx-64), gcc_linux-64) dev-environment: conda_pkgs := $(gcc) "numpy>=1.18" udunits expat pytest ipython cdms2 $(test_pkgs) dev-environment: export conda_env := dev-$(pkg_name) From de202e61664900ddbaccb21d95b3b9b85206da4b Mon Sep 17 00:00:00 2001 From: muryanto1 Date: Fri, 10 Jul 2020 14:52:46 -0700 Subject: [PATCH 14/15] more cleanup on Makefile --- .circleci/config.yml | 2 +- Makefile | 22 +++++++++++++--------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index a0f8877..ea0c416 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -49,7 +49,7 @@ aliases: export CONDA_PY_VER="python=$PY_VER" export LIBNETCDF_VER="libnetcdf=*=${LIBNETCDF}_*" make setup-tests workdir=$WORKDIR extra_pkgs="$CONDA_PY_VER $LIBNETCDF_VER $COVERAGE_PKGS" - make conda-dump-env workdir=$WORKDIR artifact_dir=$PWDspec_artifacts conda_env_filename=$CIRCLE_JOB + make conda-dump-env workdir=$WORKDIR artifact_dir=$PWD/spec_artifacts conda_env_filename=$CIRCLE_JOB - &run_tests name: run_tests diff --git a/Makefile b/Makefile index 6323971..d8872c7 100644 --- a/Makefile +++ b/Makefile @@ -19,6 +19,7 @@ last_stable ?= 8.2 conda_test_env = test-$(pkg_name) conda_build_env = build-$(pkg_name) +conda_dev_env = dev-$(pkg_name) branch ?= $(shell git rev-parse --abbrev-ref HEAD) extra_channels ?= cdat/label/nightly conda-forge @@ -62,17 +63,17 @@ help: ## Prints help sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' dev-docker: - docker run -d --name genutil-dev -v $(PWD):/src -w /src continuumio/miniconda3 /bin/sleep infinity || exit 0 - docker start genutil-dev - docker exec -it genutil-dev /bin/bash -c "apt update; apt install -y make" - docker exec -it genutil-dev /bin/bash -c "make dev-environment" - docker exec -it genutil-dev /bin/bash -c "conda init bash; echo 'conda activate dev-$(pkg_name)' >> ~/.bashrc" - docker exec -it genutil-dev /bin/bash + docker run -d --name $(conda_dev_env) -v $(PWD):/src -w /src continuumio/miniconda3 /bin/sleep infinity || exit 0 + docker start $(conda_dev_env) + docker exec -it $(conda_dev_env) /bin/bash -c "apt update; apt install -y make" + docker exec -it $(conda_dev_env) /bin/bash -c "make dev-environment" + docker exec -it $(conda_dev_env) /bin/bash -c "conda init bash; echo 'conda activate $(conda_dev_env)' >> ~/.bashrc" + docker exec -it $(conda_dev_env) /bin/bash dev-environment: conda_channels := -c cdat/label/nightly -c conda-forge dev-environment: gcc := $(or $(if $(findstring os,Darwin),clang_osx-64), gcc_linux-64) dev-environment: conda_pkgs := $(gcc) "numpy>=1.18" udunits expat pytest ipython cdms2 $(test_pkgs) -dev-environment: export conda_env := dev-$(pkg_name) +dev-environment: export conda_env := $(conda_dev_env) dev-environment: ## Creates dev environment and installs genutil. Will need to run dev-install after any code change. ifeq ($(os),Darwin) $(error dev-environment on OSX is not support) @@ -83,8 +84,8 @@ endif $(MAKE) dev-install -dev-install: export conda_env := dev-$(pkg_name) -dev-install: ## Installs genutil in conda environment "genutil-dev" +dev-install: export conda_env := $(conda_dev_env) +dev-install: ## Installs genutil in conda environment "$(conda_dev_env)" source $(conda_activate) $(conda_env); \ python setup.py build -gf; \ python setup.py install @@ -92,6 +93,9 @@ dev-install: ## Installs genutil in conda environment "genutil-dev" dev-conda-build: conda_build_extra := --local_repo $(PWD) dev-conda-build: setup-build conda-rerender conda-build ## Build conda package +dev-run-tests: ## Runs the tests using environment + source $(conda_activate) $(conda_dev_env); python run_tests.py -H -v2 $(coverage) + conda-info: ## Prints conda info for environment source $(conda_activate) base; conda info From 9af45926e1372cb795dc2ea57cad1ec21eb57d06 Mon Sep 17 00:00:00 2001 From: muryanto1 Date: Sat, 11 Jul 2020 14:38:36 -0700 Subject: [PATCH 15/15] only upload from master branch --- .circleci/config.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ea0c416..532bf96 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -162,6 +162,6 @@ workflows: - upload: requires: - test -# filters: -# branches: -# only: master + filters: + branches: + only: master