From b2d5bd79c01af8f51ab41a3d7b7a4b996d1944f8 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Sun, 16 Jan 2022 14:15:03 -0700 Subject: Massage test fixtures a bit To avoid double loops, a couple now use fileinput module. CC and CXX tests switch to using general mylink.py fixture instead of locally defined linker script. This did mean that the marker for the mock linker that the script removes had to be harmonized as #link - some were using /*link*/. Could not switch CC/CXX to use the general mycompile.py mock compiler due to difference in intent: mycompile.py is intended to plug in as a *COM variable, which means the whole cmdline is in the caller's control. mycc.py is intended to plug in as CC and mycxx.py as CXX, which means standard os-dependent construction vars will be passed via the default CCCOM and CXXCOM and have to be handled. Signed-off-by: Mats Wichmann --- test/AS/fixture/myas.py | 37 +++++++++---- test/AS/fixture/myas_args.py | 40 +++++++++----- test/CC/CC-fixture/test1.c | 2 +- test/CC/CC-fixture/test2.C | 2 +- test/CC/CC.py | 111 +++++++++++++++---------------------- test/CXX/CXX.py | 127 ++++++++++++++++--------------------------- test/fixture/mycompile.py | 36 ++++++++---- test/fixture/mygcc.py | 31 ++++++----- test/fixture/mylink.py | 27 +++++---- test/fixture/mylink_win32.py | 6 +- test/fixture/myrewrite.py | 13 +++-- 11 files changed, 211 insertions(+), 221 deletions(-) diff --git a/test/AS/fixture/myas.py b/test/AS/fixture/myas.py index 3d05c79..a348ace 100644 --- a/test/AS/fixture/myas.py +++ b/test/AS/fixture/myas.py @@ -1,6 +1,7 @@ import sys -if sys.platform == 'win32': + +def my_win32_as(): args = sys.argv[1:] inf = None while args: @@ -10,29 +11,41 @@ if sys.platform == 'win32': args = args[2:] continue args = args[1:] - if not a[0] in "/-": + if not a[0] in '/-': if not inf: inf = a continue - if a[:3] == '/Fo': out = a[3:] + if a[:3] == '/Fo': + out = a[3:] + with open(inf, 'rb') as ifp, open(out, 'wb') as ofp: - for l in ifp.readlines(): - if l[:3] != b'#as': - ofp.write(l) - sys.exit(0) + for line in ifp: + if not line.startswith(b'#as'): + ofp.write(line) + -else: +def my_as(): import getopt + try: opts, args = getopt.getopt(sys.argv[1:], 'co:') except getopt.GetoptError: # we may be called with --version, just quit if so sys.exit(0) for opt, arg in opts: - if opt == '-o': out = arg + if opt == '-o': + out = arg + if args: with open(args[0], 'rb') as ifp, open(out, 'wb') as ofp: - for l in ifp.readlines(): - if l[:3] != b'#as': - ofp.write(l) + for line in ifp: + if not line.startswith(b'#as'): + ofp.write(line) + + +if __name__ == "__main__": + if sys.platform == 'win32': + my_win32_as() + else: + my_as() sys.exit(0) diff --git a/test/AS/fixture/myas_args.py b/test/AS/fixture/myas_args.py index 24d68dc..7a5e6fa 100644 --- a/test/AS/fixture/myas_args.py +++ b/test/AS/fixture/myas_args.py @@ -1,6 +1,7 @@ import sys -if sys.platform == 'win32': + +def my_win32_as(): args = sys.argv[1:] inf = None optstring = '' @@ -21,25 +22,38 @@ if sys.platform == 'win32': out = a[3:] continue optstring = optstring + ' ' + a + with open(inf, 'rb') as ifp, open(out, 'wb') as ofp: - ofp.write(bytearray(optstring + "\n",'utf-8')) - for l in ifp.readlines(): - if l[:3] != b'#as': - ofp.write(l) - sys.exit(0) -else: + optstring = optstring + "\n" + ofp.write(optstring.encode('utf-8')) + for line in ifp: + if not line.startswith(b'#as'): + ofp.write(line) + + +def my_as(): import getopt + opts, args = getopt.getopt(sys.argv[1:], 'co:x') optstring = '' for opt, arg in opts: - if opt == '-o': out = arg - else: optstring = optstring + ' ' + opt + if opt == '-o': + out = arg + else: + optstring = optstring + ' ' + opt with open(args[0], 'rb') as ifp, open(out, 'wb') as ofp: - ofp.write(bytearray(optstring + "\n",'utf-8')) - for l in ifp.readlines(): - if l[:3] != b'#as': - ofp.write(l) + optstring = optstring + "\n" + ofp.write(optstring.encode('utf-8')) + for line in ifp: + if not line.startswith(b'#as'): + ofp.write(line) + +if __name__ == "__main__": + if sys.platform == 'win32': + my_win32_as() + else: + my_as() sys.exit(0) diff --git a/test/CC/CC-fixture/test1.c b/test/CC/CC-fixture/test1.c index 7535b0a..6748e2c 100644 --- a/test/CC/CC-fixture/test1.c +++ b/test/CC/CC-fixture/test1.c @@ -1,3 +1,3 @@ This is a .c file. /*cc*/ -/*link*/ +#link diff --git a/test/CC/CC-fixture/test2.C b/test/CC/CC-fixture/test2.C index a1ee9e3..388133b 100644 --- a/test/CC/CC-fixture/test2.C +++ b/test/CC/CC-fixture/test2.C @@ -1,3 +1,3 @@ This is a .C file. /*cc*/ -/*link*/ +#link diff --git a/test/CC/CC.py b/test/CC/CC.py index 6363273..c2562d5 100644 --- a/test/CC/CC.py +++ b/test/CC/CC.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,46 +22,27 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import os import sys import TestSCons _python_ = TestSCons._python_ -_exe = TestSCons._exe +_exe = TestSCons._exe test = TestSCons.TestSCons() test.dir_fixture('CC-fixture') +test.file_fixture('mylink.py') +# Note: mycc.py differs from the general fixture file mycompile.py +# in arg handling: that one is intended for use as a *COM consvar, +# where no compiler consvars will be passed on, this one is intended +# for use as $CC, where arguments like -o come into play. if sys.platform == 'win32': - - test.write('mylink.py', r""" -import sys -args = sys.argv[1:] -while args: - a = args[0] - if a == '-o': - out = args[1] - args = args[2:] - continue - if not a[0] in '/-': - break - args = args[1:] - if a[:5].lower() == '/out:': out = a[5:] -infile = open(args[0], 'rb') -outfile = open(out, 'wb') -for l in infile.readlines(): - if l[:8] != b'/*link*/': - outfile.write(l) -sys.exit(0) -""") - test.write('mycc.py', r""" import sys + args = sys.argv[1:] inf = None while args: @@ -69,57 +52,47 @@ while args: args = args[2:] continue args = args[1:] - if not a[0] in '-/': + if a[0] not in '-/': if not inf: inf = a continue - if a[:3] == '/Fo': out = a[3:] -infile = open(inf, 'rb') -outfile = open(out, 'wb') -for l in infile.readlines(): - if l[:6] != b'/*cc*/': - outfile.write(l) -sys.exit(0) -""") - -else: + if a.startswith('/Fo'): + out = a[3:] - test.write('mylink.py', r""" -import getopt -import sys -opts, args = getopt.getopt(sys.argv[1:], 'o:') -for opt, arg in opts: - if opt == '-o': out = arg -infile = open(args[0], 'rb') -outfile = open(out, 'wb') -for l in infile.readlines(): - if l[:8] != b'/*link*/': - outfile.write(l) +with open(inf, 'rb') as infile, open(out, 'wb') as outfile: + for line in infile: + if not line.startswith(b'/*cc*/'): + outfile.write(line) sys.exit(0) """) +else: test.write('mycc.py', r""" import getopt import sys + opts, args = getopt.getopt(sys.argv[1:], 'co:') for opt, arg in opts: - if opt == '-o': out = arg -infile = open(args[0], 'rb') -outfile = open(out, 'wb') -for l in infile.readlines(): - if l[:6] != b'/*cc*/': - outfile.write(l) + if opt == '-o': + out = arg + +with open(args[0], 'rb') as infile, open(out, 'wb') as outfile: + for line in infile: + if not line.startswith(b'/*cc*/'): + outfile.write(line) sys.exit(0) """) test.write('SConstruct', """ cc = Environment().Dictionary('CC') -env = Environment(LINK = r'%(_python_)s mylink.py', - LINKFLAGS = [], - CC = r'%(_python_)s mycc.py', - CXX = cc, - CXXFLAGS = []) -env.Program(target = 'test1', source = 'test1.c') +env = Environment( + LINK=r'%(_python_)s mylink.py', + LINKFLAGS=[], + CC=r'%(_python_)s mycc.py', + CXX=cc, + CXXFLAGS=[], +) +env.Program(target='test1', source='test1.c') """ % locals()) test.run(arguments = '.', stderr = None) @@ -130,10 +103,12 @@ if os.path.normcase('.c') == os.path.normcase('.C'): test.write('SConstruct', """ cc = Environment().Dictionary('CC') -env = Environment(LINK = r'%(_python_)s mylink.py', - CC = r'%(_python_)s mycc.py', - CXX = cc) -env.Program(target = 'test2', source = 'test2.C') +env = Environment( + LINK=r'%(_python_)s mylink.py', + CC=r'%(_python_)s mycc.py', + CXX=cc, +) +env.Program(target='test2', source='test2.C') """ % locals()) test.run(arguments = '.', stderr = None) @@ -144,9 +119,9 @@ test.file_fixture('wrapper.py') test.write('SConstruct', """ foo = Environment() cc = foo.Dictionary('CC') -bar = Environment(CC = r'%(_python_)s wrapper.py ' + cc) -foo.Program(target = 'foo', source = 'foo.c') -bar.Program(target = 'bar', source = 'bar.c') +bar = Environment(CC=r'%(_python_)s wrapper.py ' + cc) +foo.Program(target='foo', source='foo.c') +bar.Program(target='bar', source='bar.c') """ % locals()) test.run(arguments = 'foo' + _exe) diff --git a/test/CXX/CXX.py b/test/CXX/CXX.py index 4be4199..836324f 100644 --- a/test/CXX/CXX.py +++ b/test/CXX/CXX.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import sys import TestSCons @@ -32,33 +31,16 @@ _exe = TestSCons._exe test = TestSCons.TestSCons() +test.file_fixture('mylink.py') - +# Note: mycxx.py differs from the general fixture file mycompile.py +# in arg handling: that one is intended for use as a *COM consvar, +# where no compiler consvars will be passed on, this one is intended +# for use as $CXX, where arguments like -o come into play. if sys.platform == 'win32': - - test.write('mylink.py', r""" -import sys -args = sys.argv[1:] -while args: - a = args[0] - if a == '-o': - out = args[1] - args = args[2:] - continue - if not a[0] in '/-': - break - args = args[1:] - if a[:5].lower() == '/out:': out = a[5:] -infile = open(args[0], 'r') -outfile = open(out, 'w') -for l in infile.readlines(): - if l[:8] != '/*link*/': - outfile.write(l) -sys.exit(0) -""") - test.write('myc++.py', r""" import sys + args = sys.argv[1:] inf = None while args: @@ -73,79 +55,67 @@ while args: inf = a continue if a[:3] == '/Fo': out = a[3:] -infile = open(inf, 'r') -outfile = open(out, 'w') -for l in infile.readlines(): - if l[:7] != '/*c++*/': - outfile.write(l) -sys.exit(0) -""") - -else: - test.write('mylink.py', r""" -import getopt -import sys -opts, args = getopt.getopt(sys.argv[1:], 'o:') -for opt, arg in opts: - if opt == '-o': out = arg -infile = open(args[0], 'r') -outfile = open(out, 'w') -for l in infile.readlines(): - if l[:8] != '/*link*/': - outfile.write(l) +with open(inf, 'rb') as infile, open(out, 'wb') as outfile: + for line in infile: + if not line.startswith(b'/*c++*/'): + outfile.write(line) sys.exit(0) """) +else: test.write('myc++.py', r""" import getopt import sys + opts, args = getopt.getopt(sys.argv[1:], 'co:') for opt, arg in opts: if opt == '-o': out = arg -infile = open(args[0], 'r') -outfile = open(out, 'w') -for l in infile.readlines(): - if l[:7] != '/*c++*/': - outfile.write(l) + +with open(args[0], 'rb') as infile, open(out, 'wb') as outfile: + for line in infile: + if not line.startswith(b'/*c++*/'): + outfile.write(line) sys.exit(0) """) test.write('SConstruct', """ -env = Environment(LINK = r'%(_python_)s mylink.py', - LINKFLAGS = [], - CXX = r'%(_python_)s myc++.py', - CXXFLAGS = []) -env.Program(target = 'test1', source = 'test1.cc') -env.Program(target = 'test2', source = 'test2.cpp') -env.Program(target = 'test3', source = 'test3.cxx') -env.Program(target = 'test4', source = 'test4.c++') -env.Program(target = 'test5', source = 'test5.C++') +env = Environment( + LINK=r'%(_python_)s mylink.py', + LINKFLAGS=[], + CXX=r'%(_python_)s myc++.py', + CXXFLAGS=[], +) +env.Program(target='test1', source='test1.cc') +env.Program(target='test2', source='test2.cpp') +env.Program(target='test3', source='test3.cxx') +env.Program(target='test4', source='test4.c++') +env.Program(target='test5', source='test5.C++') """ % locals()) test.write('test1.cc', r"""This is a .cc file. /*c++*/ -/*link*/ +#link """) test.write('test2.cpp', r"""This is a .cpp file. /*c++*/ -/*link*/ +#link """) test.write('test3.cxx', r"""This is a .cxx file. /*c++*/ -/*link*/ +#link """) test.write('test4.c++', r"""This is a .c++ file. /*c++*/ -/*link*/ +#link """) test.write('test5.C++', r"""This is a .C++ file. /*c++*/ -/*link*/ +#link """) test.run(arguments = '.', stderr = None) @@ -161,35 +131,32 @@ test.must_match('test4' + _exe, "This is a .c++ file.\n", mode='r') test.must_match('test5' + _exe, "This is a .C++ file.\n", mode='r') if TestSCons.case_sensitive_suffixes('.c', '.C'): - test.write('SConstruct', """ -env = Environment(LINK = r'%(_python_)s mylink.py', - LINKFLAGS = [], - CXX = r'%(_python_)s myc++.py', - CXXFLAGS = []) -env.Program(target = 'test6', source = 'test6.C') +env = Environment( + LINK=r'%(_python_)s mylink.py', + LINKFLAGS=[], + CXX=r'%(_python_)s myc++.py', + CXXFLAGS=[], +) +env.Program(target='test6', source='test6.C') """ % locals()) test.write('test6.C', r"""This is a .C file. /*c++*/ -/*link*/ +#link """) test.run(arguments = '.', stderr = None) - test.must_match('test6' + _exe, "This is a .C file.\n", mode='r') - - - test.file_fixture('wrapper.py') test.write('SConstruct', """ foo = Environment() cxx = foo.Dictionary('CXX') -bar = Environment(CXX = r'%(_python_)s wrapper.py ' + cxx) -foo.Program(target = 'foo', source = 'foo.cxx') -bar.Program(target = 'bar', source = 'bar.cxx') +bar = Environment(CXX=r'%(_python_)s wrapper.py ' + cxx) +foo.Program(target='foo', source='foo.cxx') +bar.Program(target='bar', source='bar.cxx') """ % locals()) test.write('foo.cxx', r""" diff --git a/test/fixture/mycompile.py b/test/fixture/mycompile.py index 0f37d19..a60a35f 100644 --- a/test/fixture/mycompile.py +++ b/test/fixture/mycompile.py @@ -1,19 +1,31 @@ -r""" -Phony "compiler" for testing SCons. +""" +Phony compiler for testing SCons. + +Copies its source files to the target file, dropping lines that match +a pattern, so we can recognize the tool has made a modification. +Intended for use as a *COM construction variable. + +Calling convention is: + argv[1] the function of the script (cc, c++, as, link etc.) + argv[2] the output file to write + argv[3:] one or more input files to "compile" -Copies its source files to the target file, dropping lines -that match a pattern, so we can recognize the tool -has made a modification. +Invocation often looks like: + Environment(CCCOM = r'%(_python_)s mycompile.py cc $TARGET $SOURCE', ... """ +import fileinput +import getopt import sys +def fake_compile(): + skipline = f"/*{sys.argv[1]}*/\n".encode("utf-8") + with open(sys.argv[2], 'wb') as ofp, fileinput.input(files=sys.argv[3:], mode='rb') as ifp: + for line in ifp: + if line != skipline: + ofp.write(line) + + if __name__ == '__main__': - line = ('/*' + sys.argv[1] + '*/\n').encode() - with open(sys.argv[2], 'wb') as ofp: - for f in sys.argv[3:]: - with open(f, 'rb') as ifp: - lines = [ln for ln in ifp if ln != line] - for ln in lines: - ofp.write(ln) + fake_compile() sys.exit(0) diff --git a/test/fixture/mygcc.py b/test/fixture/mygcc.py index ceb10e5..5f524c2 100644 --- a/test/fixture/mygcc.py +++ b/test/fixture/mygcc.py @@ -1,18 +1,21 @@ import getopt import sys -compiler = sys.argv[1] -clen = len(compiler) + 1 -opts, args = getopt.getopt(sys.argv[2:], 'co:xf:K:') -for opt, arg in opts: - if opt == '-o': - out = arg - elif opt == '-x': - with open('mygcc.out', 'a') as f: - f.write(compiler + "\n") +def fake_gcc(): + compiler = sys.argv[1].encode('utf-8') + opts, args = getopt.getopt(sys.argv[2:], 'co:xf:K:') + for opt, arg in opts: + if opt == '-o': + out = arg + elif opt == '-x': + with open('mygcc.out', 'ab') as f: + f.write(compiler + b"\n") -with open(out, 'w') as ofp, open(args[0], 'r') as ifp: - for line in ifp.readlines(): - if line[:clen] != '#' + compiler: - ofp.write(line) -sys.exit(0) + with open(out, 'wb') as ofp, open(args[0], 'rb') as ifp: + for line in ifp: + if not line.startswith(b'#' + compiler): + ofp.write(line) + +if __name__ == '__main__': + fake_gcc() + sys.exit(0) diff --git a/test/fixture/mylink.py b/test/fixture/mylink.py index 19969f0..a0b4e27 100644 --- a/test/fixture/mylink.py +++ b/test/fixture/mylink.py @@ -1,6 +1,11 @@ """ -Dummy linker for use by tests" +Phony linker for testing SCons. + +Copies its source files to the target file, dropping lines that match +a pattern, so we can recognize the tool has made a modification. +Intended for use as the $LINK construction variable. """ +import fileinput import getopt import sys @@ -10,13 +15,10 @@ def fake_link(): if opt == '-o': out = arg - with open(out, 'w') as ofp: - for f in args: - with open(f, 'r') as ifp: - for line in ifp.readlines(): - if line[:5] != '#link': - ofp.write(line) - sys.exit(0) + with open(out, 'wb') as ofp, fileinput.input(files=args, mode='rb') as ifp: + for line in ifp: + if not line.startswith(b'#link'): + ofp.write(line) def fake_win32_link(): args = sys.argv[1:] @@ -26,18 +28,19 @@ def fake_win32_link(): out = args[1] args = args[2:] continue - if not a[0] in '/-': + if a[0] not in '/-': break args = args[1:] - if a[:5].lower() == '/out:': out = a[5:] + if a.lower().startswith('/out:'): + out = a[5:] with open(args[0], 'rb') as ifp, open(out, 'wb') as ofp: - for line in ifp.readlines(): + for line in ifp: if not line.startswith(b'#link'): ofp.write(line) - sys.exit(0) if __name__ == '__main__': if sys.platform == 'win32': fake_win32_link() else: fake_link() + sys.exit(0) diff --git a/test/fixture/mylink_win32.py b/test/fixture/mylink_win32.py index 477fc95..8edbe70 100644 --- a/test/fixture/mylink_win32.py +++ b/test/fixture/mylink_win32.py @@ -9,8 +9,8 @@ while args: if a[:5] == '/OUT:': out = a[5:] -with open(out, 'w') as ofp, open(args[0], 'r') as ifp: - for line in ifp.readlines(): - if line[:5] != '#link': +with open(out, 'wb') as ofp, open(args[0], 'rb') as ifp: + for line in ifp: + if not line.startswith(b'#link'): ofp.write(line) sys.exit(0) diff --git a/test/fixture/myrewrite.py b/test/fixture/myrewrite.py index 6914611..eb83cac 100644 --- a/test/fixture/myrewrite.py +++ b/test/fixture/myrewrite.py @@ -2,16 +2,19 @@ r""" Phony tool to modify a file in place for testing SCons. Drops lines that match a pattern. Currently used to test -ranlib-related behavior without invoking ranlib. +ranlib and ar behavior without actually invoking those tools. """ import sys -if __name__ == '__main__': - line = ('/*' + sys.argv[1] + '*/\n').encode() +def rewrite(): + line = ('/*' + sys.argv[1] + '*/\n').encode('utf-8') with open(sys.argv[2], 'rb') as ifp: lines = [ln for ln in ifp if ln != line] with open(sys.argv[2], 'wb') as ofp: - for ln in lines: - ofp.write(ln) + ofp.writelines(lines) + + +if __name__ == '__main__': + rewrite() sys.exit(0) -- cgit v0.12 From 8c9ff2495360cdf0928ba13dfa8149f86abe1bc6 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Mon, 17 Jan 2022 13:00:17 -0700 Subject: Drop an unused import - sider complaint Signed-off-by: Mats Wichmann --- test/fixture/mycompile.py | 1 - 1 file changed, 1 deletion(-) diff --git a/test/fixture/mycompile.py b/test/fixture/mycompile.py index a60a35f..15a1c6f 100644 --- a/test/fixture/mycompile.py +++ b/test/fixture/mycompile.py @@ -15,7 +15,6 @@ Invocation often looks like: """ import fileinput -import getopt import sys def fake_compile(): -- cgit v0.12 From b54e9d95e0ee70460cdb86773f31660f2c16d650 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Tue, 18 Jan 2022 16:15:50 -0700 Subject: Also move CC and CXX mock compiler to fixture CC/CC.py uses a local mycc.py and CXX/CXX.py uses a local myc++.py. These could not be replaced by mycompile.py because theu usage model is different, but these two are moved to a local (to the test) fixture directory instead of being inline. Signed-off-by: Mats Wichmann --- test/CC/CC-fixture/.exclude_tests | 1 + test/CC/CC-fixture/mycc.py | 55 +++++++++++++++++++++++++++++++++++++ test/CC/CC.py | 48 -------------------------------- test/CXX/CXX-fixture/.exclude_tests | 1 + test/CXX/CXX-fixture/myc++.py | 55 +++++++++++++++++++++++++++++++++++++ test/CXX/CXX.py | 47 +------------------------------ 6 files changed, 113 insertions(+), 94 deletions(-) create mode 100644 test/CC/CC-fixture/.exclude_tests create mode 100644 test/CC/CC-fixture/mycc.py create mode 100644 test/CXX/CXX-fixture/.exclude_tests create mode 100644 test/CXX/CXX-fixture/myc++.py diff --git a/test/CC/CC-fixture/.exclude_tests b/test/CC/CC-fixture/.exclude_tests new file mode 100644 index 0000000..3f2bc0f --- /dev/null +++ b/test/CC/CC-fixture/.exclude_tests @@ -0,0 +1 @@ +mycc.py diff --git a/test/CC/CC-fixture/mycc.py b/test/CC/CC-fixture/mycc.py new file mode 100644 index 0000000..78017f4 --- /dev/null +++ b/test/CC/CC-fixture/mycc.py @@ -0,0 +1,55 @@ +""" +Phony cc command for testing SCons. + +Copies its source file to the target file, dropping lines that match +a pattern, so we can recognize the tool has made a modification. +Intended for use as the $CXX construction variable. + +Note: mycc.py differs from the general fixture file mycompile.py +in arg handling: that one is intended for use as a *COM consvar, +where no compiler consvars will be passed on, this one is intended +for use as $CC, where arguments like -o come into play. +""" +import getopt +import sys + +def fake_win32_cc(): + args = sys.argv[1:] + inf = None + while args: + a = args[0] + if a == '-o': + out = args[1] + args = args[2:] + continue + args = args[1:] + if a[0] not in '/-': + if not inf: + inf = a + continue + if a[:3] == '/Fo': + out = a[3:] + + with open(inf, 'rb') as infile, open(out, 'wb') as outfile: + for line in infile: + if not line.startswith(b'/*cc*/'): + outfile.write(line) + +def fake_cc(): + opts, args = getopt.getopt(sys.argv[1:], 'co:') + for opt, arg in opts: + if opt == '-o': + out = arg + + with open(args[0], 'rb') as infile, open(out, 'wb') as outfile: + for line in infile: + if not line.startswith(b'/*cc*/'): + outfile.write(line) + +if __name__ == '__main__': + print(f"DEBUG: {sys.argv[0]}: {sys.argv[1:]}") + if sys.platform == 'win32': + fake_win32_cc() + else: + fake_cc() + sys.exit(0) diff --git a/test/CC/CC.py b/test/CC/CC.py index c2562d5..a548421 100644 --- a/test/CC/CC.py +++ b/test/CC/CC.py @@ -35,54 +35,6 @@ test = TestSCons.TestSCons() test.dir_fixture('CC-fixture') test.file_fixture('mylink.py') -# Note: mycc.py differs from the general fixture file mycompile.py -# in arg handling: that one is intended for use as a *COM consvar, -# where no compiler consvars will be passed on, this one is intended -# for use as $CC, where arguments like -o come into play. -if sys.platform == 'win32': - test.write('mycc.py', r""" -import sys - -args = sys.argv[1:] -inf = None -while args: - a = args[0] - if a == '-o': - out = args[1] - args = args[2:] - continue - args = args[1:] - if a[0] not in '-/': - if not inf: - inf = a - continue - if a.startswith('/Fo'): - out = a[3:] - -with open(inf, 'rb') as infile, open(out, 'wb') as outfile: - for line in infile: - if not line.startswith(b'/*cc*/'): - outfile.write(line) -sys.exit(0) -""") - -else: - test.write('mycc.py', r""" -import getopt -import sys - -opts, args = getopt.getopt(sys.argv[1:], 'co:') -for opt, arg in opts: - if opt == '-o': - out = arg - -with open(args[0], 'rb') as infile, open(out, 'wb') as outfile: - for line in infile: - if not line.startswith(b'/*cc*/'): - outfile.write(line) -sys.exit(0) -""") - test.write('SConstruct', """ cc = Environment().Dictionary('CC') env = Environment( diff --git a/test/CXX/CXX-fixture/.exclude_tests b/test/CXX/CXX-fixture/.exclude_tests new file mode 100644 index 0000000..9e0e6ff --- /dev/null +++ b/test/CXX/CXX-fixture/.exclude_tests @@ -0,0 +1 @@ +myc++.py diff --git a/test/CXX/CXX-fixture/myc++.py b/test/CXX/CXX-fixture/myc++.py new file mode 100644 index 0000000..06565c7 --- /dev/null +++ b/test/CXX/CXX-fixture/myc++.py @@ -0,0 +1,55 @@ +""" +Phony c++ command for testing SCons. + +Copies its source file to the target file, dropping lines that match +a pattern, so we can recognize the tool has made a modification. +Intended for use as the $CXX construction variable. + +Note: mycxx.py differs from the general fixture file mycompile.py +in arg handling: that one is intended for use as a *COM consvar, +where no compiler consvars will be passed on, this one is intended +for use as $CXX, where arguments like -o come into play. +""" +import getopt +import sys + +def fake_win32_cxx(): + args = sys.argv[1:] + inf = None + while args: + a = args[0] + if a == '-o': + out = args[1] + args = args[2:] + continue + args = args[1:] + if a[0] not in '/-': + if not inf: + inf = a + continue + if a[:3] == '/Fo': + out = a[3:] + + with open(inf, 'rb') as infile, open(out, 'wb') as outfile: + for line in infile: + if not line.startswith(b'/*c++*/'): + outfile.write(line) + +def fake_cxx(): + opts, args = getopt.getopt(sys.argv[1:], 'co:') + for opt, arg in opts: + if opt == '-o': + out = arg + + with open(args[0], 'rb') as infile, open(out, 'wb') as outfile: + for line in infile: + if not line.startswith(b'/*c++*/'): + outfile.write(line) + +if __name__ == '__main__': + print(f"DEBUG: {sys.argv[0]}: {sys.argv[1:]}") + if sys.platform == 'win32': + fake_win32_cxx() + else: + fake_cxx() + sys.exit(0) diff --git a/test/CXX/CXX.py b/test/CXX/CXX.py index 836324f..ad00b55 100644 --- a/test/CXX/CXX.py +++ b/test/CXX/CXX.py @@ -32,52 +32,7 @@ _exe = TestSCons._exe test = TestSCons.TestSCons() test.file_fixture('mylink.py') - -# Note: mycxx.py differs from the general fixture file mycompile.py -# in arg handling: that one is intended for use as a *COM consvar, -# where no compiler consvars will be passed on, this one is intended -# for use as $CXX, where arguments like -o come into play. -if sys.platform == 'win32': - test.write('myc++.py', r""" -import sys - -args = sys.argv[1:] -inf = None -while args: - a = args[0] - if a == '-o': - out = args[1] - args = args[2:] - continue - args = args[1:] - if not a[0] in '/-': - if not inf: - inf = a - continue - if a[:3] == '/Fo': out = a[3:] - -with open(inf, 'rb') as infile, open(out, 'wb') as outfile: - for line in infile: - if not line.startswith(b'/*c++*/'): - outfile.write(line) -sys.exit(0) -""") - -else: - test.write('myc++.py', r""" -import getopt -import sys - -opts, args = getopt.getopt(sys.argv[1:], 'co:') -for opt, arg in opts: - if opt == '-o': out = arg - -with open(args[0], 'rb') as infile, open(out, 'wb') as outfile: - for line in infile: - if not line.startswith(b'/*c++*/'): - outfile.write(line) -sys.exit(0) -""") +test.dir_fixture('CXX-fixture') test.write('SConstruct', """ env = Environment( -- cgit v0.12 From a94950db308154798e65e07704e65a85c0aef6f6 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Wed, 19 Jan 2022 10:35:38 -0700 Subject: A bit more test fixture work mylex.py is now a general fixture Some of the existing fixtures had a bit more cleanup. the unneeded mylink_win32.py is dropped (only referenced by a test which already skips on win32, and the general mylink.py covers the win32 case anyway). Signed-off-by: Mats Wichmann --- test/CC/CC-fixture/mycc.py | 12 ++++---- test/CFILESUFFIX.py | 32 ++++++-------------- test/CPPFLAGS.py | 63 +++++++++++++++++++-------------------- test/CXX/CXX-fixture/myc++.py | 12 ++++---- test/CXX/CXXFILESUFFIX.py | 33 ++++++-------------- test/LEX/LEX.py | 55 +++++++++++----------------------- test/LEX/LEXFLAGS.py | 27 ++--------------- test/fixture/mygcc.py | 18 +++++++++-- test/fixture/mylex.py | 37 +++++++++++++++++++++++ test/fixture/mylink.py | 10 +++---- test/fixture/mylink_win32.py | 16 ---------- test/fixture/wrapper.py | 9 +++++- test/fixture/wrapper_with_args.py | 9 +++++- 13 files changed, 154 insertions(+), 179 deletions(-) create mode 100644 test/fixture/mylex.py delete mode 100644 test/fixture/mylink_win32.py diff --git a/test/CC/CC-fixture/mycc.py b/test/CC/CC-fixture/mycc.py index 78017f4..eb11c87 100644 --- a/test/CC/CC-fixture/mycc.py +++ b/test/CC/CC-fixture/mycc.py @@ -17,18 +17,18 @@ def fake_win32_cc(): args = sys.argv[1:] inf = None while args: - a = args[0] - if a == '-o': + arg = args[0] + if arg == '-o': out = args[1] args = args[2:] continue args = args[1:] - if a[0] not in '/-': + if arg[0] not in '/-': if not inf: - inf = a + inf = arg continue - if a[:3] == '/Fo': - out = a[3:] + if arg.startswith('/Fo'): + out = arg[3:] with open(inf, 'rb') as infile, open(out, 'wb') as outfile: for line in infile: diff --git a/test/CFILESUFFIX.py b/test/CFILESUFFIX.py index 0a62307..2d24e25 100644 --- a/test/CFILESUFFIX.py +++ b/test/CFILESUFFIX.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Verify that we can set CFILESUFFIX to arbitrary values. @@ -35,32 +34,19 @@ _python_ = TestSCons._python_ test = TestSCons.TestSCons() -test.write('mylex.py', """ -import getopt -import sys -if sys.platform == 'win32': - longopts = ['nounistd'] -else: - longopts = [] -cmd_opts, args = getopt.getopt(sys.argv[1:], 't', longopts) -for a in args: - with open(a, 'rb') as f: - contents = f.read() - sys.stdout.write((contents.replace(b'LEX', b'mylex.py')).decode()) -sys.exit(0) -""") +test.file_fixture('mylex.py') test.write('SConstruct', """ -env = Environment(LEX = r'%(_python_)s mylex.py', tools = ['lex']) -env.CFile(target = 'foo', source = 'foo.l') -env.Clone(CFILESUFFIX = '.xyz').CFile(target = 'bar', source = 'bar.l') +env = Environment(LEX=r'%(_python_)s mylex.py', tools=['lex']) +env.CFile(target='foo', source='foo.l') +env.Clone(CFILESUFFIX='.xyz').CFile(target='bar', source='bar.l') # Make sure that calling a Tool on a construction environment *after* # we've set CFILESUFFIX doesn't overwrite the value. -env2 = Environment(tools = [], CFILESUFFIX = '.env2') +env2 = Environment(tools=[], CFILESUFFIX='.env2') env2.Tool('lex') env2['LEX'] = r'%(_python_)s mylex.py' -env2.CFile(target = 'f3', source = 'f3.l') +env2.CFile(target='f3', source='f3.l') """ % locals()) input = r""" diff --git a/test/CPPFLAGS.py b/test/CPPFLAGS.py index 2808a53..ebae2df 100644 --- a/test/CPPFLAGS.py +++ b/test/CPPFLAGS.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import sys @@ -38,25 +37,22 @@ test = TestSCons.TestSCons() if sys.platform == 'win32': test.skip_test('Skipping on win32.\n') -if sys.platform == 'win32': - test.file_fixture('mylink_win32.py', 'mylink.py') -else: - test.file_fixture('mylink.py') - +test.file_fixture('mylink.py') test.file_fixture('mygcc.py') - test.write('SConstruct', """ -env = Environment(CPPFLAGS = '-x', - LINK = r'%(_python_)s mylink.py', - LINKFLAGS = [], - CC = r'%(_python_)s mygcc.py cc', - CXX = r'%(_python_)s mygcc.py c++', - CXXFLAGS = [], - FORTRAN = r'%(_python_)s mygcc.py g77', - OBJSUFFIX = '.obj', - PROGSUFFIX = '.exe') -env.Program(target = 'foo', source = Split('test1.c test2.cpp test3.F')) +env = Environment( + CPPFLAGS='-x', + LINK=r'%(_python_)s mylink.py', + LINKFLAGS=[], + CC=r'%(_python_)s mygcc.py cc', + CXX=r'%(_python_)s mygcc.py c++', + CXXFLAGS=[], + FORTRAN=r'%(_python_)s mygcc.py g77', + OBJSUFFIX='.obj', + PROGSUFFIX='.exe', +) +env.Program(target='foo', source=Split('test1.c test2.cpp test3.F')) """ % locals()) test.write('test1.c', r"""test1.c @@ -86,19 +82,20 @@ else: test.must_match('mygcc.out', "cc\nc++\n") test.write('SConstruct', """ -env = Environment(CPPFLAGS = '-x', - SHLINK = r'%(_python_)s mylink.py', - SHLINKFLAGS = [], - CC = r'%(_python_)s mygcc.py cc', - CXX = r'%(_python_)s mygcc.py c++', - CXXFLAGS = [], - FORTRAN = r'%(_python_)s mygcc.py g77', - OBJSUFFIX = '.obj', - SHOBJPREFIX = '', - SHOBJSUFFIX = '.shobj', - PROGSUFFIX = '.exe') -env.SharedLibrary(target = File('foo.bar'), - source = Split('test1.c test2.cpp test3.F')) +env = Environment( + CPPFLAGS='-x', + SHLINK=r'%(_python_)s mylink.py', + SHLINKFLAGS=[], + CC=r'%(_python_)s mygcc.py cc', + CXX=r'%(_python_)s mygcc.py c++', + CXXFLAGS=[], + FORTRAN=r'%(_python_)s mygcc.py g77', + OBJSUFFIX='.obj', + SHOBJPREFIX='', + SHOBJSUFFIX='.shobj', + PROGSUFFIX='.exe', +) +env.SharedLibrary(target=File('foo.bar'), source=Split('test1.c test2.cpp test3.F')) """ % locals()) test.write('test1.c', r"""test1.c diff --git a/test/CXX/CXX-fixture/myc++.py b/test/CXX/CXX-fixture/myc++.py index 06565c7..d369f61 100644 --- a/test/CXX/CXX-fixture/myc++.py +++ b/test/CXX/CXX-fixture/myc++.py @@ -17,18 +17,18 @@ def fake_win32_cxx(): args = sys.argv[1:] inf = None while args: - a = args[0] - if a == '-o': + arg = args[0] + if arg == '-o': out = args[1] args = args[2:] continue args = args[1:] - if a[0] not in '/-': + if arg[0] not in '/-': if not inf: - inf = a + inf = arg continue - if a[:3] == '/Fo': - out = a[3:] + if arg.startswith('/Fo'): + out = arg[3:] with open(inf, 'rb') as infile, open(out, 'wb') as outfile: for line in infile: diff --git a/test/CXX/CXXFILESUFFIX.py b/test/CXX/CXXFILESUFFIX.py index 0ae5827..1c55106 100644 --- a/test/CXX/CXXFILESUFFIX.py +++ b/test/CXX/CXXFILESUFFIX.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,10 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - import TestSCons @@ -31,32 +29,19 @@ _python_ = TestSCons._python_ test = TestSCons.TestSCons() -test.write('mylex.py', """ -import getopt -import sys -if sys.platform == 'win32': - longopts = ['nounistd'] -else: - longopts = [] -cmd_opts, args = getopt.getopt(sys.argv[1:], 't', longopts) -for a in args: - with open(a, 'r') as f: - contents = f.read() - sys.stdout.write(contents.replace('LEX', 'mylex.py')) -sys.exit(0) -""") +test.file_fixture('mylex.py') test.write('SConstruct', """ -env = Environment(LEX = r'%(_python_)s mylex.py', tools = ['lex']) -env.CXXFile(target = 'foo', source = 'foo.ll') -env.Clone(CXXFILESUFFIX = '.xyz').CXXFile(target = 'bar', source = 'bar.ll') +env = Environment(LEX=r'%(_python_)s mylex.py', tools=['lex']) +env.CXXFile(target='foo', source='foo.ll') +env.Clone(CXXFILESUFFIX='.xyz').CXXFile(target='bar', source='bar.ll') # Make sure that calling a Tool on a construction environment *after* # we've set CXXFILESUFFIX doesn't overwrite the value. -env2 = Environment(tools = [], CXXFILESUFFIX = '.env2') +env2 = Environment(tools=[], CXXFILESUFFIX='.env2') env2.Tool('lex') env2['LEX'] = r'%(_python_)s mylex.py' -env2.CXXFile(target = 'f3', source = 'f3.ll') +env2.CXXFile(target='f3', source='f3.ll') """ % locals()) input = r""" diff --git a/test/LEX/LEX.py b/test/LEX/LEX.py index 79d8359..7dc8436 100644 --- a/test/LEX/LEX.py +++ b/test/LEX/LEX.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,10 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - import TestSCons @@ -32,46 +30,29 @@ _exe = TestSCons._exe test = TestSCons.TestSCons() - - -test.write('mylex.py', """ -import getopt -import sys -if sys.platform == 'win32': - longopts = ['nounistd'] -else: - longopts = [] -cmd_opts, args = getopt.getopt(sys.argv[1:], 't', longopts) -for a in args: - with open(a, 'rb') as f: - contents = f.read() - sys.stdout.write(contents.replace(b'LEX', b'mylex.py').decode()) -sys.exit(0) -""") +test.file_fixture('mylex.py') test.write('SConstruct', """ -env = Environment(LEX = r'%(_python_)s mylex.py', tools=['default', 'lex']) -env.CFile(target = 'aaa', source = 'aaa.l') -env.CFile(target = 'bbb', source = 'bbb.lex') -env.CXXFile(target = 'ccc', source = 'ccc.ll') -env.CXXFile(target = 'ddd', source = 'ddd.lm') +env = Environment(LEX=r'%(_python_)s mylex.py', tools=['default', 'lex']) +env.CFile(target='aaa', source='aaa.l') +env.CFile(target='bbb', source='bbb.lex') +env.CXXFile(target='ccc', source='ccc.ll') +env.CXXFile(target='ddd', source='ddd.lm') """ % locals()) -test.write('aaa.l', "aaa.l\nLEX\n") -test.write('bbb.lex', "bbb.lex\nLEX\n") -test.write('ccc.ll', "ccc.ll\nLEX\n") -test.write('ddd.lm', "ddd.lm\nLEX\n") +test.write('aaa.l', "aaa.l\nLEX\n") +test.write('bbb.lex', "bbb.lex\nLEX\n") +test.write('ccc.ll', "ccc.ll\nLEX\n") +test.write('ddd.lm', "ddd.lm\nLEX\n") -test.run(arguments = '.', stderr = None) +test.run(arguments='.', stderr=None) # Read in with mode='r' because mylex.py implicitley wrote to stdout # with mode='w'. -test.must_match('aaa.c', "aaa.l\nmylex.py\n", mode='r') -test.must_match('bbb.c', "bbb.lex\nmylex.py\n", mode='r') -test.must_match('ccc.cc', "ccc.ll\nmylex.py\n", mode='r') -test.must_match('ddd.m', "ddd.lm\nmylex.py\n", mode='r') - - +test.must_match('aaa.c', "aaa.l\nmylex.py\n", mode='r') +test.must_match('bbb.c', "bbb.lex\nmylex.py\n", mode='r') +test.must_match('ccc.cc', "ccc.ll\nmylex.py\n", mode='r') +test.must_match('ddd.m', "ddd.lm\nmylex.py\n", mode='r') test.pass_test() diff --git a/test/LEX/LEXFLAGS.py b/test/LEX/LEXFLAGS.py index efcf9c4..f7d16c1 100644 --- a/test/LEX/LEXFLAGS.py +++ b/test/LEX/LEXFLAGS.py @@ -35,28 +35,7 @@ test = TestSCons.TestSCons() test.subdir('in') -test.write('mylex.py', """ -import getopt -import sys -import os -if sys.platform == 'win32': - longopts = ['nounistd'] -else: - longopts = [] -cmd_opts, args = getopt.getopt(sys.argv[1:], 'I:tx', longopts) -opt_string = '' -i_arguments = '' -for opt, arg in cmd_opts: - if opt == '-I': i_arguments = i_arguments + ' ' + arg - else: opt_string = opt_string + ' ' + opt -for a in args: - with open(a, 'r') as f: - contents = f.read() - contents = contents.replace('LEXFLAGS', opt_string) - contents = contents.replace('I_ARGS', i_arguments) - sys.stdout.write(contents) -sys.exit(0) -""") +test.file_fixture('mylex.py') test.write('SConstruct', """ env = Environment( @@ -76,9 +55,7 @@ if sys.platform == 'win32' and not sysconfig.get_platform() in ("mingw",): lexflags = ' --nounistd' + lexflags # Read in with mode='r' because mylex.py implicitley wrote to stdout # with mode='w'. -test.must_match(['out', 'aaa.c'], "aaa.l\n%s\n out in\n" % lexflags, mode='r') - - +test.must_match(['out', 'aaa.c'], "aaa.l\n%s\n out in\n" % lexflags, mode='r') test.pass_test() diff --git a/test/fixture/mygcc.py b/test/fixture/mygcc.py index 5f524c2..91ca386 100644 --- a/test/fixture/mygcc.py +++ b/test/fixture/mygcc.py @@ -1,3 +1,17 @@ +""" +Phony compiler for testing SCons. + +Copies its source file to the target file, dropping lines that match +a pattern, so we can recognize the tool has made a modification. + +The first argument is the language (cc, c__, g77, etc.). + +Recognizes a -x option to append the language to 'mygcc.out' +for tracing purposes. + +Intended for use as $CC, $CXX, etc. +""" + import getopt import sys @@ -8,8 +22,8 @@ def fake_gcc(): if opt == '-o': out = arg elif opt == '-x': - with open('mygcc.out', 'ab') as f: - f.write(compiler + b"\n") + with open('mygcc.out', 'ab') as logfile: + logfile.write(compiler + b"\n") with open(out, 'wb') as ofp, open(args[0], 'rb') as ifp: for line in ifp: diff --git a/test/fixture/mylex.py b/test/fixture/mylex.py new file mode 100644 index 0000000..accc96a --- /dev/null +++ b/test/fixture/mylex.py @@ -0,0 +1,37 @@ +""" +Phony lex for testing SCons. + +Writes the contents of input file to stdout, +after "substituting" $LEXFLAGS and $I_ARGS + +Intended for use as $LEX +""" + +import getopt +import sys +import os + +def fake_lex(): + if sys.platform == 'win32': + longopts = ['nounistd'] + else: + longopts = [] + cmd_opts, args = getopt.getopt(sys.argv[1:], 'I:tx', longopts) + opt_string = '' + i_arguments = '' + for opt, arg in cmd_opts: + if opt == '-I': + i_arguments = f'{i_arguments} {arg}' + else: + opt_string = f'{opt_string} {opt}' + for arg in args: + with open(arg, 'rb') as ifp: + contents = ifp.read().decode(encoding='utf-8') + contents = contents.replace('LEXFLAGS', opt_string) + contents = contents.replace('LEX', 'mylex.py') + contents = contents.replace('I_ARGS', i_arguments) + sys.stdout.write(contents) + +if __name__ == '__main__': + fake_lex() + sys.exit(0) diff --git a/test/fixture/mylink.py b/test/fixture/mylink.py index a0b4e27..f462655 100644 --- a/test/fixture/mylink.py +++ b/test/fixture/mylink.py @@ -23,16 +23,16 @@ def fake_link(): def fake_win32_link(): args = sys.argv[1:] while args: - a = args[0] - if a == '-o': + arg = args[0] + if arg == '-o': out = args[1] args = args[2:] continue - if a[0] not in '/-': + if arg[0] not in '/-': break args = args[1:] - if a.lower().startswith('/out:'): - out = a[5:] + if arg.lower().startswith('/out:'): + out = arg[5:] with open(args[0], 'rb') as ifp, open(out, 'wb') as ofp: for line in ifp: if not line.startswith(b'#link'): diff --git a/test/fixture/mylink_win32.py b/test/fixture/mylink_win32.py deleted file mode 100644 index 8edbe70..0000000 --- a/test/fixture/mylink_win32.py +++ /dev/null @@ -1,16 +0,0 @@ -import sys - -args = sys.argv[1:] -while args: - a = args[0] - if a[0] != '/': - break - args.pop(0) - if a[:5] == '/OUT:': - out = a[5:] - -with open(out, 'wb') as ofp, open(args[0], 'rb') as ifp: - for line in ifp: - if not line.startswith(b'#link'): - ofp.write(line) -sys.exit(0) diff --git a/test/fixture/wrapper.py b/test/fixture/wrapper.py index 112186e..c266cfa 100644 --- a/test/fixture/wrapper.py +++ b/test/fixture/wrapper.py @@ -1,3 +1,10 @@ +""" +Command wrapper, for testing SCons. + +Writes the command name to file "wrapper.out", +then passes the command line on to subprocess. +No checking is done. +""" import os import sys import subprocess @@ -7,4 +14,4 @@ if __name__ == '__main__': if '--version' not in sys.argv and '-dumpversion' not in sys.argv: with open(path, 'wb') as f: f.write(b"wrapper.py\n") - subprocess.run(sys.argv[1:]) + subprocess.run(sys.argv[1:], check=False) diff --git a/test/fixture/wrapper_with_args.py b/test/fixture/wrapper_with_args.py index b8d6ae5..769aea4 100644 --- a/test/fixture/wrapper_with_args.py +++ b/test/fixture/wrapper_with_args.py @@ -1,3 +1,10 @@ +""" +Command wrapper taking arguments, for testing SCons. + +Writes the command name and argument list to file "wrapper.out", +then passes the command line on to subprocess. +No checking is done. +""" import os import sys import subprocess @@ -6,4 +13,4 @@ if __name__ == '__main__': path = os.path.join(os.path.dirname(os.path.relpath(__file__)), 'wrapper.out') with open(path, 'a') as f: f.write("wrapper_with_args.py %s\n" % " ".join(sys.argv[1:])) - subprocess.run(sys.argv[1:]) + subprocess.run(sys.argv[1:], check=False) -- cgit v0.12 From d10e283fb19caff12319c698bddb4f6ffda571f7 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Wed, 19 Jan 2022 10:47:57 -0700 Subject: flake8: remove unused import in test fixture Signed-off-by: Mats Wichmann --- test/fixture/mylex.py | 1 - 1 file changed, 1 deletion(-) diff --git a/test/fixture/mylex.py b/test/fixture/mylex.py index accc96a..8f47049 100644 --- a/test/fixture/mylex.py +++ b/test/fixture/mylex.py @@ -9,7 +9,6 @@ Intended for use as $LEX import getopt import sys -import os def fake_lex(): if sys.platform == 'win32': -- cgit v0.12 From ba5915c606c29d2490ce65782e4db861249a9b78 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Mon, 24 Jan 2022 09:40:48 -0700 Subject: A little java/jar cleanup * The Jar test is split into requires-jdk and not. * Move some inline tool definitions to fixture files. * Reformat some stuff. * Some linting and commenting in Jar tool. * Enabled test for a non-java file when Jar source is a directory (was commented out) - needed to add a Command to copy the file to the directory where the class files were generated. Signed-off-by: Mats Wichmann --- SCons/Tool/jar.py | 121 ++++++++-------- test/Java/JAR.py | 252 ++++++++++++++-------------------- test/Java/JAVAC.py | 42 ++---- test/Java/Java-fixture/.exclude_tests | 2 + test/Java/Java-fixture/myjar.py | 19 +++ test/Java/Java-fixture/myjavac.py | 22 +++ test/Java/jar_not_in_PATH.py | 31 +---- 7 files changed, 224 insertions(+), 265 deletions(-) create mode 100644 test/Java/Java-fixture/.exclude_tests create mode 100644 test/Java/Java-fixture/myjar.py create mode 100644 test/Java/Java-fixture/myjavac.py diff --git a/SCons/Tool/jar.py b/SCons/Tool/jar.py index a19c40a..7f58dc3 100644 --- a/SCons/Tool/jar.py +++ b/SCons/Tool/jar.py @@ -29,15 +29,19 @@ selection method. """ import os +from typing import List +import SCons.Node +import SCons.Node.FS import SCons.Subst +import SCons.Tool import SCons.Util import SCons.Warnings from SCons.Node.FS import _my_normcase from SCons.Tool.JavaCommon import get_java_install_dirs -def jarSources(target, source, env, for_signature): +def jarSources(target, source, env, for_signature) -> List[str]: """Only include sources that are not a manifest file.""" try: env['JARCHDIR'] @@ -51,21 +55,22 @@ def jarSources(target, source, env, for_signature): result = [] for src in source: contents = src.get_text_contents() - if not contents.startswith("Manifest-Version"): - if jarchdir_set: - _chdir = jarchdir - else: - try: - _chdir = src.attributes.java_classdir - except AttributeError: - _chdir = None - if _chdir: - # If we are changing the dir with -C, then sources should - # be relative to that directory. - src = SCons.Subst.Literal(src.get_path(_chdir)) - result.append('-C') - result.append(_chdir) - result.append(src) + if contents.startswith("Manifest-Version"): + continue + if jarchdir_set: + _chdir = jarchdir + else: + try: + _chdir = src.attributes.java_classdir + except AttributeError: + _chdir = None + if _chdir: + # If we are changing the dir with -C, then sources should + # be relative to that directory. + src = SCons.Subst.Literal(src.get_path(_chdir)) + result.append('-C') + result.append(_chdir) + result.append(src) return result def jarManifest(target, source, env, for_signature): @@ -76,7 +81,7 @@ def jarManifest(target, source, env, for_signature): return src return '' -def jarFlags(target, source, env, for_signature): +def jarFlags(target, source, env, for_signature) -> str: """If we have a manifest, make sure that the 'm' flag is specified.""" jarflags = env.subst('$JARFLAGS', target=target, source=source) @@ -88,16 +93,19 @@ def jarFlags(target, source, env, for_signature): break return jarflags -def Jar(env, target = None, source = [], *args, **kw): - """ - A pseudo-Builder wrapper around the separate Jar sources{File,Dir} - Builders. +def Jar(env, target=None, source=[], *args, **kw): + """The Jar Builder. + + This is a pseudo-Builder wrapper around the separate jar builders + depending on whether the sources are a file list or a directory. """ + # TODO: W1113: Keyword argument before variable positional arguments list in the definition of Jar function + # TODO: W0102: Dangerous default value [] as argument # jar target should not be a list so assume they passed # no target and want implicit target to be made and the arg # was actaully the list of sources - if SCons.Util.is_List(target) and source == []: + if SCons.Util.is_List(target) and source is None: SCons.Warnings.warn( SCons.Warnings.SConsWarning, "Making implicit target jar file, and treating the list as sources" @@ -105,14 +113,14 @@ def Jar(env, target = None, source = [], *args, **kw): source = target target = None - # mutiple targets pass so build each target the same from the + # mutiple targets passed so build each target the same from the # same source #TODO Maybe this should only be done once, and the result copied # for each target since it should result in the same? if SCons.Util.is_List(target) and SCons.Util.is_List(source): jars = [] for single_target in target: - jars += env.Jar( target = single_target, source = source, *args, **kw) + jars += env.Jar(target=single_target, source=source, *args, **kw) return jars # they passed no target so make a target implicitly @@ -121,6 +129,7 @@ def Jar(env, target = None, source = [], *args, **kw): # make target from the first source file target = os.path.splitext(str(source[0]))[0] + env.subst('$JARSUFFIX') except: + # TODO: W0702: No exception type(s) specified # something strange is happening but attempt anyways SCons.Warnings.warn( SCons.Warnings.SConsWarning, @@ -143,68 +152,68 @@ def Jar(env, target = None, source = [], *args, **kw): # if its already a class file then it can be used as a # source for jar, otherwise turn it into a class file then # return the source - def file_to_class(s): - if _my_normcase(str(s)).endswith(java_suffix): - return env.JavaClassFile(source = s, *args, **kw) - else: - return [env.fs.File(s)] + def file_to_class(src): + if _my_normcase(str(src)).endswith(java_suffix): + return env.JavaClassFile(source=src, *args, **kw) + return [env.fs.File(src)] # function for calling the JavaClassDir builder if a directory is # passed as a source to Jar builder. The JavaClassDir builder will - # return an empty list if there were not target classes built from + # return an empty list if there were no target classes built from # the directory, in this case assume the user wanted the directory # copied into the jar as is (it contains other files such as - # resources or class files compiled from proir commands) + # resources or class files compiled from prior commands) # TODO: investigate the expexcted behavior for directories that # have mixed content, such as Java files along side other files # files. - def dir_to_class(s): - dir_targets = env.JavaClassDir(source = s, *args, **kw) + def dir_to_class(src): + dir_targets = env.JavaClassDir(source=src, *args, **kw) if dir_targets == []: # no classes files could be built from the source dir # so pass the dir as is. - return [env.fs.Dir(s)] - else: - return dir_targets + return [env.fs.Dir(src)] + return dir_targets # loop through the sources and handle each accordingly # the goal here is to get all the source files into a class # file or a directory that contains class files - for s in SCons.Util.flatten(source): - s = env.subst(s) - if isinstance(s, SCons.Node.FS.Base): - if isinstance(s, SCons.Node.FS.File): + for src in SCons.Util.flatten(source): + src = env.subst(src) + if isinstance(src, SCons.Node.FS.Base): + if isinstance(src, SCons.Node.FS.File): # found a file so make sure its a class file - target_nodes.extend(file_to_class(s)) + target_nodes.extend(file_to_class(src)) else: # found a dir so get the class files out of it - target_nodes.extend(dir_to_class(s)) + target_nodes.extend(dir_to_class(src)) else: try: # source is string try to convert it to file - target_nodes.extend(file_to_class(env.fs.File(s))) + target_nodes.extend(file_to_class(env.fs.File(src))) continue except: + # TODO: W0702: No exception type(s) specified pass try: # source is string try to covnert it to dir - target_nodes.extend(dir_to_class(env.fs.Dir(s))) + target_nodes.extend(dir_to_class(env.fs.Dir(src))) continue except: + # TODO: W0702: No exception type(s) specified pass SCons.Warnings.warn( SCons.Warnings.SConsWarning, - ("File: " + str(s) + ("File: " + str(src) + " could not be identified as File or Directory, skipping.") ) - # at this point all our sources have been converted to classes or directories of class - # so pass it to the Jar builder - return env.JarFile(target = target, source = target_nodes, *args, **kw) + # at this point all our sources have been converted to classes or + # directories of class so pass it to the Jar builder + return env.JarFile(target=target, source=target_nodes, *args, **kw) -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for jar to an Environment.""" SCons.Tool.CreateJarBuilder(env) @@ -222,14 +231,14 @@ def generate(env): jar_bin_dir = os.path.dirname(jar) env.AppendENVPath('PATH', jar_bin_dir) - env['JAR'] = 'jar' - env['JARFLAGS'] = SCons.Util.CLVar('cf') - env['_JARFLAGS'] = jarFlags + env['JAR'] = 'jar' + env['JARFLAGS'] = SCons.Util.CLVar('cf') + env['_JARFLAGS'] = jarFlags env['_JARMANIFEST'] = jarManifest env['_JARSOURCES'] = jarSources - env['_JARCOM'] = '$JAR $_JARFLAGS $TARGET $_JARMANIFEST $_JARSOURCES' - env['JARCOM'] = "${TEMPFILE('$_JARCOM','$JARCOMSTR')}" - env['JARSUFFIX'] = '.jar' + env['_JARCOM'] = '$JAR $_JARFLAGS $TARGET $_JARMANIFEST $_JARSOURCES' + env['JARCOM'] = "${TEMPFILE('$_JARCOM','$JARCOMSTR')}" + env['JARSUFFIX'] = '.jar' def exists(env): # As reported by Jan Nijtmans in issue #2730, the simple @@ -238,7 +247,7 @@ def exists(env): # stop trying to detect an executable (analogous to the # javac Builder). # TODO: Come up with a proper detect() routine...and enable it. - return 1 + return True # Local Variables: # tab-width:4 diff --git a/test/Java/JAR.py b/test/Java/JAR.py index bc52a89..2d67717 100644 --- a/test/Java/JAR.py +++ b/test/Java/JAR.py @@ -23,6 +23,12 @@ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +""" +Test Jar builder. + +These tests require a findable/working Java subsystem. +""" + import os import TestSCons @@ -30,115 +36,23 @@ _python_ = TestSCons._python_ test = TestSCons.TestSCons() -# Keep this logic because it skips the test if javac or jar not found. where_javac, java_version = test.java_where_javac() where_jar = test.java_where_jar() -test.write('myjar.py', r""" -import sys -args = sys.argv[1:] -while args: - a = args[0] - if a == 'cf': - out = args[1] - args = args[1:] - else: - break - args = args[1:] -outfile = open(out, 'w') -for file in args: - infile = open(file, 'r') - for l in infile.readlines(): - if l[:7] != '/*jar*/': - outfile.write(l) -sys.exit(0) -""") - -test.write('SConstruct', """ -DefaultEnvironment(tools=[]) -env = Environment(tools = ['jar'], - JAR = r'%(_python_)s myjar.py') -env.Jar(target = 'test1.jar', source = 'test1.class') -""" % locals()) - -test.write('test1.class', """\ -test1.class -/*jar*/ -line 3 -""") - -test.run(arguments='.', stderr=None) - -test.must_match('test1.jar', "test1.class\nline 3\n", mode='r') - -if os.path.normcase('.class') == os.path.normcase('.CLASS'): - - test.write('SConstruct', """ -DefaultEnvironment(tools=[]) -env = Environment(tools = ['jar'], - JAR = r'%(_python_)s myjar.py') -env.Jar(target = 'test2.jar', source = 'test2.CLASS') -""" % locals()) - - test.write('test2.CLASS', """\ -test2.CLASS -/*jar*/ -line 3 -""") - - test.run(arguments='.', stderr=None) - - test.must_match('test2.jar', "test2.CLASS\nline 3\n", mode='r') - -test.write('myjar2.py', r""" -import sys -f=open(sys.argv[2], 'w') -f.write(" ".join(sys.argv[1:])) -f.write("\n") -f.close() -sys.exit(0) -""") - -test.write('SConstruct', """ -DefaultEnvironment(tools=[]) -env = Environment(tools = ['jar'], - JAR = r'%(_python_)s myjar2.py', - JARFLAGS='cvf') -env.Jar(target = 'classes.jar', source = [ 'testdir/bar.class', - 'foo.mf' ], - TESTDIR='testdir', - JARCHDIR='$TESTDIR') -""" % locals()) - -test.subdir('testdir') -test.write(['testdir', 'bar.class'], 'foo') -test.write('foo.mf', - """Manifest-Version : 1.0 - blah - blah - blah - """) -test.run(arguments='classes.jar') -test.must_match('classes.jar', - 'cvfm classes.jar foo.mf -C testdir bar.class\n', mode='r') - test.file_fixture('wrapper_with_args.py') -test.write('SConstruct', """ +test.write('SConstruct', """\ DefaultEnvironment(tools=[]) -foo = Environment(tools = ['javac', 'jar']) +foo = Environment(tools=['javac', 'jar']) # jar = foo.Dictionary('JAR') -bar = foo.Clone(JAR = r'%(_python_)s wrapper_with_args.py jar') -foo.Java(target = 'classes', source = 'com/sub/foo') -bar.Java(target = 'classes', source = 'com/sub/bar') -foo.Jar(target = 'foo', source = 'classes/com/sub/foo') -bar.Jar(target = 'bar', source = Dir('classes/com/sub/bar')) +bar = foo.Clone(JAR=r'%(_python_)s wrapper_with_args.py jar') +foo.Java(target='classes', source='com/sub/foo') +bar.Java(target='classes', source='com/sub/bar') +foo.Jar(target='foo', source='classes/com/sub/foo') +bar.Jar(target='bar', source=Dir('classes/com/sub/bar')) """ % locals()) -test.subdir('com', - ['com', 'sub'], - ['com', 'sub', 'foo'], - ['com', 'sub', 'bar']) +test.subdir('com', ['com', 'sub'], ['com', 'sub', 'foo'], ['com', 'sub', 'bar']) test.write(['com', 'sub', 'foo', 'Example1.java'], """\ package com.sub.foo; @@ -228,13 +142,12 @@ test.run(arguments = '.') expected_wrapper_out = "wrapper_with_args.py jar cf bar.jar classes/com/sub/bar\n" expected_wrapper_out = expected_wrapper_out.replace('/', os.sep) -test.must_match('wrapper.out', - expected_wrapper_out % locals(), mode='r') +test.must_match('wrapper.out', expected_wrapper_out % locals(), mode='r') test.must_exist('foo.jar') test.must_exist('bar.jar') -test.up_to_date(arguments = '.') +test.up_to_date(arguments='.') ####### # test java source files as source to Jar builder @@ -250,22 +163,43 @@ test.write(['testdir2', 'SConstruct'], """ DefaultEnvironment(tools=[]) foo = Environment() -foo.Jar(target = 'foobar', source = [ - 'com/javasource/JavaFile1.java', - 'com/javasource/JavaFile2.java', - 'com/javasource/JavaFile3.java' -]) -foo.Jar(target = ['foo', 'bar'], source = [ - 'com/javasource/JavaFile1.java', - 'com/javasource/JavaFile2.java', - 'com/javasource/JavaFile3.java' -]) -foo.Command("foobarTest", [], Mkdir("foobarTest") ) -foo.Command('foobarTest/com/javasource/JavaFile3.java', 'foobar.jar', foo['JAR'] + ' xvf ../foobar.jar', chdir='foobarTest') -foo.Command("fooTest", [], Mkdir("fooTest") ) -foo.Command('fooTest/com/javasource/JavaFile3.java', 'foo.jar', foo['JAR'] + ' xvf ../foo.jar', chdir='fooTest') -foo.Command("barTest", [], Mkdir("barTest") ) -foo.Command('barTest/com/javasource/JavaFile3.java', 'bar.jar', foo['JAR'] + ' xvf ../bar.jar', chdir='barTest') +foo.Jar( + target='foobar', + source=[ + 'com/javasource/JavaFile1.java', + 'com/javasource/JavaFile2.java', + 'com/javasource/JavaFile3.java', + ], +) +foo.Jar( + target=['foo', 'bar'], + source=[ + 'com/javasource/JavaFile1.java', + 'com/javasource/JavaFile2.java', + 'com/javasource/JavaFile3.java', + ], +) +foo.Command("foobarTest", [], Mkdir("foobarTest")) +foo.Command( + 'foobarTest/com/javasource/JavaFile3.java', + 'foobar.jar', + foo['JAR'] + ' xvf ../foobar.jar', + chdir='foobarTest', +) +foo.Command("fooTest", [], Mkdir("fooTest")) +foo.Command( + 'fooTest/com/javasource/JavaFile3.java', + 'foo.jar', + foo['JAR'] + ' xvf ../foo.jar', + chdir='fooTest', +) +foo.Command("barTest", [], Mkdir("barTest")) +foo.Command( + 'barTest/com/javasource/JavaFile3.java', + 'bar.jar', + foo['JAR'] + ' xvf ../bar.jar', + chdir='barTest', +) """) test.write(['testdir2', 'com', 'javasource', 'JavaFile1.java'], """\ @@ -309,11 +243,7 @@ public class JavaFile3 # use regex . for dirsep so this will work on both windows and other platforms. expect = ".*jar cf foo.jar -C com.javasource.JavaFile1 com.javasource.JavaFile1.class -C com.javasource.JavaFile2 com.javasource.JavaFile2.class -C com.javasource.JavaFile3 com.javasource.JavaFile3.class.*" -test.run(chdir='testdir2', - match=TestSCons.match_re_dotall, - stdout = expect) - - +test.run(chdir='testdir2', match=TestSCons.match_re_dotall, stdout=expect) #test single target jar test.must_exist(['testdir2','foobar.jar']) @@ -338,12 +268,14 @@ test.must_exist(['testdir2', 'barTest', 'com', 'javasource', 'JavaFile3.class']) # test list of lists # make some directories to test in -test.subdir('listOfLists', - ['manifest_dir'], - ['listOfLists', 'src'], - ['listOfLists', 'src', 'com'], - ['listOfLists', 'src', 'com', 'javasource'], - ['listOfLists', 'src', 'com', 'resource']) +test.subdir( + 'listOfLists', + ['manifest_dir'], + ['listOfLists', 'src'], + ['listOfLists', 'src', 'com'], + ['listOfLists', 'src', 'com', 'javasource'], + ['listOfLists', 'src', 'com', 'resource'], +) # test varient dir and lists of lists test.write(['listOfLists', 'SConstruct'], """ @@ -352,15 +284,26 @@ DefaultEnvironment(tools=[]) foo = Environment() foo.VariantDir('build', 'src', duplicate=0) foo.VariantDir('test', '../manifest_dir', duplicate=0) -sourceFiles = ["src/com/javasource/JavaFile1.java", "src/com/javasource/JavaFile2.java", "src/com/javasource/JavaFile3.java",] +sourceFiles = [ + "src/com/javasource/JavaFile1.java", + "src/com/javasource/JavaFile2.java", + "src/com/javasource/JavaFile3.java", +] list_of_class_files = foo.Java('build', source=sourceFiles) resources = ['build/com/resource/resource1.txt', 'build/com/resource/resource2.txt'] for resource in resources: - foo.Command(resource, list_of_class_files, Copy(resource, resource.replace('build','src'))) + foo.Command( + resource, list_of_class_files, Copy(resource, resource.replace('build', 'src')) + ) contents = [list_of_class_files, resources] -foo.Jar(target = 'lists', source = contents + ['test/MANIFEST.mf'], JARCHDIR='build') -foo.Command("listsTest", [], Mkdir("listsTest") ) -foo.Command('listsTest/src/com/javasource/JavaFile3.java', 'lists.jar', foo['JAR'] + ' xvf ../lists.jar', chdir='listsTest') +foo.Jar(target='lists', source=contents + ['test/MANIFEST.mf'], JARCHDIR='build') +foo.Command("listsTest", [], Mkdir("listsTest")) +foo.Command( + 'listsTest/src/com/javasource/JavaFile3.java', + 'lists.jar', + foo['JAR'] + ' xvf ../lists.jar', + chdir='listsTest', +) """) test.write(['listOfLists', 'src', 'com', 'javasource', 'JavaFile1.java'], """\ @@ -431,25 +374,34 @@ test.must_contain(['listOfLists', 'listsTest', 'META-INF', 'MANIFEST.MF'], b"MyM # test different style of passing in dirs # make some directories to test in -test.subdir('testdir3', - ['testdir3', 'com'], - ['testdir3', 'com', 'sub'], - ['testdir3', 'com', 'sub', 'foo'], - ['testdir3', 'com', 'sub', 'bar']) +test.subdir( + 'testdir3', + ['testdir3', 'com'], + ['testdir3', 'com', 'sub'], + ['testdir3', 'com', 'sub', 'foo'], + ['testdir3', 'com', 'sub', 'bar'], +) # Create the jars then extract them back to check contents test.write(['testdir3', 'SConstruct'], """ DefaultEnvironment(tools=[]) foo = Environment() -bar = foo.Clone() -foo.Java(target = 'classes', source = 'com/sub/foo') -bar.Java(target = 'classes', source = 'com/sub/bar') -foo.Jar(target = 'foo', source = 'classes/com/sub/foo', JARCHDIR='classes') -bar.Jar(target = 'bar', source = Dir('classes/com/sub/bar'), JARCHDIR='classes') -foo.Command("fooTest", 'foo.jar', Mkdir("fooTest") ) +foo_cls = foo.Java(target='classes', source='com/sub/foo') +foo_res = 'classes/com/sub/foo/NonJava.txt' +foo_res_src = 'com/sub/foo/NonJava.txt' +foo.Command(foo_res, foo_cls, Copy(foo_res, foo_res_src)) +foo.Jar(target='foo', source='classes/com/sub/foo', JARCHDIR='classes') +foo.Command("fooTest", 'foo.jar', Mkdir("fooTest")) foo.Command('doesnt_exist1', "fooTest", foo['JAR'] + ' xvf ../foo.jar', chdir='fooTest') -bar.Command("barTest", 'bar.jar', Mkdir("barTest") ) + +bar = foo.Clone() +bar_cls = bar.Java(target='classes', source='com/sub/bar') +bar_res = 'classes/com/sub/bar/NonJava.txt' +bar_res_src = 'com/sub/bar/NonJava.txt' +bar.Command(bar_res, bar_cls, Copy(bar_res, bar_res_src)) +bar.Jar(target='bar', source=Dir('classes/com/sub/bar'), JARCHDIR='classes') +bar.Command("barTest", 'bar.jar', Mkdir("barTest")) bar.Command('doesnt_exist2', 'barTest', bar['JAR'] + ' xvf ../bar.jar', chdir='barTest') """) @@ -549,7 +501,6 @@ test.run(chdir='testdir3') # check the output and make sure the java files got converted to classes - # make sure there are class in the jar test.must_exist(['testdir3','foo.jar']) test.must_exist(['testdir3', 'fooTest', 'com', 'sub', 'foo', 'Example1.class']) @@ -557,7 +508,7 @@ test.must_exist(['testdir3', 'fooTest', 'com', 'sub', 'foo', 'Example2.class']) test.must_exist(['testdir3', 'fooTest', 'com', 'sub', 'foo', 'Example3.class']) # TODO: determine expected behavior with resource files, should they be # automatically copied in or specified in seperate commands -#test.must_exist(['testdir3', 'fooTest', 'com', 'sub', 'foo', 'NonJava.txt']) +test.must_exist(['testdir3', 'fooTest', 'com', 'sub', 'foo', 'NonJava.txt']) # make sure both jars got createds test.must_exist(['testdir3','bar.jar']) @@ -566,11 +517,10 @@ test.must_exist(['testdir3', 'barTest', 'com', 'sub', 'bar', 'Example5.class']) test.must_exist(['testdir3', 'barTest', 'com', 'sub', 'bar', 'Example6.class']) # TODO: determine expected behavior with resource files, should they be # automatically copied in or specified in seperate commands -#test.must_exist(['testdir3', 'fooTest', 'com', 'sub', 'bar', 'NonJava.txt']) +test.must_exist(['testdir3', 'barTest', 'com', 'sub', 'bar', 'NonJava.txt']) test.pass_test() - # Local Variables: # tab-width:4 # indent-tabs-mode:nil diff --git a/test/Java/JAVAC.py b/test/Java/JAVAC.py index 20f7f96..f303e87 100644 --- a/test/Java/JAVAC.py +++ b/test/Java/JAVAC.py @@ -25,6 +25,8 @@ """ Test setting the JAVAC variable. + +This test does not require a JDK to operate. """ import os @@ -35,33 +37,11 @@ _python_ = TestSCons._python_ test = TestSCons.TestSCons() +test.file_fixture(['Java-fixture', 'myjavac.py']) - -test.write('myjavac.py', r""" -import sys -args = sys.argv[1:] -while args: - a = args[0] - if a == '-d': - args = args[1:] - elif a == '-sourcepath': - args = args[1:] - else: - break - args = args[1:] -for file in args: - infile = open(file, 'r') - outfile = open(file[:-5] + '.class', 'w') - for l in infile.readlines(): - if l[:9] != '/*javac*/': - outfile.write(l) -sys.exit(0) -""") - -test.write('SConstruct', """ -env = Environment(tools = ['javac'], - JAVAC = r'%(_python_)s myjavac.py') -env.Java(target = '.', source = '.') +test.write('SConstruct', """\ +env = Environment(tools=['javac'], JAVAC=r'%(_python_)s myjavac.py') +env.Java(target='.', source='.') """ % locals()) test.write('test1.java', """\ @@ -71,15 +51,12 @@ line 3 """) test.run(arguments='.', stderr=None) - test.must_match('test1.class', "test1.java\nline 3\n", mode='r') if os.path.normcase('.java') == os.path.normcase('.JAVA'): - test.write('SConstruct', """\ -env = Environment(tools = ['javac'], - JAVAC = r'%(_python_)s myjavac.py') -env.Java(target = '.', source = '.') +env = Environment(tools=['javac'], JAVAC=r'%(_python_)s myjavac.py') +env.Java(target='.', source='.') """ % locals()) test.write('test2.JAVA', """\ @@ -89,11 +66,8 @@ line 3 """) test.run(arguments='.', stderr=None) - test.must_match('test2.class', "test2.JAVA\nline 3\n", mode='r') - - test.pass_test() # Local Variables: diff --git a/test/Java/Java-fixture/.exclude_tests b/test/Java/Java-fixture/.exclude_tests new file mode 100644 index 0000000..37004e6 --- /dev/null +++ b/test/Java/Java-fixture/.exclude_tests @@ -0,0 +1,2 @@ +myjar.py +myjavac.py diff --git a/test/Java/Java-fixture/myjar.py b/test/Java/Java-fixture/myjar.py new file mode 100644 index 0000000..a47e3b0 --- /dev/null +++ b/test/Java/Java-fixture/myjar.py @@ -0,0 +1,19 @@ +import fileinput +import sys + +args = sys.argv[1:] +while args: + arg = args[0] + if arg == 'cf': + out = args[1] + args = args[1:] + else: + break + args = args[1:] + +with open(out, 'wb') as ofp, fileinput.input(files=args, mode='rb') as ifp: + for line in ifp: + if not line.startswith(b'/*jar*/'): + ofp.write(line) + +sys.exit(0) diff --git a/test/Java/Java-fixture/myjavac.py b/test/Java/Java-fixture/myjavac.py new file mode 100644 index 0000000..0177c51 --- /dev/null +++ b/test/Java/Java-fixture/myjavac.py @@ -0,0 +1,22 @@ +import fileinput +import sys + +args = sys.argv[1:] +while args: + arg = args[0] + if arg == '-d': + args = args[1:] + elif arg == '-sourcepath': + args = args[1:] + else: + break + args = args[1:] + +for file in args: + out = file.lower().replace('.java', '.class') + with open(file, 'rb') as infile, open(out, 'wb') as outfile: + for line in infile: + if not line.startswith(b'/*javac*/'): + outfile.write(line) + +sys.exit(0) diff --git a/test/Java/jar_not_in_PATH.py b/test/Java/jar_not_in_PATH.py index 26e92ce..05bb9c8 100644 --- a/test/Java/jar_not_in_PATH.py +++ b/test/Java/jar_not_in_PATH.py @@ -35,33 +35,16 @@ _python_ = TestSCons._python_ test = TestSCons.TestSCons() -test.write('myjar.py', r""" -import sys -args = sys.argv[1:] -while args: - a = args[0] - if a == 'cf': - out = args[1] - args = args[1:] - else: - break - args = args[1:] -outfile = open(out, 'wb') -for file in args: - infile = open(file, 'rb') - for l in infile.readlines(): - if l[:7] != '/*jar*/': - outfile.write(l) -sys.exit(0) -""") +test.file_fixture(['Java-fixture', 'myjar.py']) -test.write('SConstruct', """ +test.write('SConstruct', """\ import os -oldpath = os.environ.get('PATH','') -env = Environment(ENV = {'PATH' : ['.']}) + +oldpath = os.environ.get('PATH', '') +env = Environment(ENV={'PATH': ['.']}) env['ENV']['PATH'] = oldpath env['JAR'] = r'%(_python_)s ./myjar.py' -env.Jar(target = 'test1.jar', source = 'test1.class') +env.Jar(target='test1.jar', source='test1.class') """ % locals()) test.write('test1.class', """\ @@ -70,7 +53,7 @@ test1.class line 3 """) -test.run(arguments = '.', stderr = None) +test.run(arguments='.', stderr=None) test.must_exist('test1.jar') -- cgit v0.12 From aed511ce545afc16bd8704eafd869be10b23d0a6 Mon Sep 17 00:00:00 2001 From: Daniel Moody Date: Mon, 24 Jan 2022 14:53:40 -0600 Subject: added missing newline to cachedir debug message. --- SCons/CacheDir.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SCons/CacheDir.py b/SCons/CacheDir.py index 8be6643..14e52ad 100644 --- a/SCons/CacheDir.py +++ b/SCons/CacheDir.py @@ -125,7 +125,7 @@ def CachePushFunc(target, source, env): # In any case, inability to push a file to cache doesn't affect # the correctness of the build, so just print a warning. msg = errfmt % (str(t), cachefile) - cd.CacheDebug(errfmt, str(t), cachefile) + cd.CacheDebug(errfmt + '\n', str(t), cachefile) SCons.Warnings.warn(SCons.Warnings.CacheWriteErrorWarning, msg) CachePush = SCons.Action.Action(CachePushFunc, None) -- cgit v0.12 From 08a5946e09cf6bce2af218da94834ac38aca0eda Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Mon, 24 Jan 2022 14:06:37 -0700 Subject: Fix ci complaint for PR #4089 Signed-off-by: Mats Wichmann --- SCons/Tool/jar.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SCons/Tool/jar.py b/SCons/Tool/jar.py index 7f58dc3..3a75be7 100644 --- a/SCons/Tool/jar.py +++ b/SCons/Tool/jar.py @@ -105,7 +105,7 @@ def Jar(env, target=None, source=[], *args, **kw): # jar target should not be a list so assume they passed # no target and want implicit target to be made and the arg # was actaully the list of sources - if SCons.Util.is_List(target) and source is None: + if SCons.Util.is_List(target) and source is []: SCons.Warnings.warn( SCons.Warnings.SConsWarning, "Making implicit target jar file, and treating the list as sources" -- cgit v0.12 From 45c02700a8356785ce995a381326d8b5878310e7 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Mon, 24 Jan 2022 15:26:45 -0700 Subject: Actually commit fixed myjava.py [skip appveyor] Signed-off-by: Mats Wichmann --- test/Java/Java-fixture/myjavac.py | 1 - 1 file changed, 1 deletion(-) diff --git a/test/Java/Java-fixture/myjavac.py b/test/Java/Java-fixture/myjavac.py index 0177c51..1c7fdea 100644 --- a/test/Java/Java-fixture/myjavac.py +++ b/test/Java/Java-fixture/myjavac.py @@ -1,4 +1,3 @@ -import fileinput import sys args = sys.argv[1:] -- cgit v0.12 From 5fcf75e653d4fe5cd0f171635ee569902d041549 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Fri, 28 Jan 2022 06:39:16 -0700 Subject: Java not-in-path tests use limited tools There's no reason for these tests to initialize all tools since only checking for one. During development of unrelated PR #4088 these two failed initializing gcc tool - might as well run as lean as possible. Signed-off-by: Mats Wichmann --- SCons/Tool/jar.py | 2 +- test/Java/jar_not_in_PATH.py | 3 ++- test/Java/rmic_not_in_PATH.py | 8 +++++--- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/SCons/Tool/jar.py b/SCons/Tool/jar.py index 3a75be7..ae44ff3 100644 --- a/SCons/Tool/jar.py +++ b/SCons/Tool/jar.py @@ -105,7 +105,7 @@ def Jar(env, target=None, source=[], *args, **kw): # jar target should not be a list so assume they passed # no target and want implicit target to be made and the arg # was actaully the list of sources - if SCons.Util.is_List(target) and source is []: + if SCons.Util.is_List(target) and source == []: SCons.Warnings.warn( SCons.Warnings.SConsWarning, "Making implicit target jar file, and treating the list as sources" diff --git a/test/Java/jar_not_in_PATH.py b/test/Java/jar_not_in_PATH.py index 05bb9c8..b890ba1 100644 --- a/test/Java/jar_not_in_PATH.py +++ b/test/Java/jar_not_in_PATH.py @@ -41,7 +41,8 @@ test.write('SConstruct', """\ import os oldpath = os.environ.get('PATH', '') -env = Environment(ENV={'PATH': ['.']}) +DefaultEnvironment(tools=[]) +env = Environment(ENV={'PATH': ['.']}, tools=['javac', 'jar']) env['ENV']['PATH'] = oldpath env['JAR'] = r'%(_python_)s ./myjar.py' env.Jar(target='test1.jar', source='test1.class') diff --git a/test/Java/rmic_not_in_PATH.py b/test/Java/rmic_not_in_PATH.py index ac3f28e..68a2c30 100644 --- a/test/Java/rmic_not_in_PATH.py +++ b/test/Java/rmic_not_in_PATH.py @@ -63,11 +63,13 @@ sys.exit(0) test.write('SConstruct', """ import os -oldpath = os.environ.get('PATH','') -env = Environment(ENV = {'PATH' : ['.']}) + +oldpath = os.environ.get('PATH', '') +DefaultEnvironment(tools=[]) +env = Environment(ENV={'PATH': ['.']}, tools=['javac', 'rmic']) env['ENV']['PATH'] = oldpath env['RMIC'] = r'%(_python_)s myrmic.py' -env.RMIC(target = 'outdir', source = 'test1.java') +env.RMIC(target='outdir', source='test1.java') """ % locals()) test.write('test1.java', """\ -- cgit v0.12