diff --git a/.travis.yml b/.travis.yml index a6dd2dcf28..f27f024f2d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ matrix: python: 2.7 - name: "Python 2.7 on macOS" os: osx - osx_image: xcode10.2 + osx_image: xcode11 language: shell # 'language: python' is not yet supported on macOS env: NODE_GYP_FORCE_PYTHON=python2 before_install: HOMEBREW_NO_AUTO_UPDATE=1 brew install npm @@ -28,6 +28,7 @@ matrix: PATH=/c/Python27:/c/Python27/Scripts:$PATH NODE_GYP_FORCE_PYTHON=/c/Python27/python.exe before_install: choco install python2 + - name: "Node.js 6 & Python 3.7 on Linux" python: 3.7 env: NODE_GYP_FORCE_PYTHON=python3 EXPERIMENTAL_NODE_GYP_PYTHON3=1 @@ -44,6 +45,12 @@ matrix: python: 3.7 env: NODE_GYP_FORCE_PYTHON=python3 EXPERIMENTAL_NODE_GYP_PYTHON3=1 before_install: nvm install 12 + - name: "Python 3.7 on macOS" + os: osx + #osx_image: xcode11 + language: shell # 'language: python' is not yet supported on macOS + env: NODE_GYP_FORCE_PYTHON=python3 EXPERIMENTAL_NODE_GYP_PYTHON3=1 + before_install: HOMEBREW_NO_AUTO_UPDATE=1 brew install npm - name: "Node.js 12 & Python 3.7 on Windows" os: windows language: node_js @@ -53,12 +60,7 @@ matrix: NODE_GYP_FORCE_PYTHON=/c/Python37/python.exe EXPERIMENTAL_NODE_GYP_PYTHON3=1 before_install: choco install python - allow_failures: - - env: NODE_GYP_FORCE_PYTHON=python3 EXPERIMENTAL_NODE_GYP_PYTHON3=1 - - env: >- - PATH=/c/Python37:/c/Python37/Scripts:$PATH - NODE_GYP_FORCE_PYTHON=/c/Python37/python.exe - EXPERIMENTAL_NODE_GYP_PYTHON3=1 + install: #- pip install -r requirements.txt - pip install flake8 # pytest # add another testing frameworks later diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a99ef2d0a..3dbc5d9244 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,27 @@ +v5.0.4 2019-09-27 +================= + +* [[`1236869ffc`](https://github.com/nodejs/node-gyp/commit/1236869ffc)] - **gyp**: modify XcodeVersion() to convert "4.2" to "0420" and "10.0" to "1000" (Christian Clauss) [#1895](https://github.com/nodejs/node-gyp/pull/1895) +* [[`36638afe48`](https://github.com/nodejs/node-gyp/commit/36638afe48)] - **gyp**: more decode stdout on Python 3 (cclauss) [#1894](https://github.com/nodejs/node-gyp/pull/1894) +* [[`f753c167c5`](https://github.com/nodejs/node-gyp/commit/f753c167c5)] - **gyp**: decode stdout on Python 3 (cclauss) [#1890](https://github.com/nodejs/node-gyp/pull/1890) +* [[`60a4083523`](https://github.com/nodejs/node-gyp/commit/60a4083523)] - **doc**: update xcode install instructions to match Node's BUILDING (Nhan Khong) [#1884](https://github.com/nodejs/node-gyp/pull/1884) +* [[`19dbc9ac32`](https://github.com/nodejs/node-gyp/commit/19dbc9ac32)] - **deps**: update tar to 4.4.12 (Matheus Marchini) [#1889](https://github.com/nodejs/node-gyp/pull/1889) +* [[`5f3ed92181`](https://github.com/nodejs/node-gyp/commit/5f3ed92181)] - **bin**: fix the usage instructions (Halit Ogunc) [#1888](https://github.com/nodejs/node-gyp/pull/1888) +* [[`aab118edf1`](https://github.com/nodejs/node-gyp/commit/aab118edf1)] - **lib**: adding keep-alive header to download requests (Milad Farazmand) [#1863](https://github.com/nodejs/node-gyp/pull/1863) +* [[`1186e89326`](https://github.com/nodejs/node-gyp/commit/1186e89326)] - **lib**: ignore non-critical os.userInfo() failures (Rod Vagg) [#1835](https://github.com/nodejs/node-gyp/pull/1835) +* [[`785e527c3d`](https://github.com/nodejs/node-gyp/commit/785e527c3d)] - **doc**: fix missing argument for setting python path (lagorsse) [#1802](https://github.com/nodejs/node-gyp/pull/1802) +* [[`a97615196c`](https://github.com/nodejs/node-gyp/commit/a97615196c)] - **gyp**: rm semicolons (Python != JavaScript) (MattIPv4) [#1858](https://github.com/nodejs/node-gyp/pull/1858) +* [[`06019bac24`](https://github.com/nodejs/node-gyp/commit/06019bac24)] - **gyp**: assorted typo fixes (XhmikosR) [#1853](https://github.com/nodejs/node-gyp/pull/1853) +* [[`3f4972c1ca`](https://github.com/nodejs/node-gyp/commit/3f4972c1ca)] - **gyp**: use "is" when comparing to None (Vladyslav Burzakovskyy) [#1860](https://github.com/nodejs/node-gyp/pull/1860) +* [[`1cb4708073`](https://github.com/nodejs/node-gyp/commit/1cb4708073)] - **src,win**: improve unmanaged handling (Peter Sabath) [#1852](https://github.com/nodejs/node-gyp/pull/1852) +* [[`5553cd910e`](https://github.com/nodejs/node-gyp/commit/5553cd910e)] - **gyp**: improve Windows+Cygwin compatibility (Jose Quijada) [#1817](https://github.com/nodejs/node-gyp/pull/1817) +* [[`8bcb1fbb43`](https://github.com/nodejs/node-gyp/commit/8bcb1fbb43)] - **gyp**: Python 3 Windows fixes (João Reis) [#1843](https://github.com/nodejs/node-gyp/pull/1843) +* [[`2e24d0a326`](https://github.com/nodejs/node-gyp/commit/2e24d0a326)] - **test**: accept Python 3 in test-find-python.js (João Reis) [#1843](https://github.com/nodejs/node-gyp/pull/1843) +* [[`1267b4dc1c`](https://github.com/nodejs/node-gyp/commit/1267b4dc1c)] - **build**: add test run Python 3.7 on macOS (Christian Clauss) [#1843](https://github.com/nodejs/node-gyp/pull/1843) +* [[`da1b031aa3`](https://github.com/nodejs/node-gyp/commit/da1b031aa3)] - **build**: import StringIO on Python 2 and Python 3 (Christian Clauss) [#1836](https://github.com/nodejs/node-gyp/pull/1836) +* [[`fa0ed4aa42`](https://github.com/nodejs/node-gyp/commit/fa0ed4aa42)] - **build**: more Python 3 compat, replace compile with ast (cclauss) [#1820](https://github.com/nodejs/node-gyp/pull/1820) +* [[`18d5c7c9d0`](https://github.com/nodejs/node-gyp/commit/18d5c7c9d0)] - **win,src**: update win\_delay\_load\_hook.cc to work with /clr (Ivan Petrovic) [#1819](https://github.com/nodejs/node-gyp/pull/1819) + v5.0.3 2019-07-17 ================= diff --git a/README.md b/README.md index b0900028d7..0c76ffc09b 100644 --- a/README.md +++ b/README.md @@ -35,8 +35,7 @@ You will also need to install: * `python` (`v2.7` recommended, `v3.x.x` is __*not*__ supported) (already installed on macOS) * [Xcode](https://developer.apple.com/xcode/download/) - * You also need to install the `Command Line Tools` via Xcode. You can find this under the menu `Xcode -> Preferences -> Locations` (or by running `xcode-select --install` in your Terminal) - * This step will install `gcc` and the related toolchain containing `make` + * You also need to install the `XCode Command Line Tools` by running `xcode-select --install`. Alternatively, if you already have the full Xcode installed, you can find them under the menu `Xcode -> Open Developer Tool -> More Developer Tools...`. This step will install `clang`, `clang++`, and `make`. ### On Windows @@ -63,7 +62,7 @@ If you have multiple Python versions installed, you can identify which Python version `node-gyp` uses by setting the `--python` variable: ``` bash -$ node-gyp --python /path/to/python2.7 +$ node-gyp --python /path/to/executable/python2.7 ``` If `node-gyp` is called by way of `npm`, *and* you have multiple versions of diff --git a/gyp/gyp_main.py b/gyp/gyp_main.py index 25a6eba94a..aece53c8eb 100755 --- a/gyp/gyp_main.py +++ b/gyp/gyp_main.py @@ -6,10 +6,44 @@ import os import sys +import subprocess + +PY3 = bytes != str + +# Below IsCygwin() function copied from pylib/gyp/common.py +def IsCygwin(): + try: + out = subprocess.Popen("uname", + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + stdout, stderr = out.communicate() + if PY3: + stdout = stdout.decode("utf-8") + return "CYGWIN" in str(stdout) + except Exception: + return False + + +def UnixifyPath(path): + try: + if not IsCygwin(): + return path + out = subprocess.Popen(["cygpath", "-u", path], + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + stdout, stderr = out.communicate() + if PY3: + stdout = stdout.decode("utf-8") + return str(stdout) + except Exception: + return path + # Make sure we're using the version of pylib in this repo, not one installed -# elsewhere on the system. -sys.path.insert(0, os.path.join(os.path.dirname(sys.argv[0]), 'pylib')) +# elsewhere on the system. Also convert to Unix style path on Cygwin systems, +# else the 'gyp' library will not be found +path = UnixifyPath(sys.argv[0]) +sys.path.insert(0, os.path.join(os.path.dirname(path), 'pylib')) import gyp if __name__ == '__main__': diff --git a/gyp/pylib/gyp/MSVSNew.py b/gyp/pylib/gyp/MSVSNew.py index 0ec628cc1f..9b64e2c1c8 100644 --- a/gyp/pylib/gyp/MSVSNew.py +++ b/gyp/pylib/gyp/MSVSNew.py @@ -45,7 +45,7 @@ def MakeGuid(name, seed='msvs_new'): not change when the project for a target is rebuilt. """ # Calculate a MD5 signature for the seed and name. - d = hashlib.md5(str(seed) + str(name)).hexdigest().upper() + d = hashlib.md5((str(seed) + str(name)).encode('utf-8')).hexdigest().upper() # Convert most of the signature to GUID form (discard the rest) guid = ('{' + d[:8] + '-' + d[8:12] + '-' + d[12:16] + '-' + d[16:20] + '-' + d[20:32] + '}') diff --git a/gyp/pylib/gyp/MSVSSettings_test.py b/gyp/pylib/gyp/MSVSSettings_test.py index bf6ea6b802..c082bbea9b 100755 --- a/gyp/pylib/gyp/MSVSSettings_test.py +++ b/gyp/pylib/gyp/MSVSSettings_test.py @@ -6,7 +6,11 @@ """Unit tests for the MSVSSettings.py file.""" -import StringIO +try: + from cStringIO import StringIO +except ImportError: + from io import StringIO + import unittest import gyp.MSVSSettings as MSVSSettings @@ -14,7 +18,7 @@ class TestSequenceFunctions(unittest.TestCase): def setUp(self): - self.stderr = StringIO.StringIO() + self.stderr = StringIO() def _ExpectedWarnings(self, expected): """Compares recorded lines to expected warnings.""" diff --git a/gyp/pylib/gyp/common.py b/gyp/pylib/gyp/common.py index 834a8e6c95..071ad7e242 100644 --- a/gyp/pylib/gyp/common.py +++ b/gyp/pylib/gyp/common.py @@ -9,6 +9,9 @@ import re import tempfile import sys +import subprocess + +PY3 = bytes != str # A minimal memoizing decorator. It'll blow up if the args aren't immutable, @@ -337,11 +340,16 @@ def WriteOnDiff(filename): class Writer(object): """Wrapper around file which only covers the target if it differs.""" def __init__(self): + # On Cygwin remove the "dir" argument because `C:` prefixed paths are treated as relative, + # consequently ending up with current dir "/cygdrive/c/..." being prefixed to those, which was + # obviously a non-existent path, for example: "/cygdrive/c//C:\". + # See https://docs.python.org/2/library/tempfile.html#tempfile.mkstemp for more details + base_temp_dir = "" if IsCygwin() else os.path.dirname(filename) # Pick temporary file. tmp_fd, self.tmp_path = tempfile.mkstemp( suffix='.tmp', prefix=os.path.split(filename)[1] + '.gyp.', - dir=os.path.split(filename)[0]) + dir=base_temp_dir) try: self.tmp_file = os.fdopen(tmp_fd, 'wb') except Exception: @@ -394,6 +402,9 @@ def close(self): os.unlink(self.tmp_path) raise + def write(self, s): + self.tmp_file.write(s.encode('utf-8')) + return Writer() @@ -608,3 +619,16 @@ def CrossCompileRequested(): os.environ.get('AR_target') or os.environ.get('CC_target') or os.environ.get('CXX_target')) + +def IsCygwin(): + try: + out = subprocess.Popen("uname", + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + stdout, stderr = out.communicate() + if PY3: + stdout = stdout.decode("utf-8") + return "CYGWIN" in str(stdout) + except Exception: + return False + diff --git a/gyp/pylib/gyp/common_test.py b/gyp/pylib/gyp/common_test.py index ad6f9a1438..b75bbb8412 100755 --- a/gyp/pylib/gyp/common_test.py +++ b/gyp/pylib/gyp/common_test.py @@ -59,10 +59,10 @@ def test_platform_default(self): self.assertFlavor('freebsd', 'freebsd9' , {}) self.assertFlavor('freebsd', 'freebsd10', {}) self.assertFlavor('openbsd', 'openbsd5' , {}) - self.assertFlavor('solaris', 'sunos5' , {}); - self.assertFlavor('solaris', 'sunos' , {}); - self.assertFlavor('linux' , 'linux2' , {}); - self.assertFlavor('linux' , 'linux3' , {}); + self.assertFlavor('solaris', 'sunos5' , {}) + self.assertFlavor('solaris', 'sunos' , {}) + self.assertFlavor('linux' , 'linux2' , {}) + self.assertFlavor('linux' , 'linux3' , {}) def test_param(self): self.assertFlavor('foobar', 'linux2' , {'flavor': 'foobar'}) diff --git a/gyp/pylib/gyp/easy_xml.py b/gyp/pylib/gyp/easy_xml.py index 7c3f621f1f..1ddd909175 100644 --- a/gyp/pylib/gyp/easy_xml.py +++ b/gyp/pylib/gyp/easy_xml.py @@ -120,7 +120,7 @@ def WriteXmlIfChanged(content, path, encoding='utf-8', pretty=False, default_encoding = locale.getdefaultlocale()[1] if default_encoding.upper() != encoding.upper(): - xml_string = xml_string.decode(default_encoding).encode(encoding) + xml_string = xml_string.encode(encoding) # Get the old content try: @@ -132,7 +132,7 @@ def WriteXmlIfChanged(content, path, encoding='utf-8', pretty=False, # It has changed, write it if existing != xml_string: - f = open(path, 'w') + f = open(path, 'wb') f.write(xml_string) f.close() diff --git a/gyp/pylib/gyp/easy_xml_test.py b/gyp/pylib/gyp/easy_xml_test.py index df64354982..2a80b8a456 100755 --- a/gyp/pylib/gyp/easy_xml_test.py +++ b/gyp/pylib/gyp/easy_xml_test.py @@ -8,13 +8,16 @@ import gyp.easy_xml as easy_xml import unittest -import StringIO +try: + from cStringIO import StringIO +except ImportError: + from io import StringIO class TestSequenceFunctions(unittest.TestCase): def setUp(self): - self.stderr = StringIO.StringIO() + self.stderr = StringIO() def test_EasyXml_simple(self): self.assertEqual( diff --git a/gyp/pylib/gyp/generator/analyzer.py b/gyp/pylib/gyp/generator/analyzer.py index dc17c96524..59d73dbedb 100644 --- a/gyp/pylib/gyp/generator/analyzer.py +++ b/gyp/pylib/gyp/generator/analyzer.py @@ -615,7 +615,7 @@ def _supplied_target_names(self): def _supplied_target_names_no_all(self): """Returns the supplied test targets without 'all'.""" - result = self._supplied_target_names(); + result = self._supplied_target_names() result.discard('all') return result @@ -668,10 +668,10 @@ def find_matching_test_target_names(self): def find_matching_compile_target_names(self): """Returns the set of output compile targets.""" - assert self.is_build_impacted(); + assert self.is_build_impacted() # Compile targets are found by searching up from changed targets. # Reset the visited status for _GetBuildTargets. - for target in self._name_to_target.itervalues(): + for target in self._name_to_target.values(): target.visited = False supplied_targets = _LookupTargets(self._supplied_target_names_no_all(), diff --git a/gyp/pylib/gyp/generator/android.py b/gyp/pylib/gyp/generator/android.py index b7f9842888..cecb28c366 100644 --- a/gyp/pylib/gyp/generator/android.py +++ b/gyp/pylib/gyp/generator/android.py @@ -550,7 +550,7 @@ def WriteSources(self, spec, configs, extra_sources): # to work properly. If the file has the wrong C++ extension, then we add # a rule to copy that to intermediates and use the new version. final_generated_sources = [] - # If a source file gets copied, we still need to add the orginal source + # If a source file gets copied, we still need to add the original source # directory as header search path, for GCC searches headers in the # directory that contains the source file by default. origin_src_dirs = [] diff --git a/gyp/pylib/gyp/generator/cmake.py b/gyp/pylib/gyp/generator/cmake.py index 7aabddb633..996b6f25fd 100644 --- a/gyp/pylib/gyp/generator/cmake.py +++ b/gyp/pylib/gyp/generator/cmake.py @@ -574,7 +574,7 @@ class CMakeNamer(object): """Converts Gyp target names into CMake target names. CMake requires that target names be globally unique. One way to ensure - this is to fully qualify the names of the targets. Unfortunatly, this + this is to fully qualify the names of the targets. Unfortunately, this ends up with all targets looking like "chrome_chrome_gyp_chrome" instead of just "chrome". If this generator were only interested in building, it would be possible to fully qualify all target names, then create @@ -681,7 +681,7 @@ def WriteTarget(namer, qualified_target, target_dicts, build_dir, config_to_use, for src in srcs: _, ext = os.path.splitext(src) src_type = COMPILABLE_EXTENSIONS.get(ext, None) - src_norm_path = NormjoinPath(path_from_cmakelists_to_gyp, src); + src_norm_path = NormjoinPath(path_from_cmakelists_to_gyp, src) if src_type == 's': s_sources.append(src_norm_path) diff --git a/gyp/pylib/gyp/generator/eclipse.py b/gyp/pylib/gyp/generator/eclipse.py index b7c6aa951f..6b49ad6760 100644 --- a/gyp/pylib/gyp/generator/eclipse.py +++ b/gyp/pylib/gyp/generator/eclipse.py @@ -195,7 +195,7 @@ def GetAllDefines(target_list, target_dicts, data, config_name, params, """Calculate the defines for a project. Returns: - A dict that includes explict defines declared in gyp files along with all of + A dict that includes explicit defines declared in gyp files along with all of the default defines that the compiler uses. """ @@ -272,7 +272,7 @@ def WriteMacros(out, eclipse_langs, defines): out.write(' \n') for lang in eclipse_langs: out.write(' \n' % lang) - for key in sorted(defines.iterkeys()): + for key in sorted(defines): out.write(' %s%s\n' % (escape(key), escape(defines[key]))) out.write(' \n') diff --git a/gyp/pylib/gyp/generator/make.py b/gyp/pylib/gyp/generator/make.py index 37ac255bfa..bdf7134537 100644 --- a/gyp/pylib/gyp/generator/make.py +++ b/gyp/pylib/gyp/generator/make.py @@ -12,7 +12,7 @@ # all are sourced by the top-level Makefile. This means that all # variables in .mk-files clobber one another. Be careful to use := # where appropriate for immediate evaluation, and similarly to watch -# that you're not relying on a variable value to last beween different +# that you're not relying on a variable value to last between different # .mk files. # # TODOs: @@ -821,7 +821,7 @@ def Write(self, qualified_target, base_path, output_filename, spec, configs, gyp.xcode_emulation.MacPrefixHeader( self.xcode_settings, lambda p: Sourceify(self.Absolutify(p)), self.Pchify)) - sources = filter(Compilable, all_sources) + sources = list(filter(Compilable, all_sources)) if sources: self.WriteLn(SHARED_HEADER_SUFFIX_RULES_COMMENT1) extensions = set([os.path.splitext(s)[1] for s in sources]) @@ -950,7 +950,7 @@ def WriteActions(self, actions, extra_sources, extra_outputs, '%s%s' % (name, cd_action, command)) self.WriteLn() - outputs = map(self.Absolutify, outputs) + outputs = [self.Absolutify(output) for output in outputs] # The makefile rules are all relative to the top dir, but the gyp actions # are defined relative to their containing dir. This replaces the obj # variable for the action rule with an absolute version so that the output @@ -974,7 +974,7 @@ def WriteActions(self, actions, extra_sources, extra_outputs, outputs = [gyp.xcode_emulation.ExpandEnvVars(o, env) for o in outputs] inputs = [gyp.xcode_emulation.ExpandEnvVars(i, env) for i in inputs] - self.WriteDoCmd(outputs, map(Sourceify, map(self.Absolutify, inputs)), + self.WriteDoCmd(outputs, [Sourceify(self.Absolutify(i)) for i in inputs], part_of_all=part_of_all, command=name) # Stuff the outputs in a variable so we can refer to them later. @@ -1023,8 +1023,8 @@ def WriteRules(self, rules, extra_sources, extra_outputs, extra_sources += outputs if int(rule.get('process_outputs_as_mac_bundle_resources', False)): extra_mac_bundle_resources += outputs - inputs = map(Sourceify, map(self.Absolutify, [rule_source] + - rule.get('inputs', []))) + inputs = [Sourceify(self.Absolutify(i)) for i + in [rule_source] + rule.get('inputs', [])] actions = ['$(call do_cmd,%s_%d)' % (name, count)] if name == 'resources_grit': @@ -1040,7 +1040,7 @@ def WriteRules(self, rules, extra_sources, extra_outputs, outputs = [gyp.xcode_emulation.ExpandEnvVars(o, env) for o in outputs] inputs = [gyp.xcode_emulation.ExpandEnvVars(i, env) for i in inputs] - outputs = map(self.Absolutify, outputs) + outputs = [self.Absolutify(output) for output in outputs] all_outputs += outputs # Only write the 'obj' and 'builddir' rules for the "primary" output # (:1); it's superfluous for the "extra outputs", and this avoids @@ -1147,7 +1147,7 @@ def WriteCopies(self, copies, extra_outputs, part_of_all): path = gyp.xcode_emulation.ExpandEnvVars(path, env) self.WriteDoCmd([output], [path], 'copy', part_of_all) outputs.append(output) - self.WriteLn('%s = %s' % (variable, ' '.join(map(QuoteSpaces, outputs)))) + self.WriteLn('%s = %s' % (variable, ' '.join(QuoteSpaces(o) for o in outputs))) extra_outputs.append('$(%s)' % variable) self.WriteLn() @@ -1158,7 +1158,7 @@ def WriteMacBundleResources(self, resources, bundle_deps): for output, res in gyp.xcode_emulation.GetMacBundleResources( generator_default_variables['PRODUCT_DIR'], self.xcode_settings, - map(Sourceify, map(self.Absolutify, resources))): + [Sourceify(self.Absolutify(r)) for r in resources]): _, ext = os.path.splitext(output) if ext != '.xcassets': # Make does not supports '.xcassets' emulation. @@ -1225,24 +1225,24 @@ def WriteSources(self, configs, deps, sources, cflags_c = config.get('cflags_c') cflags_cc = config.get('cflags_cc') - self.WriteLn("# Flags passed to all source files."); + self.WriteLn("# Flags passed to all source files.") self.WriteList(cflags, 'CFLAGS_%s' % configname) - self.WriteLn("# Flags passed to only C files."); + self.WriteLn("# Flags passed to only C files.") self.WriteList(cflags_c, 'CFLAGS_C_%s' % configname) - self.WriteLn("# Flags passed to only C++ files."); + self.WriteLn("# Flags passed to only C++ files.") self.WriteList(cflags_cc, 'CFLAGS_CC_%s' % configname) if self.flavor == 'mac': - self.WriteLn("# Flags passed to only ObjC files."); + self.WriteLn("# Flags passed to only ObjC files.") self.WriteList(cflags_objc, 'CFLAGS_OBJC_%s' % configname) - self.WriteLn("# Flags passed to only ObjC++ files."); + self.WriteLn("# Flags passed to only ObjC++ files.") self.WriteList(cflags_objcc, 'CFLAGS_OBJCC_%s' % configname) includes = config.get('include_dirs') if includes: - includes = map(Sourceify, map(self.Absolutify, includes)) + includes = [Sourceify(self.Absolutify(i)) for i in includes] self.WriteList(includes, 'INCS_%s' % configname, prefix='-I') - compilable = filter(Compilable, sources) - objs = map(self.Objectify, map(self.Absolutify, map(Target, compilable))) + compilable = list(filter(Compilable, sources)) + objs = [self.Objectify(self.Absolutify(Target(c))) for c in compilable] self.WriteList(objs, 'OBJS') for obj in objs: @@ -1314,7 +1314,7 @@ def WriteSources(self, configs, deps, sources, # If there are any object files in our input file list, link them into our # output. - extra_link_deps += filter(Linkable, sources) + extra_link_deps += list(filter(Linkable, sources)) self.WriteLn() @@ -1564,7 +1564,7 @@ def WriteTarget(self, spec, configs, deps, link_deps, bundle_deps, # Bundle dependencies. Note that the code below adds actions to this # target, so if you move these two lines, move the lines below as well. - self.WriteList(map(QuoteSpaces, bundle_deps), 'BUNDLE_DEPS') + self.WriteList([QuoteSpaces(dep) for dep in bundle_deps], 'BUNDLE_DEPS') self.WriteLn('%s: $(BUNDLE_DEPS)' % QuoteSpaces(self.output)) # After the framework is built, package it. Needs to happen before @@ -1598,7 +1598,7 @@ def WriteTarget(self, spec, configs, deps, link_deps, bundle_deps, if self.type == 'executable': self.WriteLn('%s: LD_INPUTS := %s' % ( QuoteSpaces(self.output_binary), - ' '.join(map(QuoteSpaces, link_deps)))) + ' '.join(QuoteSpaces(dep) for dep in link_deps))) if self.toolset == 'host' and self.flavor == 'android': self.WriteDoCmd([self.output_binary], link_deps, 'link_host', part_of_all, postbuilds=postbuilds) @@ -1620,7 +1620,7 @@ def WriteTarget(self, spec, configs, deps, link_deps, bundle_deps, elif self.type == 'shared_library': self.WriteLn('%s: LD_INPUTS := %s' % ( QuoteSpaces(self.output_binary), - ' '.join(map(QuoteSpaces, link_deps)))) + ' '.join(QuoteSpaces(dep) for dep in link_deps))) self.WriteDoCmd([self.output_binary], link_deps, 'solink', part_of_all, postbuilds=postbuilds) elif self.type == 'loadable_module': @@ -1746,8 +1746,8 @@ def WriteMakeRule(self, outputs, inputs, actions=None, comment=None, output is just a name to run the rule command: (optional) command name to generate unambiguous labels """ - outputs = map(QuoteSpaces, outputs) - inputs = map(QuoteSpaces, inputs) + outputs = [QuoteSpaces(o) for o in outputs] + inputs = [QuoteSpaces(i) for i in inputs] if comment: self.WriteLn('# ' + comment) @@ -1779,7 +1779,7 @@ def WriteMakeRule(self, outputs, inputs, actions=None, comment=None, cmddigest = hashlib.sha1(command if command else self.target).hexdigest() intermediate = "%s.intermediate" % cmddigest self.WriteLn('%s: %s' % (' '.join(outputs), intermediate)) - self.WriteLn('\t%s' % '@:'); + self.WriteLn('\t%s' % '@:') self.WriteLn('%s: %s' % ('.INTERMEDIATE', intermediate)) self.WriteLn('%s: %s%s' % (intermediate, ' '.join(inputs), force_append)) @@ -1836,7 +1836,7 @@ def WriteAndroidNdkModuleRule(self, module_name, all_sources, link_deps): default_cpp_ext = ext self.WriteLn('LOCAL_CPP_EXTENSION := ' + default_cpp_ext) - self.WriteList(map(self.Absolutify, filter(Compilable, all_sources)), + self.WriteList(list(map(self.Absolutify, filter(Compilable, all_sources))), 'LOCAL_SRC_FILES') # Filter out those which do not match prefix and suffix and produce @@ -1979,7 +1979,7 @@ def WriteAutoRegenerationRule(params, root_makefile, makefile_name, "%(makefile_name)s: %(deps)s\n" "\t$(call do_cmd,regen_makefile)\n\n" % { 'makefile_name': makefile_name, - 'deps': ' '.join(map(SourceifyAndQuoteSpaces, build_files)), + 'deps': ' '.join(SourceifyAndQuoteSpaces(bf) for bf in build_files), 'cmd': gyp.common.EncodePOSIXShellList( [gyp_binary, '-fmake'] + gyp.RegenerateFlags(options) + diff --git a/gyp/pylib/gyp/generator/msvs.py b/gyp/pylib/gyp/generator/msvs.py index aacbe60836..b3b4bc1053 100644 --- a/gyp/pylib/gyp/generator/msvs.py +++ b/gyp/pylib/gyp/generator/msvs.py @@ -165,7 +165,7 @@ def _FixPath(path): Returns: The path with all slashes made into backslashes. """ - if fixpath_prefix and path and not os.path.isabs(path) and not path[0] == '$': + if fixpath_prefix and path and not os.path.isabs(path) and not path[0] == '$' and not _IsWindowsAbsPath(path): path = os.path.join(fixpath_prefix, path) path = path.replace('/', '\\') path = _NormalizedSource(path) @@ -174,6 +174,16 @@ def _FixPath(path): return path +def _IsWindowsAbsPath(path): + """ + On Cygwin systems Python needs a little help determining if a path is an absolute Windows path or not, so that + it does not treat those as relative, which results in bad paths like: + + '..\C:\\some_source_code_file.cc' + """ + return path.startswith('c:') or path.startswith('C:') + + def _FixPaths(paths): """Fix each of the paths of the list.""" return [_FixPath(i) for i in paths] @@ -1753,8 +1763,8 @@ def _CollapseSingles(parent, node): # such projects up one level. if (type(node) == dict and len(node) == 1 and - node.keys()[0] == parent + '.vcproj'): - return node[node.keys()[0]] + list(node)[0] == parent + '.vcproj'): + return node[list(node)[0]] if type(node) != dict: return node for child in node: @@ -1773,8 +1783,8 @@ def _GatherSolutionFolders(sln_projects, project_objects, flat): # Walk down from the top until we hit a folder that has more than one entry. # In practice, this strips the top-level "src/" dir from the hierarchy in # the solution. - while len(root) == 1 and type(root[root.keys()[0]]) == dict: - root = root[root.keys()[0]] + while len(root) == 1 and type(root[list(root)[0]]) == dict: + root = root[list(root)[0]] # Collapse singles. root = _CollapseSingles('', root) # Merge buckets until everything is a root entry. @@ -2691,7 +2701,7 @@ def _GetMSBuildGlobalProperties(spec, guid, gyp_file_name): platform_name = None msvs_windows_target_platform_version = None - for configuration in spec['configurations'].itervalues(): + for configuration in spec['configurations'].values(): platform_name = platform_name or _ConfigPlatform(configuration) msvs_windows_target_platform_version = \ msvs_windows_target_platform_version or \ @@ -3059,7 +3069,7 @@ def _FinalizeMSBuildSettings(spec, configuration): _ToolAppend(msbuild_settings, 'ResourceCompile', 'AdditionalIncludeDirectories', resource_include_dirs) # Add in libraries, note that even for empty libraries, we want this - # set, to prevent inheriting default libraries from the enviroment. + # set, to prevent inheriting default libraries from the environment. _ToolSetOrAppend(msbuild_settings, 'Link', 'AdditionalDependencies', libraries) _ToolAppend(msbuild_settings, 'Link', 'AdditionalLibraryDirectories', @@ -3252,7 +3262,7 @@ def _GetMSBuildProjectReferences(project): ['Project', guid], ['ReferenceOutputAssembly', 'false'] ] - for config in dependency.spec.get('configurations', {}).itervalues(): + for config in dependency.spec.get('configurations', {}).values(): if config.get('msvs_use_library_dependency_inputs', 0): project_ref.append(['UseLibraryDependencyInputs', 'true']) break @@ -3321,7 +3331,7 @@ def _GenerateMSBuildProject(project, options, version, generator_flags): extension_to_rule_name, _GetUniquePlatforms(spec)) missing_sources = _VerifySourcesExist(sources, project_dir) - for configuration in configurations.itervalues(): + for configuration in configurations.values(): _FinalizeMSBuildSettings(spec, configuration) # Add attributes to root element diff --git a/gyp/pylib/gyp/generator/msvs_test.py b/gyp/pylib/gyp/generator/msvs_test.py index c0b021df50..daf4f411bc 100755 --- a/gyp/pylib/gyp/generator/msvs_test.py +++ b/gyp/pylib/gyp/generator/msvs_test.py @@ -7,13 +7,16 @@ import gyp.generator.msvs as msvs import unittest -import StringIO +try: + from cStringIO import StringIO +except ImportError: + from io import StringIO class TestSequenceFunctions(unittest.TestCase): def setUp(self): - self.stderr = StringIO.StringIO() + self.stderr = StringIO() def test_GetLibraries(self): self.assertEqual( diff --git a/gyp/pylib/gyp/generator/ninja.py b/gyp/pylib/gyp/generator/ninja.py index aae5b71310..33cc253aba 100644 --- a/gyp/pylib/gyp/generator/ninja.py +++ b/gyp/pylib/gyp/generator/ninja.py @@ -19,7 +19,10 @@ import gyp.msvs_emulation import gyp.MSVSUtil as MSVSUtil import gyp.xcode_emulation -from cStringIO import StringIO +try: + from cStringIO import StringIO +except ImportError: + from io import StringIO from gyp.common import GetEnvironFallback import gyp.ninja_syntax as ninja_syntax @@ -723,7 +726,7 @@ def cygwin_munge(path): elif var == 'name': extra_bindings.append(('name', cygwin_munge(basename))) else: - assert var == None, repr(var) + assert var is None, repr(var) outputs = [self.GypPathToNinja(o, env) for o in outputs] if self.flavor == 'win': @@ -1818,7 +1821,7 @@ def GenerateOutputForConfig(target_list, target_dicts, data, params, # - The priority from low to high is gcc/g++, the 'make_global_settings' in # gyp, the environment variable. # - If there is no 'make_global_settings' for CC.host/CXX.host or - # 'CC_host'/'CXX_host' enviroment variable, cc_host/cxx_host should be set + # 'CC_host'/'CXX_host' environment variable, cc_host/cxx_host should be set # to cc/cxx. if flavor == 'win': ar = 'lib.exe' diff --git a/gyp/pylib/gyp/generator/ninja_test.py b/gyp/pylib/gyp/generator/ninja_test.py index 1767b2f45a..1ad68e4fc9 100644 --- a/gyp/pylib/gyp/generator/ninja_test.py +++ b/gyp/pylib/gyp/generator/ninja_test.py @@ -8,7 +8,6 @@ import gyp.generator.ninja as ninja import unittest -import StringIO import sys import TestCommon diff --git a/gyp/pylib/gyp/generator/xcode.py b/gyp/pylib/gyp/generator/xcode.py index 694a28afb1..6317d04c70 100644 --- a/gyp/pylib/gyp/generator/xcode.py +++ b/gyp/pylib/gyp/generator/xcode.py @@ -246,7 +246,7 @@ def Finalize1(self, xcode_targets, serialize_all_tests): targets_for_all.append(xcode_target) if target_name.lower() == 'all': - has_custom_all = True; + has_custom_all = True # If this target has a 'run_as' attribute, add its target to the # targets, and add it to the test targets. @@ -539,7 +539,7 @@ def ExpandXcodeVariables(string, expansions): """ matches = _xcode_variable_re.findall(string) - if matches == None: + if matches is None: return string matches.reverse() @@ -637,7 +637,7 @@ def GenerateOutput(target_list, target_dicts, data, params): pbxp = xcp.project # Set project-level attributes from multiple options - project_attributes = {}; + project_attributes = {} if parallel_builds: project_attributes['BuildIndependentTargetsInParallel'] = 'YES' if upgrade_check_project_version: @@ -776,7 +776,7 @@ def GenerateOutput(target_list, target_dicts, data, params): # logic all happens in ninja. Don't bother creating the extra targets in # that case. if type != 'none' and (spec_actions or spec_rules) and not ninja_wrapper: - support_xccl = CreateXCConfigurationList(configuration_names); + support_xccl = CreateXCConfigurationList(configuration_names) support_target_suffix = generator_flags.get( 'support_target_suffix', ' Support') support_target_properties = { @@ -998,7 +998,7 @@ def GenerateOutput(target_list, target_dicts, data, params): actions.append(action) if len(concrete_outputs_all) > 0: - # TODO(mark): There's a possibilty for collision here. Consider + # TODO(mark): There's a possibility for collision here. Consider # target "t" rule "A_r" and target "t_A" rule "r". makefile_name = '%s.make' % re.sub( '[^a-zA-Z0-9_]', '_' , '%s_%s' % (target_name, rule['rule_name'])) @@ -1171,7 +1171,7 @@ def GenerateOutput(target_list, target_dicts, data, params): dest = '$(SRCROOT)/' + dest code_sign = int(copy_group.get('xcode_code_sign', 0)) - settings = (None, '{ATTRIBUTES = (CodeSignOnCopy, ); }')[code_sign]; + settings = (None, '{ATTRIBUTES = (CodeSignOnCopy, ); }')[code_sign] # Coalesce multiple "copies" sections in the same target with the same # "destination" property into the same PBXCopyFilesBuildPhase, otherwise diff --git a/gyp/pylib/gyp/input.py b/gyp/pylib/gyp/input.py index eb9858f0c8..aba81cf654 100644 --- a/gyp/pylib/gyp/input.py +++ b/gyp/pylib/gyp/input.py @@ -4,14 +4,8 @@ from __future__ import print_function -from compiler.ast import Const -from compiler.ast import Dict -from compiler.ast import Discard -from compiler.ast import List -from compiler.ast import Module -from compiler.ast import Node -from compiler.ast import Stmt -import compiler +import ast + import gyp.common import gyp.simple_copy import multiprocessing @@ -161,7 +155,7 @@ def GetIncludedBuildFiles(build_file_path, aux_data, included=None): in the list will be relative to the current directory. """ - if included == None: + if included is None: included = [] if build_file_path in included: @@ -184,43 +178,39 @@ def CheckedEval(file_contents): Note that this is slower than eval() is. """ - ast = compiler.parse(file_contents) - assert isinstance(ast, Module) - c1 = ast.getChildren() - assert c1[0] is None - assert isinstance(c1[1], Stmt) - c2 = c1[1].getChildren() - assert isinstance(c2[0], Discard) - c3 = c2[0].getChildren() - assert len(c3) == 1 - return CheckNode(c3[0], []) + syntax_tree = ast.parse(file_contents) + assert isinstance(syntax_tree, ast.Module) + c1 = syntax_tree.body + assert len(c1) == 1 + c2 = c1[0] + assert isinstance(c2, ast.Expr) + return CheckNode(c2.value, []) def CheckNode(node, keypath): - if isinstance(node, Dict): + if isinstance(node, ast.Dict): c = node.getChildren() dict = {} - for n in range(0, len(c), 2): - assert isinstance(c[n], Const) - key = c[n].getChildren()[0] + for key, value in zip(node.keys, node.values): + assert isinstance(key, ast.Str) + key = key.s if key in dict: raise GypError("Key '" + key + "' repeated at level " + repr(len(keypath) + 1) + " with key path '" + '.'.join(keypath) + "'") kp = list(keypath) # Make a copy of the list for descending this node. kp.append(key) - dict[key] = CheckNode(c[n + 1], kp) + dict[key] = CheckNode(value, kp) return dict - elif isinstance(node, List): - c = node.getChildren() + elif isinstance(node, ast.List): children = [] - for index, child in enumerate(c): + for index, child in enumerate(node.elts): kp = list(keypath) # Copy list. kp.append(repr(index)) children.append(CheckNode(child, kp)) return children - elif isinstance(node, Const): - return node.getChildren()[0] + elif isinstance(node, ast.Str): + return node.s else: raise TypeError("Unknown AST node at key path '" + '.'.join(keypath) + "': " + repr(node)) @@ -954,8 +944,12 @@ def ExpandVariables(input, phase, variables, build_file): else: replacement = variables[contents] + if isinstance(replacement, bytes) and not isinstance(replacement, str): + replacement = replacement.decode("utf-8") # done on Python 3 only if type(replacement) is list: for item in replacement: + if isinstance(item, bytes) and not isinstance(item, str): + item = item.decode("utf-8") # done on Python 3 only if not contents[-1] == '/' and type(item) not in (str, int): raise GypError('Variable ' + contents + ' must expand to a string or list of strings; ' + @@ -1068,7 +1062,7 @@ def EvalCondition(condition, conditions_key, phase, variables, build_file): else: false_dict = None i = i + 2 - if result == None: + if result is None: result = EvalSingleCondition( cond_expr, true_dict, false_dict, phase, variables, build_file) @@ -1079,7 +1073,7 @@ def EvalSingleCondition( cond_expr, true_dict, false_dict, phase, variables, build_file): """Returns true_dict if cond_expr evaluates to true, and false_dict otherwise.""" - # Do expansions on the condition itself. Since the conditon can naturally + # Do expansions on the condition itself. Since the condition can naturally # contain variable references without needing to resort to GYP expansion # syntax, this is of dubious value for variables, but someone might want to # use a command expansion directly inside a condition. @@ -1184,7 +1178,7 @@ def LoadVariablesFromVariablesDict(variables, the_dict, the_dict_key): continue if the_dict_key == 'variables' and variable_name in the_dict: # If the variable is set without a % in the_dict, and the_dict is a - # variables dict (making |variables| a varaibles sub-dict of a + # variables dict (making |variables| a variables sub-dict of a # variables dict), use the_dict's definition. value = the_dict[variable_name] else: @@ -1609,7 +1603,7 @@ def Visit(node, path): def DirectDependencies(self, dependencies=None): """Returns a list of just direct dependencies.""" - if dependencies == None: + if dependencies is None: dependencies = [] for dependency in self.dependencies: @@ -1637,7 +1631,7 @@ def _AddImportedDependencies(self, targets, dependencies=None): public entry point. """ - if dependencies == None: + if dependencies is None: dependencies = [] index = 0 @@ -1847,7 +1841,7 @@ def VerifyNoGYPFileCircularDependencies(targets): # Create a DependencyGraphNode for each gyp file containing a target. Put # it into a dict for easy access. dependency_nodes = {} - for target in targets.iterkeys(): + for target in targets: build_file = gyp.common.BuildFile(target) if not build_file in dependency_nodes: dependency_nodes[build_file] = DependencyGraphNode(build_file) @@ -1870,7 +1864,7 @@ def VerifyNoGYPFileCircularDependencies(targets): continue dependency_node = dependency_nodes.get(dependency_build_file) if not dependency_node: - raise GypError("Dependancy '%s' not found" % dependency_build_file) + raise GypError("Dependency '%s' not found" % dependency_build_file) if dependency_node not in build_file_node.dependencies: build_file_node.dependencies.append(dependency_node) dependency_node.dependents.append(build_file_node) @@ -1878,7 +1872,7 @@ def VerifyNoGYPFileCircularDependencies(targets): # Files that have no dependencies are treated as dependent on root_node. root_node = DependencyGraphNode(None) - for build_file_node in dependency_nodes.itervalues(): + for build_file_node in dependency_nodes.values(): if len(build_file_node.dependencies) == 0: build_file_node.dependencies.append(root_node) root_node.dependents.append(build_file_node) diff --git a/gyp/pylib/gyp/msvs_emulation.py b/gyp/pylib/gyp/msvs_emulation.py index 4a50b1b74c..9d50bad1f5 100644 --- a/gyp/pylib/gyp/msvs_emulation.py +++ b/gyp/pylib/gyp/msvs_emulation.py @@ -375,7 +375,7 @@ def GetCompilerPdbName(self, config, expand_special): return pdbname def GetMapFileName(self, config, expand_special): - """Gets the explicitly overriden map file name for a target or returns None + """Gets the explicitly overridden map file name for a target or returns None if it's not set.""" config = self._TargetConfig(config) map_file = self._Setting(('VCLinkerTool', 'MapFileName'), config) diff --git a/gyp/pylib/gyp/xcode_emulation.py b/gyp/pylib/gyp/xcode_emulation.py index 6ae41e293a..70f41e6bb4 100644 --- a/gyp/pylib/gyp/xcode_emulation.py +++ b/gyp/pylib/gyp/xcode_emulation.py @@ -20,6 +20,8 @@ import tempfile from gyp.common import GypError +PY3 = bytes != str + # Populated lazily by XcodeVersion, for efficiency, and to fix an issue when # "xcodebuild" is called too quickly (it has been found to return incorrect # version number). @@ -778,7 +780,7 @@ def GetLdflags(self, configname, product_dir, gyp_to_build_path, arch=None): product_dir: The directory where products such static and dynamic libraries are placed. This is added to the library search path. gyp_to_build_path: A function that converts paths relative to the - current gyp file to paths relative to the build direcotry. + current gyp file to paths relative to the build directory. """ self.configname = configname ldflags = [] @@ -923,7 +925,7 @@ def GetPerTargetSetting(self, setting, default=None): def _GetStripPostbuilds(self, configname, output_binary, quiet): """Returns a list of shell commands that contain the shell commands - neccessary to strip this target's binary. These should be run as postbuilds + necessary to strip this target's binary. These should be run as postbuilds before the actual postbuilds run.""" self.configname = configname @@ -957,7 +959,7 @@ def _GetStripPostbuilds(self, configname, output_binary, quiet): def _GetDebugInfoPostbuilds(self, configname, output, output_binary, quiet): """Returns a list of shell commands that contain the shell commands - neccessary to massage this target's debug information. These should be run + necessary to massage this target's debug information. These should be run as postbuilds before the actual postbuilds run.""" self.configname = configname @@ -1052,7 +1054,7 @@ def _AdjustLibrary(self, library, config_name=None): # "/usr/lib" libraries, is do "-L/usr/lib -lname" which is dependent on the # library order and cause collision when building Chrome. # - # Instead substitude ".tbd" to ".dylib" in the generated project when the + # Instead substitute ".tbd" to ".dylib" in the generated project when the # following conditions are both true: # - library is referenced in the gyp file as "$(SDKROOT)/**/*.dylib", # - the ".dylib" file does not exists but a ".tbd" file do. @@ -1277,16 +1279,16 @@ def XcodeVersion(): except: version = CLTVersion() if version: - version = re.match(r'(\d+\.\d+\.?\d*)', version).groups()[0] + version = ".".join(version.split(".")[:3]) else: raise GypError("No Xcode or CLT version detected!") # The CLT has no build information, so we return an empty string. version_list = [version, ''] version = version_list[0] build = version_list[-1] - # Be careful to convert "4.2" to "0420": - version = version.split()[-1].replace('.', '') - version = (version + '0' * (3 - len(version))).zfill(4) + # Be careful to convert "4.2" to "0420" and "10.0" to "1000": + version = format(''.join((version.split()[-1].split('.') + ['0', '0'])[:3]), + '>04s') if build: build = build.split()[-1] XCODE_VERSION_CACHE = (version, build) @@ -1322,6 +1324,8 @@ def GetStdoutQuiet(cmdlist): Raises |GypError| if the command return with a non-zero return code.""" job = subprocess.Popen(cmdlist, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out = job.communicate()[0] + if PY3: + out = out.decode("utf-8") if job.returncode != 0: raise GypError('Error %d running %s' % (job.returncode, cmdlist[0])) return out.rstrip('\n') @@ -1332,6 +1336,8 @@ def GetStdout(cmdlist): Raises |GypError| if the command return with a non-zero return code.""" job = subprocess.Popen(cmdlist, stdout=subprocess.PIPE) out = job.communicate()[0] + if PY3: + out = out.decode("utf-8") if job.returncode != 0: sys.stderr.write(out + '\n') raise GypError('Error %d running %s' % (job.returncode, cmdlist[0])) @@ -1341,7 +1347,7 @@ def GetStdout(cmdlist): def MergeGlobalXcodeSettingsToSpec(global_dict, spec): """Merges the global xcode_settings dictionary into each configuration of the target represented by spec. For keys that are both in the global and the local - xcode_settings dict, the local key gets precendence. + xcode_settings dict, the local key gets precedence. """ # The xcode generator special-cases global xcode_settings and does something # that amounts to merging in the global xcode_settings into each local @@ -1384,7 +1390,7 @@ def GetMacBundleResources(product_dir, xcode_settings, resources): output = dest # The make generator doesn't support it, so forbid it everywhere - # to keep the generators more interchangable. + # to keep the generators more interchangeable. assert ' ' not in res, ( "Spaces in resource filenames not supported (%s)" % res) @@ -1426,14 +1432,14 @@ def GetMacInfoPlist(product_dir, xcode_settings, gyp_path_to_build_path): relative to the build directory. xcode_settings: The XcodeSettings of the current target. gyp_to_build_path: A function that converts paths relative to the - current gyp file to paths relative to the build direcotry. + current gyp file to paths relative to the build directory. """ info_plist = xcode_settings.GetPerTargetSetting('INFOPLIST_FILE') if not info_plist: return None, None, [], {} # The make generator doesn't support it, so forbid it everywhere - # to keep the generators more interchangable. + # to keep the generators more interchangeable. assert ' ' not in info_plist, ( "Spaces in Info.plist filenames not supported (%s)" % info_plist) @@ -1636,7 +1642,7 @@ def _HasIOSTarget(targets): def _AddIOSDeviceConfigurations(targets): """Clone all targets and append -iphoneos to the name. Configure these targets to build for iOS devices and use correct architectures for those builds.""" - for target_dict in targets.itervalues(): + for target_dict in targets.values(): toolset = target_dict['toolset'] configs = target_dict['configurations'] for config_name, config_dict in dict(configs).items(): diff --git a/gyp/pylib/gyp/xcode_ninja.py b/gyp/pylib/gyp/xcode_ninja.py index 5acd82e004..d70eddc90a 100644 --- a/gyp/pylib/gyp/xcode_ninja.py +++ b/gyp/pylib/gyp/xcode_ninja.py @@ -85,7 +85,7 @@ def _TargetFromSpec(old_spec, params): "%s/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)" % ninja_toplevel if 'configurations' in old_spec: - for config in old_spec['configurations'].iterkeys(): + for config in old_spec['configurations']: old_xcode_settings = \ old_spec['configurations'][config].get('xcode_settings', {}) if 'IPHONEOS_DEPLOYMENT_TARGET' in old_xcode_settings: diff --git a/gyp/pylib/gyp/xcodeproj_file.py b/gyp/pylib/gyp/xcodeproj_file.py index b0385468c5..93ffca7c90 100644 --- a/gyp/pylib/gyp/xcodeproj_file.py +++ b/gyp/pylib/gyp/xcodeproj_file.py @@ -220,7 +220,7 @@ class XCObject(object): an empty string ("", in the case of property_type str) or list ([], in the case of is_list True) from being set for the property. - default: Optional. If is_requried is True, default may be set + default: Optional. If is_required is True, default may be set to provide a default value for objects that do not supply their own value. If is_required is True and default is not provided, users of the class must supply their own diff --git a/gyp/tools/pretty_gyp.py b/gyp/tools/pretty_gyp.py index d01c692edc..633048a59a 100755 --- a/gyp/tools/pretty_gyp.py +++ b/gyp/tools/pretty_gyp.py @@ -18,7 +18,7 @@ # Regex to remove quoted strings when we're counting braces. # It takes into account quoted quotes, and makes sure that the quotes match. # NOTE: It does not handle quotes that span more than one line, or -# cases where an escaped quote is preceeded by an escaped backslash. +# cases where an escaped quote is preceded by an escaped backslash. QUOTE_RE_STR = r'(?P[\'"])(.*?)(? (http://tootallnate.net)", "repository": { @@ -31,7 +31,7 @@ "request": "^2.87.0", "rimraf": "2", "semver": "~5.3.0", - "tar": "^4.4.8", + "tar": "^4.4.12", "which": "1" }, "engines": { diff --git a/src/win_delay_load_hook.cc b/src/win_delay_load_hook.cc index 5e7f14b2b2..169f8029f1 100644 --- a/src/win_delay_load_hook.cc +++ b/src/win_delay_load_hook.cc @@ -9,6 +9,8 @@ #ifdef _MSC_VER +#pragma managed(push, off) + #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif @@ -32,4 +34,6 @@ static FARPROC WINAPI load_exe_hook(unsigned int event, DelayLoadInfo* info) { decltype(__pfnDliNotifyHook2) __pfnDliNotifyHook2 = load_exe_hook; +#pragma managed(pop) + #endif diff --git a/test/test-find-python.js b/test/test-find-python.js index c52a579666..1c86f45b73 100644 --- a/test/test-find-python.js +++ b/test/test-find-python.js @@ -1,13 +1,12 @@ 'use strict' +delete process.env.PYTHON + const test = require('tap').test const findPython = require('../lib/find-python') const execFile = require('child_process').execFile const PythonFinder = findPython.test.PythonFinder -delete process.env.PYTHON -delete process.env.NODE_GYP_FORCE_PYTHON - require('npmlog').level = 'warn' test('find python', function (t) { @@ -17,8 +16,13 @@ test('find python', function (t) { t.strictEqual(err, null) var proc = execFile(found, ['-V'], function (err, stdout, stderr) { t.strictEqual(err, null) - t.strictEqual(stdout, '') - t.ok(/Python 2/.test(stderr)) + if (/Python 2/.test(stderr)) { + t.strictEqual(stdout, '') + t.ok(/Python 2/.test(stderr)) + } else { + t.ok(/Python 3/.test(stdout)) + t.strictEqual(stderr, '') + } }) proc.stdout.setEncoding('utf-8') proc.stderr.setEncoding('utf-8') @@ -51,6 +55,7 @@ TestPythonFinder.prototype.log = { warn: () => {}, error: () => {} } +delete TestPythonFinder.prototype.env.NODE_GYP_FORCE_PYTHON test('find python - python', function (t) { t.plan(6)