Skip to content

Commit 1a4a379

Browse files
committed
update vsc-base with support for --confighelp and (unused) bash tab completion support
1 parent eade00a commit 1a4a379

8 files changed

+871
-45
lines changed

optcomplete.bash

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#******************************************************************************\
2+
# * Copyright (c) 2003-2004, Martin Blais
3+
# * All rights reserved.
4+
# *
5+
# * Redistribution and use in source and binary forms, with or without
6+
# * modification, are permitted provided that the following conditions are
7+
# * met:
8+
# *
9+
# * * Redistributions of source code must retain the above copyright
10+
# * notice, this list of conditions and the following disclaimer.
11+
# *
12+
# * * Redistributions in binary form must reproduce the above copyright
13+
# * notice, this list of conditions and the following disclaimer in the
14+
# * documentation and/or other materials provided with the distribution.
15+
# *
16+
# * * Neither the name of the Martin Blais, Furius, nor the names of its
17+
# * contributors may be used to endorse or promote products derived from
18+
# * this software without specific prior written permission.
19+
# *
20+
# * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21+
# * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22+
# * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23+
# * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24+
# * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25+
# * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26+
# * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27+
# * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28+
# * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29+
# * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30+
# * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31+
#******************************************************************************\
32+
#
33+
# stdweird: This is a copy of etc/optcomplete.bash (changeset 17:e0a9131a94cc)
34+
# stdweird: source: https://hg.furius.ca/public/optcomplete
35+
#
36+
# optcomplete harness for bash shell. You then need to tell
37+
# bash to invoke this shell function with a command like
38+
# this:
39+
#
40+
# complete -F _optcomplete <your command>
41+
#
42+
43+
_optcomplete()
44+
{
45+
# needed to let it return _filedir based commands
46+
local cur prev quoted
47+
_get_comp_words_by_ref cur prev
48+
_quote_readline_by_ref "$cur" quoted
49+
_expand || return 0
50+
51+
# call the command with the completion information, then eval it's results so it can call _filedir or similar
52+
# this does have the potential to be a security problem, especially if running as root, but we should trust
53+
# the completions as we're planning to run this script anyway
54+
eval $( \
55+
COMP_LINE=$COMP_LINE COMP_POINT=$COMP_POINT \
56+
COMP_WORDS="${COMP_WORDS[*]}" COMP_CWORD=$COMP_CWORD \
57+
OPTPARSE_AUTO_COMPLETE=1 $1
58+
)
59+
}

setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ def find_rel_test():
9292
packages = easybuild_packages,
9393
package_dir = {'test.framework': "test/framework"},
9494
package_data = {"test.framework": find_rel_test()},
95-
scripts = ["eb"],
95+
scripts = ["eb", "optcomplete.bash"],
9696
data_files = [
9797
('easybuild', ["easybuild/easybuild_config.py"]),
9898
],

vsc/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
Code from https://github.com/hpcugent/vsc-base
22

3-
based on 2f42ee01237ec7a7c1ef0247c2dbd64a5dae086c
3+
based on e48f33454b2f0daa26cdfd720ecb8e5e83259d37

vsc/__init__.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,11 @@
3131
3232
@author: Jens Timmerman (Ghent University)
3333
"""
34+
#from pkgutil import extend_path
35+
36+
# we're not the only ones in this namespace
3437
# avoid that EasyBuild uses vsc package from somewhere else, e.g. a system vsc-base installation
35-
#import pkg_resources
36-
#pkg_resources.declare_namespace(__name__)
38+
#__path__ = extend_path(__path__, __name__) #@ReservedAssignment
3739

3840
# here for backwards compatibility
3941
from vsc.utils import fancylogger

vsc/utils/dateandtime.py

+30-16
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,16 @@
3131
"""
3232

3333
import calendar
34-
import operator
3534
import re
3635
import time as _time
3736
from datetime import tzinfo, timedelta, datetime, date
3837

38+
try:
39+
any([0, 1])
40+
except:
41+
from vsc.utils.missing import any
42+
43+
3944
class FancyMonth:
4045
"""Convenience class for month math"""
4146
def __init__(self, tmpdate=None, year=None, month=None, day=None):
@@ -53,7 +58,6 @@ def __init__(self, tmpdate=None, year=None, month=None, day=None):
5358

5459
self.date = date(year, month, day)
5560

56-
5761
self.first = None
5862
self.last = None
5963
self.nrdays = None
@@ -124,7 +128,7 @@ def get_start_end(self, otherdate):
124128
def number(self, otherdate):
125129
"""Calculate the number of months between this month (date actually) and otherdate
126130
"""
127-
if self.include == False:
131+
if self.include is False:
128132
msg = "number: include=False not implemented"
129133
raise(Exception(msg))
130134
else:
@@ -137,22 +141,22 @@ def number(self, otherdate):
137141

138142
return nr
139143

140-
def get_other(self, shift= -1):
144+
def get_other(self, shift=-1):
141145
"""Return month that is shifted shift months: negative integer is in past, positive is in future"""
142146
new = self.date.year * 12 + self.date.month - 1 + shift
143147
return self.__class__(date(new // 12, new % 12 + 1, 01))
144148

145149
def interval(self, otherdate):
146150
"""Return time ordered list of months between date and otherdate"""
147-
if self.include == False:
151+
if self.include is False:
148152
msg = "interval: include=False not implemented"
149153
raise(Exception(msg))
150154
else:
151155
nr = self.number(otherdate)
152156
startdate, enddate = self.get_start_end(otherdate)
153157

154158
start = self.__class__(startdate)
155-
all_dates = [ start.get_other(m) for m in range(nr)]
159+
all_dates = [start.get_other(m) for m in range(nr)]
156160

157161
return all_dates
158162

@@ -192,6 +196,7 @@ def parser(self, txt):
192196

193197
return res
194198

199+
195200
def date_parser(txt):
196201
"""Parse txt
197202
@@ -208,8 +213,10 @@ def date_parser(txt):
208213
if txt.endswith('MONTH'):
209214
m = FancyMonth()
210215
res = m.parser(txt)
211-
elif reduce(operator.or_, testsupportedmonths): # TODO replace with any()
212-
m = FancyMonth(month=testsupportedmonths.index(True) + 1)
216+
elif any(testsupportedmonths):
217+
# set day=1 or this will fail on day's with an index more then the count of days then the month you want to parse
218+
# e.g. will fail on 31'st when trying to parse april
219+
m = FancyMonth(month=testsupportedmonths.index(True) + 1, day=1)
213220
res = m.parser(txt)
214221
elif txt in reserveddate:
215222
if txt in ('TODAY',):
@@ -229,6 +236,7 @@ def date_parser(txt):
229236

230237
return res
231238

239+
232240
def datetime_parser(txt):
233241
"""Parse txt: tmpdate YYYY-MM-DD HH:MM:SS.mmmmmm in datetime.datetime
234242
- date part is parsed with date_parser
@@ -255,6 +263,7 @@ def datetime_parser(txt):
255263

256264
return res
257265

266+
258267
def timestamp_parser(timestamp):
259268
"""Parse timestamp to datetime"""
260269
return datetime.fromtimestamp(float(timestamp))
@@ -267,8 +276,8 @@ def timestamp_parser(timestamp):
267276
ZERO = timedelta(0)
268277
HOUR = timedelta(hours=1)
269278

270-
# A UTC class.
271279

280+
# A UTC class.
272281
class UTC(tzinfo):
273282
"""UTC"""
274283

@@ -283,12 +292,14 @@ def dst(self, dt):
283292

284293
utc = UTC()
285294

286-
# A class building tzinfo objects for fixed-offset time zones.
287-
# Note that FixedOffset(0, "UTC") is a different way to build a
288-
# UTC tzinfo object.
289295

290296
class FixedOffset(tzinfo):
291-
"""Fixed offset in minutes east from UTC."""
297+
"""Fixed offset in minutes east from UTC.
298+
299+
This is a class for building tzinfo objects for fixed-offset time zones.
300+
Note that FixedOffset(0, "UTC") is a different way to build a
301+
UTC tzinfo object.
302+
"""
292303
def __init__(self, offset, name):
293304
self.__offset = timedelta(minutes=offset)
294305
self.__name = name
@@ -302,17 +313,20 @@ def tzname(self, dt):
302313
def dst(self, dt):
303314
return ZERO
304315

305-
# A class capturing the platform's idea of local time.
306316

307-
STDOFFSET = timedelta(seconds= -_time.timezone)
317+
STDOFFSET = timedelta(seconds=-_time.timezone)
308318
if _time.daylight:
309-
DSTOFFSET = timedelta(seconds= -_time.altzone)
319+
DSTOFFSET = timedelta(seconds=-_time.altzone)
310320
else:
311321
DSTOFFSET = STDOFFSET
312322

313323
DSTDIFF = DSTOFFSET - STDOFFSET
314324

325+
315326
class LocalTimezone(tzinfo):
327+
"""
328+
A class capturing the platform's idea of local time.
329+
"""
316330

317331
def utcoffset(self, dt):
318332
if self._isdst(dt):

0 commit comments

Comments
 (0)