gyp: update xml string encoding conversion - #1203

Closed
lc-soft wants to merge 3 commits into
nodejs:masterfrom
lc-soft:fix_xml_encoding_bug
Closed

gyp: update xml string encoding conversion#1203
lc-soft wants to merge 3 commits into
nodejs:masterfrom
lc-soft:fix_xml_encoding_bug

Conversation

@lc-soft

@lc-softlc-soft commented May 20, 2017

Copy link
Copy Markdown
Contributor

My project depends on the node-sass, but it can not successfully install, so I tried using the npm rebuild node-sass --force command to build the node-sass on Windows 10. But it could not be built successfully, error message is: "node_version.h": No such file or directory

I guess this is the problem of compiling configuration, and I found the node-sass\build\binding.vcxproj file from the output information, so I opened it with the editor and found that the configuration item has garbled text:

qq 20170520130717

My username can not be displayed correctly, there seems to be a encoding conversion bug when writing to the binding.vcxproj file. I took some time to debug it, Eventually I found the problem out here: easy_xml.py#L120

qq 20170520130900

Since xml_string contains non-ascii characters, xml_string.encode() will fail and throw an exception, and then this string will be treated as latin-1 encoded string to convert, but my default locale character encoding is not latin-1, therefore, the binding.vcproj file is written with the wrong content.

After modification, the contents of the output file is correct.

qq 20170520130513

node-sass can be built successfully.

gyp info ok
Installed to F:\work\XXXXXX\node_modules\node-sass\vendor\win32-x64-48\binding.node
node-sass@4.5.3 F:\work\XXXXXX\node_modules\node-sass

@gibfahn

Copy link
Copy Markdown
Member

Maybe cc/ @joaocgreis@refack ?

Proposed change seems reasonable, but I don't know enough to review.

@refack

Copy link
Copy Markdown
Contributor

@lc-soft I'll have a look
Since it looks like a bug in GYP you should also open an issue at https://bugs.chromium.org/p/gyp/issues/list or even submit a patch

@refack

Copy link
Copy Markdown
Contributor

P.S. I keep forgetting to say...
Thank you very much for the contribution! 🥇

@lc-soft

lc-soft commented May 20, 2017

Copy link
Copy Markdown
ContributorAuthor

@refack I found these: #366#945#297.
This is old bug. but they did not submit a patch to upstream, this file has not been changed:
https://chromium.googlesource.com/external/gyp.git/+/master/pylib/gyp/easy_xml.py#105

@refack

Copy link
Copy Markdown
Contributor

I found these: #366#945#297, This is old bug. but they did not submit a patch to upstream, this file has not been changed:
https://chromium.googlesource.com/external/gyp.git/+/master/pylib/gyp/easy_xml.py#105

Yeah, for a long time upstream GYP was unresponsive so people didn't bother with submitting patches. They are trying to be better 🤷‍♂️ . Thank you for pointing me to those PRs!

I'm looking at your patch, we might land it here, and then try to push it upstream.

Anyway since AFAIK this is your first contribution, I'll give you some info on our review and landing process.
Ref: https://github.com/nodejs/node/blob/master/CONTRIBUTING.md#step-7-discuss-and-update
We keep the PR open for at least 48-72 hours so that anyone that might have some input to give will have get a chance. We will go over your code change, maybe ask a few question or request some changes. Then we run our automated test suite, and if everything is Ok we land the change.
In the case of node-gyp one of the package owners will need to decide when and how to release a new package version. Since this seems like semver-patch this stage will probably be quick.

@refackrefack self-assigned this May 20, 2017
Comment threadgyp/pylib/gyp/easy_xml.py Outdated
xml_string = unicode(xml_string, 'latin-1').encode(encoding)

default_encoding = locale.getdefaultlocale()[1]
if default_encoding != encoding.upper():

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not .upper or .lower both sides?
Also are you sure this won't throw?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, this is my negligence, I mistakenly thought it is capitalized, by this result:

image

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it makes sense to "normalize" both sides, since AFAIK there are no two Language Tags that differ only by case.

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

I can not run gyptest.py on Windows 10.

F:\repos\gyp>python gyptest.py test/win
[ 1/196] (msvs) test\win\generator-output-different-drive\gyptest-generator-output-different-drive.py failed 0.186s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 2e20748> ignored
[ 2/196] (msvs) test\win\gyptest-asm-files.py failed 0.184s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 2a53908> ignored
[ 3/196] (msvs) test\win\gyptest-cl-additional-include-dirs.py failed 0.195s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 29f3908> ignored
[ 4/196] (msvs) test\win\gyptest-cl-additional-options.py failed 0.185s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 2983a20> ignored
[ 6/196] (msvs) test\win\gyptest-cl-buffer-security-check.py failed 0.191s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 2a93978> ignored
[ 7/196] (msvs) test\win\gyptest-cl-calling-convention.py failed 0.199s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 29c3978> ignored
[ 8/196] (msvs) test\win\gyptest-cl-character-set.py failed 0.194s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 2ad3978> ignored

@refack

Copy link
Copy Markdown
Contributor

Which version of Visual Studio you got Installed? Cause if it's VS2017 Build Tools, gyptest can't find them...
You'll need to set an environment variable GYP_BUILD_TOOL to the full path of your msbuild.exe.

Also you could run node-gyp's tests by npm test

BTW: could you add a test case here (maybe add a copy of test\node_modules\hello_world in a unicode path and a call in in test\test-addon.js)

@lc-soft

lc-soft commented May 20, 2017

Copy link
Copy Markdown
ContributorAuthor

@refack OK, It has been running successfully.

F:\repos\gyp>set GYP_BUILD_TOOL=D:\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe
F:\repos\gyp>python gyptest.py test/win

But there are some errors:

[ 6/196] (msvs) test\win\gyptest-cl-buffer-security-check.py failed 3.843s
'D:\Microsoft' is not recognized as an internal or external command, operable program or batch file. Traceback (most recent call last):
File "test\win\gyptest-cl-buffer-security-check.py", line 42, in <module>
if 'security_cookie' not in GetDisassemblyOfMain('test_bsc_unset.exe'):
File "test\win\gyptest-cl-buffer-security-check.py", line 27, in GetDisassemblyOfMain
output = test.run_dumpbin('/disasm', full_path)
File "F:\repos\gyp\test\lib\TestGyp.py", line 813, in run_dumpbin
assert not proc.returncode
AssertionError
...
[ 18/196] (msvs) test\win\gyptest-cl-function-level-linking.py failed 2.896s
'D:\Microsoft' is not recognized as an internal or external command, operable program or batch file. Traceback (most recent call last):
File "test\win\gyptest-cl-function-level-linking.py", line 44, in <module>
should_exist=True)
File "test\win\gyptest-cl-function-level-linking.py", line 23, in CheckForSectionString
output = test.run_dumpbin('/headers', binary)
File "F:\repos\gyp\test\lib\TestGyp.py", line 813, in run_dumpbin
assert not proc.returncode
AssertionError
...

@lc-softlc-soft changed the title Improve xml string encoding conversiongyp: update xml string encoding conversionMay 20, 2017
@refack

Copy link
Copy Markdown
Contributor

Try set GYP_BUILD_TOOL="D:\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe"

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

@refack There will be more problems after using this method.

F:\repos\gyp>set GYP_BUILD_TOOL="D:\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe"
F:\repos\gyp>python gyptest.py test/win
[ 1/196] (msvs) test\win\generator-output-different-drive\gyptest-generator-output-different-drive.py failed 0.806s
STDOUT =========================================================================
STDERR =========================================================================
Exception trying to execute: ['F:\\repos\\gyp\\"D:\\Microsoft Visual Studio\\2017\\Community\\MSBuild\\15.0\\Bin\\MSBuild.exe"', 'prog.sln', '/t:Build', '/p:Configuration=Default']
Traceback (most recent call last):
File "test\win\generator-output-different-drive\gyptest-generator-output-different-drive.py", line 38, in <module>
test.build('prog.gyp', test.ALL, chdir=os.path.join(output_drive, 'output'))
File "F:\repos\gyp\test\lib\TestGyp.py", line 937, in build
return self.run(program=self.build_tool, **kw)
File "F:\repos\gyp\test\lib\TestGyp.py", line 333, in run
super(TestGypBase, self).run(*args, **kw)
File "F:\repos\gyp\test\lib\TestCommon.py", line 542, in run
apply(TestCmd.run, [self], kw)
File "F:\repos\gyp\test\lib\TestCmd.py", line 1224, in run
stdin=stdin)
File "F:\repos\gyp\test\lib\TestCommon.py", line 484, in start
raise e
WindowsError: [Error 5]
[ 2/196] (msvs) test\win\gyptest-asm-files.py failed 1.532s
STDOUT =========================================================================
STDERR =========================================================================
Exception trying to execute: ['F:\\repos\\gyp\\"D:\\Microsoft Visual Studio\\2017\\Community\\MSBuild\\15.0\\Bin\\MSBuild.exe"', 'asm-files.sln', '/t:Build', '/p:Configuration=Default']
Traceback (most recent call last):
File "test\win\gyptest-asm-files.py", line 24, in <module>
test.build('asm-files.gyp', test.ALL, chdir=CHDIR)
File "F:\repos\gyp\test\lib\TestGyp.py", line 937, in build
return self.run(program=self.build_tool, **kw)
File "F:\repos\gyp\test\lib\TestGyp.py", line 333, in run
super(TestGypBase, self).run(*args, **kw)
File "F:\repos\gyp\test\lib\TestCommon.py", line 542, in run
apply(TestCmd.run, [self], kw)
File "F:\repos\gyp\test\lib\TestCmd.py", line 1224, in run
stdin=stdin)
File "F:\repos\gyp\test\lib\TestCommon.py", line 484, in start
raise e
WindowsError: [Error 5]

@refack

Copy link
Copy Markdown
Contributor

Yeah, the test harness is very rusty.
I've pushed your patch to the Chromium code review system, and I've started a CI there - https://chromium-review.googlesource.com/c/509632/

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

@refack Good job! 👍

@refack

Copy link
Copy Markdown
Contributor

@refack

refack commented May 21, 2017

Copy link
Copy Markdown
Contributor

Did I click submit on a comment asking you to add a test?

Anyway, please do. I can suggest copying test\node_modules\hello_world to a path with non latin-1 characters in it, and adding a test case in "test\test-addon.js" building it.

Bonus points if you add a test also to https://github.com/refack/GYP/tree/node-gyp-1203 😉

@refackrefack left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, pending addition of a test.

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

OK, I will take a few days to add test.

Comment threadtest/test-addon.js Outdated
}
runCmd(t, [nodeGyp, 'configure', '-C', addonPath, '--loglevel=verbose',
'-nodedir=' + testNodeDir])
runCmd(t, [nodeGyp, 'build', '-C', addonPath, '--loglevel=verbose'])

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a clean up (try { fs.unlinkSync...)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack I have tried to use the rebuild command before, but there will be errors:

...
gyp verb clean removing "build" directory
gyp ERR! clean error
gyp ERR! stack Error: EPERM: operation not permitted, unlink 'F:\repos\GitHub\node-gyp\test\node_modules\hello_world\build\Release\hello.node'
...

how to solve this problem? a temporary solution is to use configure and build commands.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the reason hello.node can not be deleted is that it is occupied at the time of execution to require('hello_world'). so, solution is to create a new project (E.g:
hello_world_2), and rebuild it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO execFileSync is also completely fine.
OR you could create a hello_非英文字符 fixture.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean something like execFileSync(node, ['-e', "var x = require('hello_world'); if (x.hello() !== 'hello') process.exit(2)"])
Which is more sanitary anyway.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tried to use execFileSync before, but there have been some error messages, so I switched to the current solution.
OK, I will try to use execFileSync again.

@refack

Copy link
Copy Markdown
Contributor

Thank you!
One comment and I'll land this.

Comment threadtest/test-addon.js Outdated
t.plan(5)

configure(t).on('exit', function () {
var data, config, nodeDir, testNodeDir

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack I'am directly merged this test into the test build simple addon.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it works I'm +1
Another solution is to use execFileSync

Comment threadtest/test-addon.js Outdated
}
}

rebuild(t, testNodeDir).on('exit', function () {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Comment threadtest/test-addon.js Outdated
})

test('build simple addon in path with non-ascii characters', function (t) {
t.plan(3)

@lc-softlc-softMay 24, 2017

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack OK, this test has been able to run successfully.

F:\repos\GitHub\node-gyp>node ./test/test-addon.js
TAP version 13
# build simple addon
ok 1 should be equal
ok 2 should end in ok
ok 3 should be equal
# build simple addon in path with non-ascii characters
ok 4 should be equal
ok 5 should end in ok
ok 6 should be equal
1..6
# tests 6
# pass 6
# ok

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@refack

Copy link
Copy Markdown
Contributor

Comment threadtest/test-addon.js
var execFile = require('child_process').execFile
var path = require('path')
var fs = require('graceful-fs')
var child_process = require('child_process')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question to @nodejs/node-gyp
Can we use destructuring?

const{ execFileSync, execFile }=require('child_process')

Or do we test on pre ES6 versions?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the CI still tests 0.10 and 0.12.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not any more 😄

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

CI test did not pass.

gyp: c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\node_modules\hello_world\?????\include\node\common.gypi not found (cwd: c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\node_modules\hello_world) while reading includes of binding.gyp while trying to load binding.gyp
gyp ERR! configure error gyp ERR! stack Error: `gyp` failed with exit code: 1
gyp ERR! stack at ChildProcess.onCpExit (c:\workspace\nodegyp-test-commit\nodes\win2012r2\lib\configure.js:336:16)
gyp ERR! stack at emitTwo (events.js:87:13)
gyp ERR! stack at ChildProcess.emit (events.js:172:7)
gyp ERR! stack at Process.ChildProcess._handle.onexit (internal/child_process.js:211:12)
gyp ERR! System Windows_NT 6.3.9600
gyp ERR! command "c:\\workspace\\nodegyp-test-commit\\nodes\\win2012r2\\local_node\\node.exe" "c:\\workspace\\nodegyp-test-commit\\nodes\\win2012r2\\bin\\node-gyp.js" "rebuild" "-C" "c:\\workspace\\nodegyp-test-commit\\nodes\\win2012r2\\test\\node_modules\\hello_world" "--loglevel=verbose" "-nodedir=c:\\workspace\\nodegyp-test-commit\\nodes\\win2012r2\\test\\node_modules\\hello_world\\�英文字符"
gyp ERR! cwd c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\node_modules\hello_world
gyp ERR! node -v v4.8.3
gyp ERR! node-gyp -v v3.6.1
gyp ERR! not ok 

@refack

Copy link
Copy Markdown
Contributor

Comment threadtest/test-addon.js
if (!checkCharmapValid()) {
return t.skip('python console app can\'t encode non-ascii character.')
}

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack I added the character map check, if python app can not convert non-ASCII characters, then skip this test. console output like this:

TAP version 13
# build simple addon
ok 1 should be equal
ok 2 should end in ok
ok 3 should be equal
# build simple addon in path with non-ascii characters
node : Traceback (most recent call last):
At line:5 char:1
+ node ./test/test-addon
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (Traceback (most recent call last)::String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
File "test-charmap.py", line 20, in <module>
print main()
File "test-charmap.py", line 15, in main
print textmap[encoding]
File "C:\Python27\lib\encodings\cp1252.py", line 12, in encode
return codecs.charmap_encode(input,errors,encoding_table)
UnicodeEncodeError: 'charmap' codec can't encode character u'\u012b' in position 3: character maps to <undefined>
ok 4 python console app can't encode non-ascii character. # SKIP
1..4
# tests 4
# pass 4
# ok

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

@refack
What else do I need to do for this PR ?

Comment threadpackage.json Outdated
},
"scripts": {
"test": "tape test/test-*"
"test": "tape test/test-*.js"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather you move test-charmap.py to test/fixtures

@refack

Copy link
Copy Markdown
Contributor

Comment threadtest/test-addon.js
var execFile = require('child_process').execFile
var path = require('path')
var fs = require('graceful-fs')
var child_process = require('child_process')

@lc-softlc-softJun 8, 2017

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack
Do I need rename child_process to childProcess ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack

Copy link
Copy Markdown
Contributor

If you could rebase on master it will make the CI not test on node < 4

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

https://ci.nodejs.org/job/nodegyp-test-commit/187/nodes=win2012r2/console
execFileSync is undefined ?

c:\workspace\nodegyp-test-commit\nodes\win2012r2>call npm test > node-gyp@3.6.1 test c:\workspace\nodegyp-test-commit\nodes\win2012r2
> tape test/test-*.js
TAP version 13
# build simple addon
ok 1 should be equal
ok 2 should end in ok
c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\test-addon.js:14
return execFileSync('node', ['-e', testCode], { cwd: __dirname }).toString()
^
TypeError: undefined is not a function
at runHello (c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\test-addon.js:14:10)
at c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\test-addon.js:43:19
at ChildProcess.exithandler (child_process.js:656:7)
at ChildProcess.emit (events.js:98:17)
at maybeClose (child_process.js:766:16)
at Process.ChildProcess._handle.onexit (child_process.js:833:5)
npm ERR! Test failed. See above for more details.
Build step 'Conditional steps (multiple)' marked build as failure
Notifying upstream pro

@refack

Copy link
Copy Markdown
Contributor

Ignore it's node@0.10https://ci.nodejs.org/job/nodegyp-test-commit/187/nodes=win2012r2/
As I said if you rebase onto master we bumped the version to 4 and don't test on node < 4

@refack

Copy link
Copy Markdown
Contributor

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

I need to modify this test to make it support node@0.10 ?

@refack

Copy link
Copy Markdown
Contributor

I need to modify this test to make it support node@0.10 ?

No. We stopped supporting node < 4 a week ago.

refack pushed a commit to refack/node-gyp that referenced this pull request Jun 8, 2017
* test: build simple addon in path with non-ascii characters
* test: add test-charmap.py
PR-URL: nodejs#1203
Reviewed-By: Refael Ackermann <refack@gmail.com>
@refack

Copy link
Copy Markdown
Contributor

Landed in d6139b5

@bnoordhuis

Copy link
Copy Markdown
Member

Kind of late to the party but I think there is a bug in the python script. It assumes that locale.getdefaultlocale()[1] is a string but that isn't always true:

$ env LC_ALL=C python -c 'import locale; print locale.getdefaultlocale()'
(None, None)

It makes the test fail (or rather: pass when it shouldn't) like this:

$ env LC_ALL=C node test/test-addon.js TAP version 13
# build simple addon
ok 1 should be equal
ok 2 should end in ok
ok 3 should be equal
# build simple addon in path with non-ascii characters
Traceback (most recent call last):
File "fixtures/test-charmap.py", line 19, in<module>
print main()
File "fixtures/test-charmap.py", line 8, in main
sys.setdefaultencoding(encoding)
TypeError: setdefaultencoding() argument 1 must be string, not None
ok 4 python console app can't encode non-ascii character. # SKIP1..4# tests 4# pass 4# ok

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

@bnoordhuis
I have not tested it when locale.getdefaultlocale()[1] value is None, and I do not know whether python can process non-ascii encoding string, So, in this case, I set default result is python can not process non-ascii encoding string, not need to run the test.

@refack

Copy link
Copy Markdown
Contributor

xml_string = unicode(xml_string, 'latin-1').encode(encoding)

default_encoding = locale.getdefaultlocale()[1]
if default_encoding.upper() != encoding.upper():

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should test default_encoding and default_encoding.upper() != encoding.upper():

@refack

Copy link
Copy Markdown
Contributor

@richardlaurichardlau mentioned this pull request Jul 20, 2018
2 tasks
duqingnian pushed a commit to duqingnian/gyp that referenced this pull request Apr 26, 2024
Bug: nodejs/node-gyp#1203
Change-Id: I30d71a2bb3d4b09e7bd9409c3c45c32bd182d736
duqingnian pushed a commit to duqingnian/gyp that referenced this pull request Apr 26, 2024
Bug: nodejs/node-gyp#1203
Change-Id: I30d71a2bb3d4b09e7bd9409c3c45c32bd182d736
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@lc-soft@gibfahn@refack@bnoordhuis@richardlau
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all \u003cpre\u003e\u003ccode\u003e blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks"); } } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); } })(); (function(){ try { var __m = "github.com"; var __re = new RegExp('^' + "github\\.com" + '
Skip to content

gyp: update xml string encoding conversion - #1203

Closed
lc-soft wants to merge 3 commits into
nodejs:masterfrom
lc-soft:fix_xml_encoding_bug
Closed

gyp: update xml string encoding conversion#1203
lc-soft wants to merge 3 commits into
nodejs:masterfrom
lc-soft:fix_xml_encoding_bug

Conversation

@lc-soft

@lc-softlc-soft commented May 20, 2017

Copy link
Copy Markdown
Contributor

My project depends on the node-sass, but it can not successfully install, so I tried using the npm rebuild node-sass --force command to build the node-sass on Windows 10. But it could not be built successfully, error message is: "node_version.h": No such file or directory

I guess this is the problem of compiling configuration, and I found the node-sass\build\binding.vcxproj file from the output information, so I opened it with the editor and found that the configuration item has garbled text:

qq 20170520130717

My username can not be displayed correctly, there seems to be a encoding conversion bug when writing to the binding.vcxproj file. I took some time to debug it, Eventually I found the problem out here: easy_xml.py#L120

qq 20170520130900

Since xml_string contains non-ascii characters, xml_string.encode() will fail and throw an exception, and then this string will be treated as latin-1 encoded string to convert, but my default locale character encoding is not latin-1, therefore, the binding.vcproj file is written with the wrong content.

After modification, the contents of the output file is correct.

qq 20170520130513

node-sass can be built successfully.

gyp info ok
Installed to F:\work\XXXXXX\node_modules\node-sass\vendor\win32-x64-48\binding.node
node-sass@4.5.3 F:\work\XXXXXX\node_modules\node-sass

@gibfahn

Copy link
Copy Markdown
Member

Maybe cc/ @joaocgreis@refack ?

Proposed change seems reasonable, but I don't know enough to review.

@refack

Copy link
Copy Markdown
Contributor

@lc-soft I'll have a look
Since it looks like a bug in GYP you should also open an issue at https://bugs.chromium.org/p/gyp/issues/list or even submit a patch

@refack

Copy link
Copy Markdown
Contributor

P.S. I keep forgetting to say...
Thank you very much for the contribution! 🥇

@lc-soft

lc-soft commented May 20, 2017

Copy link
Copy Markdown
ContributorAuthor

@refack I found these: #366#945#297.
This is old bug. but they did not submit a patch to upstream, this file has not been changed:
https://chromium.googlesource.com/external/gyp.git/+/master/pylib/gyp/easy_xml.py#105

@refack

Copy link
Copy Markdown
Contributor

I found these: #366#945#297, This is old bug. but they did not submit a patch to upstream, this file has not been changed:
https://chromium.googlesource.com/external/gyp.git/+/master/pylib/gyp/easy_xml.py#105

Yeah, for a long time upstream GYP was unresponsive so people didn't bother with submitting patches. They are trying to be better 🤷‍♂️ . Thank you for pointing me to those PRs!

I'm looking at your patch, we might land it here, and then try to push it upstream.

Anyway since AFAIK this is your first contribution, I'll give you some info on our review and landing process.
Ref: https://github.com/nodejs/node/blob/master/CONTRIBUTING.md#step-7-discuss-and-update
We keep the PR open for at least 48-72 hours so that anyone that might have some input to give will have get a chance. We will go over your code change, maybe ask a few question or request some changes. Then we run our automated test suite, and if everything is Ok we land the change.
In the case of node-gyp one of the package owners will need to decide when and how to release a new package version. Since this seems like semver-patch this stage will probably be quick.

@refackrefack self-assigned this May 20, 2017
Comment threadgyp/pylib/gyp/easy_xml.py Outdated
xml_string = unicode(xml_string, 'latin-1').encode(encoding)

default_encoding = locale.getdefaultlocale()[1]
if default_encoding != encoding.upper():

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not .upper or .lower both sides?
Also are you sure this won't throw?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, this is my negligence, I mistakenly thought it is capitalized, by this result:

image

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it makes sense to "normalize" both sides, since AFAIK there are no two Language Tags that differ only by case.

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

I can not run gyptest.py on Windows 10.

F:\repos\gyp>python gyptest.py test/win
[ 1/196] (msvs) test\win\generator-output-different-drive\gyptest-generator-output-different-drive.py failed 0.186s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 2e20748> ignored
[ 2/196] (msvs) test\win\gyptest-asm-files.py failed 0.184s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 2a53908> ignored
[ 3/196] (msvs) test\win\gyptest-cl-additional-include-dirs.py failed 0.195s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 29f3908> ignored
[ 4/196] (msvs) test\win\gyptest-cl-additional-options.py failed 0.185s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 2983a20> ignored
[ 6/196] (msvs) test\win\gyptest-cl-buffer-security-check.py failed 0.191s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 2a93978> ignored
[ 7/196] (msvs) test\win\gyptest-cl-calling-convention.py failed 0.199s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 29c3978> ignored
[ 8/196] (msvs) test\win\gyptest-cl-character-set.py failed 0.194s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 2ad3978> ignored

@refack

Copy link
Copy Markdown
Contributor

Which version of Visual Studio you got Installed? Cause if it's VS2017 Build Tools, gyptest can't find them...
You'll need to set an environment variable GYP_BUILD_TOOL to the full path of your msbuild.exe.

Also you could run node-gyp's tests by npm test

BTW: could you add a test case here (maybe add a copy of test\node_modules\hello_world in a unicode path and a call in in test\test-addon.js)

@lc-soft

lc-soft commented May 20, 2017

Copy link
Copy Markdown
ContributorAuthor

@refack OK, It has been running successfully.

F:\repos\gyp>set GYP_BUILD_TOOL=D:\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe
F:\repos\gyp>python gyptest.py test/win

But there are some errors:

[ 6/196] (msvs) test\win\gyptest-cl-buffer-security-check.py failed 3.843s
'D:\Microsoft' is not recognized as an internal or external command, operable program or batch file. Traceback (most recent call last):
File "test\win\gyptest-cl-buffer-security-check.py", line 42, in <module>
if 'security_cookie' not in GetDisassemblyOfMain('test_bsc_unset.exe'):
File "test\win\gyptest-cl-buffer-security-check.py", line 27, in GetDisassemblyOfMain
output = test.run_dumpbin('/disasm', full_path)
File "F:\repos\gyp\test\lib\TestGyp.py", line 813, in run_dumpbin
assert not proc.returncode
AssertionError
...
[ 18/196] (msvs) test\win\gyptest-cl-function-level-linking.py failed 2.896s
'D:\Microsoft' is not recognized as an internal or external command, operable program or batch file. Traceback (most recent call last):
File "test\win\gyptest-cl-function-level-linking.py", line 44, in <module>
should_exist=True)
File "test\win\gyptest-cl-function-level-linking.py", line 23, in CheckForSectionString
output = test.run_dumpbin('/headers', binary)
File "F:\repos\gyp\test\lib\TestGyp.py", line 813, in run_dumpbin
assert not proc.returncode
AssertionError
...

@lc-softlc-soft changed the title Improve xml string encoding conversiongyp: update xml string encoding conversionMay 20, 2017
@refack

Copy link
Copy Markdown
Contributor

Try set GYP_BUILD_TOOL="D:\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe"

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

@refack There will be more problems after using this method.

F:\repos\gyp>set GYP_BUILD_TOOL="D:\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe"
F:\repos\gyp>python gyptest.py test/win
[ 1/196] (msvs) test\win\generator-output-different-drive\gyptest-generator-output-different-drive.py failed 0.806s
STDOUT =========================================================================
STDERR =========================================================================
Exception trying to execute: ['F:\\repos\\gyp\\"D:\\Microsoft Visual Studio\\2017\\Community\\MSBuild\\15.0\\Bin\\MSBuild.exe"', 'prog.sln', '/t:Build', '/p:Configuration=Default']
Traceback (most recent call last):
File "test\win\generator-output-different-drive\gyptest-generator-output-different-drive.py", line 38, in <module>
test.build('prog.gyp', test.ALL, chdir=os.path.join(output_drive, 'output'))
File "F:\repos\gyp\test\lib\TestGyp.py", line 937, in build
return self.run(program=self.build_tool, **kw)
File "F:\repos\gyp\test\lib\TestGyp.py", line 333, in run
super(TestGypBase, self).run(*args, **kw)
File "F:\repos\gyp\test\lib\TestCommon.py", line 542, in run
apply(TestCmd.run, [self], kw)
File "F:\repos\gyp\test\lib\TestCmd.py", line 1224, in run
stdin=stdin)
File "F:\repos\gyp\test\lib\TestCommon.py", line 484, in start
raise e
WindowsError: [Error 5]
[ 2/196] (msvs) test\win\gyptest-asm-files.py failed 1.532s
STDOUT =========================================================================
STDERR =========================================================================
Exception trying to execute: ['F:\\repos\\gyp\\"D:\\Microsoft Visual Studio\\2017\\Community\\MSBuild\\15.0\\Bin\\MSBuild.exe"', 'asm-files.sln', '/t:Build', '/p:Configuration=Default']
Traceback (most recent call last):
File "test\win\gyptest-asm-files.py", line 24, in <module>
test.build('asm-files.gyp', test.ALL, chdir=CHDIR)
File "F:\repos\gyp\test\lib\TestGyp.py", line 937, in build
return self.run(program=self.build_tool, **kw)
File "F:\repos\gyp\test\lib\TestGyp.py", line 333, in run
super(TestGypBase, self).run(*args, **kw)
File "F:\repos\gyp\test\lib\TestCommon.py", line 542, in run
apply(TestCmd.run, [self], kw)
File "F:\repos\gyp\test\lib\TestCmd.py", line 1224, in run
stdin=stdin)
File "F:\repos\gyp\test\lib\TestCommon.py", line 484, in start
raise e
WindowsError: [Error 5]

@refack

Copy link
Copy Markdown
Contributor

Yeah, the test harness is very rusty.
I've pushed your patch to the Chromium code review system, and I've started a CI there - https://chromium-review.googlesource.com/c/509632/

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

@refack Good job! 👍

@refack

Copy link
Copy Markdown
Contributor

@refack

refack commented May 21, 2017

Copy link
Copy Markdown
Contributor

Did I click submit on a comment asking you to add a test?

Anyway, please do. I can suggest copying test\node_modules\hello_world to a path with non latin-1 characters in it, and adding a test case in "test\test-addon.js" building it.

Bonus points if you add a test also to https://github.com/refack/GYP/tree/node-gyp-1203 😉

@refackrefack left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, pending addition of a test.

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

OK, I will take a few days to add test.

Comment threadtest/test-addon.js Outdated
}
runCmd(t, [nodeGyp, 'configure', '-C', addonPath, '--loglevel=verbose',
'-nodedir=' + testNodeDir])
runCmd(t, [nodeGyp, 'build', '-C', addonPath, '--loglevel=verbose'])

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a clean up (try { fs.unlinkSync...)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack I have tried to use the rebuild command before, but there will be errors:

...
gyp verb clean removing "build" directory
gyp ERR! clean error
gyp ERR! stack Error: EPERM: operation not permitted, unlink 'F:\repos\GitHub\node-gyp\test\node_modules\hello_world\build\Release\hello.node'
...

how to solve this problem? a temporary solution is to use configure and build commands.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the reason hello.node can not be deleted is that it is occupied at the time of execution to require('hello_world'). so, solution is to create a new project (E.g:
hello_world_2), and rebuild it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO execFileSync is also completely fine.
OR you could create a hello_非英文字符 fixture.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean something like execFileSync(node, ['-e', "var x = require('hello_world'); if (x.hello() !== 'hello') process.exit(2)"])
Which is more sanitary anyway.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tried to use execFileSync before, but there have been some error messages, so I switched to the current solution.
OK, I will try to use execFileSync again.

@refack

Copy link
Copy Markdown
Contributor

Thank you!
One comment and I'll land this.

Comment threadtest/test-addon.js Outdated
t.plan(5)

configure(t).on('exit', function () {
var data, config, nodeDir, testNodeDir

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack I'am directly merged this test into the test build simple addon.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it works I'm +1
Another solution is to use execFileSync

Comment threadtest/test-addon.js Outdated
}
}

rebuild(t, testNodeDir).on('exit', function () {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Comment threadtest/test-addon.js Outdated
})

test('build simple addon in path with non-ascii characters', function (t) {
t.plan(3)

@lc-softlc-softMay 24, 2017

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack OK, this test has been able to run successfully.

F:\repos\GitHub\node-gyp>node ./test/test-addon.js
TAP version 13
# build simple addon
ok 1 should be equal
ok 2 should end in ok
ok 3 should be equal
# build simple addon in path with non-ascii characters
ok 4 should be equal
ok 5 should end in ok
ok 6 should be equal
1..6
# tests 6
# pass 6
# ok

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@refack

Copy link
Copy Markdown
Contributor

Comment threadtest/test-addon.js
var execFile = require('child_process').execFile
var path = require('path')
var fs = require('graceful-fs')
var child_process = require('child_process')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question to @nodejs/node-gyp
Can we use destructuring?

const{ execFileSync, execFile }=require('child_process')

Or do we test on pre ES6 versions?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the CI still tests 0.10 and 0.12.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not any more 😄

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

CI test did not pass.

gyp: c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\node_modules\hello_world\?????\include\node\common.gypi not found (cwd: c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\node_modules\hello_world) while reading includes of binding.gyp while trying to load binding.gyp
gyp ERR! configure error gyp ERR! stack Error: `gyp` failed with exit code: 1
gyp ERR! stack at ChildProcess.onCpExit (c:\workspace\nodegyp-test-commit\nodes\win2012r2\lib\configure.js:336:16)
gyp ERR! stack at emitTwo (events.js:87:13)
gyp ERR! stack at ChildProcess.emit (events.js:172:7)
gyp ERR! stack at Process.ChildProcess._handle.onexit (internal/child_process.js:211:12)
gyp ERR! System Windows_NT 6.3.9600
gyp ERR! command "c:\\workspace\\nodegyp-test-commit\\nodes\\win2012r2\\local_node\\node.exe" "c:\\workspace\\nodegyp-test-commit\\nodes\\win2012r2\\bin\\node-gyp.js" "rebuild" "-C" "c:\\workspace\\nodegyp-test-commit\\nodes\\win2012r2\\test\\node_modules\\hello_world" "--loglevel=verbose" "-nodedir=c:\\workspace\\nodegyp-test-commit\\nodes\\win2012r2\\test\\node_modules\\hello_world\\�英文字符"
gyp ERR! cwd c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\node_modules\hello_world
gyp ERR! node -v v4.8.3
gyp ERR! node-gyp -v v3.6.1
gyp ERR! not ok 

@refack

Copy link
Copy Markdown
Contributor

Comment threadtest/test-addon.js
if (!checkCharmapValid()) {
return t.skip('python console app can\'t encode non-ascii character.')
}

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack I added the character map check, if python app can not convert non-ASCII characters, then skip this test. console output like this:

TAP version 13
# build simple addon
ok 1 should be equal
ok 2 should end in ok
ok 3 should be equal
# build simple addon in path with non-ascii characters
node : Traceback (most recent call last):
At line:5 char:1
+ node ./test/test-addon
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (Traceback (most recent call last)::String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
File "test-charmap.py", line 20, in <module>
print main()
File "test-charmap.py", line 15, in main
print textmap[encoding]
File "C:\Python27\lib\encodings\cp1252.py", line 12, in encode
return codecs.charmap_encode(input,errors,encoding_table)
UnicodeEncodeError: 'charmap' codec can't encode character u'\u012b' in position 3: character maps to <undefined>
ok 4 python console app can't encode non-ascii character. # SKIP
1..4
# tests 4
# pass 4
# ok

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

@refack
What else do I need to do for this PR ?

Comment threadpackage.json Outdated
},
"scripts": {
"test": "tape test/test-*"
"test": "tape test/test-*.js"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather you move test-charmap.py to test/fixtures

@refack

Copy link
Copy Markdown
Contributor

Comment threadtest/test-addon.js
var execFile = require('child_process').execFile
var path = require('path')
var fs = require('graceful-fs')
var child_process = require('child_process')

@lc-softlc-softJun 8, 2017

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack
Do I need rename child_process to childProcess ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack

Copy link
Copy Markdown
Contributor

If you could rebase on master it will make the CI not test on node < 4

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

https://ci.nodejs.org/job/nodegyp-test-commit/187/nodes=win2012r2/console
execFileSync is undefined ?

c:\workspace\nodegyp-test-commit\nodes\win2012r2>call npm test > node-gyp@3.6.1 test c:\workspace\nodegyp-test-commit\nodes\win2012r2
> tape test/test-*.js
TAP version 13
# build simple addon
ok 1 should be equal
ok 2 should end in ok
c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\test-addon.js:14
return execFileSync('node', ['-e', testCode], { cwd: __dirname }).toString()
^
TypeError: undefined is not a function
at runHello (c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\test-addon.js:14:10)
at c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\test-addon.js:43:19
at ChildProcess.exithandler (child_process.js:656:7)
at ChildProcess.emit (events.js:98:17)
at maybeClose (child_process.js:766:16)
at Process.ChildProcess._handle.onexit (child_process.js:833:5)
npm ERR! Test failed. See above for more details.
Build step 'Conditional steps (multiple)' marked build as failure
Notifying upstream pro

@refack

Copy link
Copy Markdown
Contributor

Ignore it's node@0.10https://ci.nodejs.org/job/nodegyp-test-commit/187/nodes=win2012r2/
As I said if you rebase onto master we bumped the version to 4 and don't test on node < 4

@refack

Copy link
Copy Markdown
Contributor

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

I need to modify this test to make it support node@0.10 ?

@refack

Copy link
Copy Markdown
Contributor

I need to modify this test to make it support node@0.10 ?

No. We stopped supporting node < 4 a week ago.

refack pushed a commit to refack/node-gyp that referenced this pull request Jun 8, 2017
* test: build simple addon in path with non-ascii characters
* test: add test-charmap.py
PR-URL: nodejs#1203
Reviewed-By: Refael Ackermann <refack@gmail.com>
@refack

Copy link
Copy Markdown
Contributor

Landed in d6139b5

@bnoordhuis

Copy link
Copy Markdown
Member

Kind of late to the party but I think there is a bug in the python script. It assumes that locale.getdefaultlocale()[1] is a string but that isn't always true:

$ env LC_ALL=C python -c 'import locale; print locale.getdefaultlocale()'
(None, None)

It makes the test fail (or rather: pass when it shouldn't) like this:

$ env LC_ALL=C node test/test-addon.js TAP version 13
# build simple addon
ok 1 should be equal
ok 2 should end in ok
ok 3 should be equal
# build simple addon in path with non-ascii characters
Traceback (most recent call last):
File "fixtures/test-charmap.py", line 19, in<module>
print main()
File "fixtures/test-charmap.py", line 8, in main
sys.setdefaultencoding(encoding)
TypeError: setdefaultencoding() argument 1 must be string, not None
ok 4 python console app can't encode non-ascii character. # SKIP1..4# tests 4# pass 4# ok

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

@bnoordhuis
I have not tested it when locale.getdefaultlocale()[1] value is None, and I do not know whether python can process non-ascii encoding string, So, in this case, I set default result is python can not process non-ascii encoding string, not need to run the test.

@refack

Copy link
Copy Markdown
Contributor

xml_string = unicode(xml_string, 'latin-1').encode(encoding)

default_encoding = locale.getdefaultlocale()[1]
if default_encoding.upper() != encoding.upper():

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should test default_encoding and default_encoding.upper() != encoding.upper():

@refack

Copy link
Copy Markdown
Contributor

@richardlaurichardlau mentioned this pull request Jul 20, 2018
2 tasks
duqingnian pushed a commit to duqingnian/gyp that referenced this pull request Apr 26, 2024
Bug: nodejs/node-gyp#1203
Change-Id: I30d71a2bb3d4b09e7bd9409c3c45c32bd182d736
duqingnian pushed a commit to duqingnian/gyp that referenced this pull request Apr 26, 2024
Bug: nodejs/node-gyp#1203
Change-Id: I30d71a2bb3d4b09e7bd9409c3c45c32bd182d736
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@lc-soft@gibfahn@refack@bnoordhuis@richardlau
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

gyp: update xml string encoding conversion - #1203

Closed
lc-soft wants to merge 3 commits into
nodejs:masterfrom
lc-soft:fix_xml_encoding_bug
Closed

gyp: update xml string encoding conversion#1203
lc-soft wants to merge 3 commits into
nodejs:masterfrom
lc-soft:fix_xml_encoding_bug

Conversation

@lc-soft

@lc-softlc-soft commented May 20, 2017

Copy link
Copy Markdown
Contributor

My project depends on the node-sass, but it can not successfully install, so I tried using the npm rebuild node-sass --force command to build the node-sass on Windows 10. But it could not be built successfully, error message is: "node_version.h": No such file or directory

I guess this is the problem of compiling configuration, and I found the node-sass\build\binding.vcxproj file from the output information, so I opened it with the editor and found that the configuration item has garbled text:

qq 20170520130717

My username can not be displayed correctly, there seems to be a encoding conversion bug when writing to the binding.vcxproj file. I took some time to debug it, Eventually I found the problem out here: easy_xml.py#L120

qq 20170520130900

Since xml_string contains non-ascii characters, xml_string.encode() will fail and throw an exception, and then this string will be treated as latin-1 encoded string to convert, but my default locale character encoding is not latin-1, therefore, the binding.vcproj file is written with the wrong content.

After modification, the contents of the output file is correct.

qq 20170520130513

node-sass can be built successfully.

gyp info ok
Installed to F:\work\XXXXXX\node_modules\node-sass\vendor\win32-x64-48\binding.node
node-sass@4.5.3 F:\work\XXXXXX\node_modules\node-sass

@gibfahn

Copy link
Copy Markdown
Member

Maybe cc/ @joaocgreis@refack ?

Proposed change seems reasonable, but I don't know enough to review.

@refack

Copy link
Copy Markdown
Contributor

@lc-soft I'll have a look
Since it looks like a bug in GYP you should also open an issue at https://bugs.chromium.org/p/gyp/issues/list or even submit a patch

@refack

Copy link
Copy Markdown
Contributor

P.S. I keep forgetting to say...
Thank you very much for the contribution! 🥇

@lc-soft

lc-soft commented May 20, 2017

Copy link
Copy Markdown
ContributorAuthor

@refack I found these: #366#945#297.
This is old bug. but they did not submit a patch to upstream, this file has not been changed:
https://chromium.googlesource.com/external/gyp.git/+/master/pylib/gyp/easy_xml.py#105

@refack

Copy link
Copy Markdown
Contributor

I found these: #366#945#297, This is old bug. but they did not submit a patch to upstream, this file has not been changed:
https://chromium.googlesource.com/external/gyp.git/+/master/pylib/gyp/easy_xml.py#105

Yeah, for a long time upstream GYP was unresponsive so people didn't bother with submitting patches. They are trying to be better 🤷‍♂️ . Thank you for pointing me to those PRs!

I'm looking at your patch, we might land it here, and then try to push it upstream.

Anyway since AFAIK this is your first contribution, I'll give you some info on our review and landing process.
Ref: https://github.com/nodejs/node/blob/master/CONTRIBUTING.md#step-7-discuss-and-update
We keep the PR open for at least 48-72 hours so that anyone that might have some input to give will have get a chance. We will go over your code change, maybe ask a few question or request some changes. Then we run our automated test suite, and if everything is Ok we land the change.
In the case of node-gyp one of the package owners will need to decide when and how to release a new package version. Since this seems like semver-patch this stage will probably be quick.

@refackrefack self-assigned this May 20, 2017
Comment threadgyp/pylib/gyp/easy_xml.py Outdated
xml_string = unicode(xml_string, 'latin-1').encode(encoding)

default_encoding = locale.getdefaultlocale()[1]
if default_encoding != encoding.upper():

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not .upper or .lower both sides?
Also are you sure this won't throw?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, this is my negligence, I mistakenly thought it is capitalized, by this result:

image

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it makes sense to "normalize" both sides, since AFAIK there are no two Language Tags that differ only by case.

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

I can not run gyptest.py on Windows 10.

F:\repos\gyp>python gyptest.py test/win
[ 1/196] (msvs) test\win\generator-output-different-drive\gyptest-generator-output-different-drive.py failed 0.186s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 2e20748> ignored
[ 2/196] (msvs) test\win\gyptest-asm-files.py failed 0.184s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 2a53908> ignored
[ 3/196] (msvs) test\win\gyptest-cl-additional-include-dirs.py failed 0.195s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 29f3908> ignored
[ 4/196] (msvs) test\win\gyptest-cl-additional-options.py failed 0.185s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 2983a20> ignored
[ 6/196] (msvs) test\win\gyptest-cl-buffer-security-check.py failed 0.191s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 2a93978> ignored
[ 7/196] (msvs) test\win\gyptest-cl-calling-convention.py failed 0.199s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 29c3978> ignored
[ 8/196] (msvs) test\win\gyptest-cl-character-set.py failed 0.194s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 2ad3978> ignored

@refack

Copy link
Copy Markdown
Contributor

Which version of Visual Studio you got Installed? Cause if it's VS2017 Build Tools, gyptest can't find them...
You'll need to set an environment variable GYP_BUILD_TOOL to the full path of your msbuild.exe.

Also you could run node-gyp's tests by npm test

BTW: could you add a test case here (maybe add a copy of test\node_modules\hello_world in a unicode path and a call in in test\test-addon.js)

@lc-soft

lc-soft commented May 20, 2017

Copy link
Copy Markdown
ContributorAuthor

@refack OK, It has been running successfully.

F:\repos\gyp>set GYP_BUILD_TOOL=D:\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe
F:\repos\gyp>python gyptest.py test/win

But there are some errors:

[ 6/196] (msvs) test\win\gyptest-cl-buffer-security-check.py failed 3.843s
'D:\Microsoft' is not recognized as an internal or external command, operable program or batch file. Traceback (most recent call last):
File "test\win\gyptest-cl-buffer-security-check.py", line 42, in <module>
if 'security_cookie' not in GetDisassemblyOfMain('test_bsc_unset.exe'):
File "test\win\gyptest-cl-buffer-security-check.py", line 27, in GetDisassemblyOfMain
output = test.run_dumpbin('/disasm', full_path)
File "F:\repos\gyp\test\lib\TestGyp.py", line 813, in run_dumpbin
assert not proc.returncode
AssertionError
...
[ 18/196] (msvs) test\win\gyptest-cl-function-level-linking.py failed 2.896s
'D:\Microsoft' is not recognized as an internal or external command, operable program or batch file. Traceback (most recent call last):
File "test\win\gyptest-cl-function-level-linking.py", line 44, in <module>
should_exist=True)
File "test\win\gyptest-cl-function-level-linking.py", line 23, in CheckForSectionString
output = test.run_dumpbin('/headers', binary)
File "F:\repos\gyp\test\lib\TestGyp.py", line 813, in run_dumpbin
assert not proc.returncode
AssertionError
...

@lc-softlc-soft changed the title Improve xml string encoding conversiongyp: update xml string encoding conversionMay 20, 2017
@refack

Copy link
Copy Markdown
Contributor

Try set GYP_BUILD_TOOL="D:\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe"

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

@refack There will be more problems after using this method.

F:\repos\gyp>set GYP_BUILD_TOOL="D:\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe"
F:\repos\gyp>python gyptest.py test/win
[ 1/196] (msvs) test\win\generator-output-different-drive\gyptest-generator-output-different-drive.py failed 0.806s
STDOUT =========================================================================
STDERR =========================================================================
Exception trying to execute: ['F:\\repos\\gyp\\"D:\\Microsoft Visual Studio\\2017\\Community\\MSBuild\\15.0\\Bin\\MSBuild.exe"', 'prog.sln', '/t:Build', '/p:Configuration=Default']
Traceback (most recent call last):
File "test\win\generator-output-different-drive\gyptest-generator-output-different-drive.py", line 38, in <module>
test.build('prog.gyp', test.ALL, chdir=os.path.join(output_drive, 'output'))
File "F:\repos\gyp\test\lib\TestGyp.py", line 937, in build
return self.run(program=self.build_tool, **kw)
File "F:\repos\gyp\test\lib\TestGyp.py", line 333, in run
super(TestGypBase, self).run(*args, **kw)
File "F:\repos\gyp\test\lib\TestCommon.py", line 542, in run
apply(TestCmd.run, [self], kw)
File "F:\repos\gyp\test\lib\TestCmd.py", line 1224, in run
stdin=stdin)
File "F:\repos\gyp\test\lib\TestCommon.py", line 484, in start
raise e
WindowsError: [Error 5]
[ 2/196] (msvs) test\win\gyptest-asm-files.py failed 1.532s
STDOUT =========================================================================
STDERR =========================================================================
Exception trying to execute: ['F:\\repos\\gyp\\"D:\\Microsoft Visual Studio\\2017\\Community\\MSBuild\\15.0\\Bin\\MSBuild.exe"', 'asm-files.sln', '/t:Build', '/p:Configuration=Default']
Traceback (most recent call last):
File "test\win\gyptest-asm-files.py", line 24, in <module>
test.build('asm-files.gyp', test.ALL, chdir=CHDIR)
File "F:\repos\gyp\test\lib\TestGyp.py", line 937, in build
return self.run(program=self.build_tool, **kw)
File "F:\repos\gyp\test\lib\TestGyp.py", line 333, in run
super(TestGypBase, self).run(*args, **kw)
File "F:\repos\gyp\test\lib\TestCommon.py", line 542, in run
apply(TestCmd.run, [self], kw)
File "F:\repos\gyp\test\lib\TestCmd.py", line 1224, in run
stdin=stdin)
File "F:\repos\gyp\test\lib\TestCommon.py", line 484, in start
raise e
WindowsError: [Error 5]

@refack

Copy link
Copy Markdown
Contributor

Yeah, the test harness is very rusty.
I've pushed your patch to the Chromium code review system, and I've started a CI there - https://chromium-review.googlesource.com/c/509632/

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

@refack Good job! 👍

@refack

Copy link
Copy Markdown
Contributor

@refack

refack commented May 21, 2017

Copy link
Copy Markdown
Contributor

Did I click submit on a comment asking you to add a test?

Anyway, please do. I can suggest copying test\node_modules\hello_world to a path with non latin-1 characters in it, and adding a test case in "test\test-addon.js" building it.

Bonus points if you add a test also to https://github.com/refack/GYP/tree/node-gyp-1203 😉

@refackrefack left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, pending addition of a test.

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

OK, I will take a few days to add test.

Comment threadtest/test-addon.js Outdated
}
runCmd(t, [nodeGyp, 'configure', '-C', addonPath, '--loglevel=verbose',
'-nodedir=' + testNodeDir])
runCmd(t, [nodeGyp, 'build', '-C', addonPath, '--loglevel=verbose'])

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a clean up (try { fs.unlinkSync...)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack I have tried to use the rebuild command before, but there will be errors:

...
gyp verb clean removing "build" directory
gyp ERR! clean error
gyp ERR! stack Error: EPERM: operation not permitted, unlink 'F:\repos\GitHub\node-gyp\test\node_modules\hello_world\build\Release\hello.node'
...

how to solve this problem? a temporary solution is to use configure and build commands.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the reason hello.node can not be deleted is that it is occupied at the time of execution to require('hello_world'). so, solution is to create a new project (E.g:
hello_world_2), and rebuild it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO execFileSync is also completely fine.
OR you could create a hello_非英文字符 fixture.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean something like execFileSync(node, ['-e', "var x = require('hello_world'); if (x.hello() !== 'hello') process.exit(2)"])
Which is more sanitary anyway.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tried to use execFileSync before, but there have been some error messages, so I switched to the current solution.
OK, I will try to use execFileSync again.

@refack

Copy link
Copy Markdown
Contributor

Thank you!
One comment and I'll land this.

Comment threadtest/test-addon.js Outdated
t.plan(5)

configure(t).on('exit', function () {
var data, config, nodeDir, testNodeDir

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack I'am directly merged this test into the test build simple addon.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it works I'm +1
Another solution is to use execFileSync

Comment threadtest/test-addon.js Outdated
}
}

rebuild(t, testNodeDir).on('exit', function () {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Comment threadtest/test-addon.js Outdated
})

test('build simple addon in path with non-ascii characters', function (t) {
t.plan(3)

@lc-softlc-softMay 24, 2017

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack OK, this test has been able to run successfully.

F:\repos\GitHub\node-gyp>node ./test/test-addon.js
TAP version 13
# build simple addon
ok 1 should be equal
ok 2 should end in ok
ok 3 should be equal
# build simple addon in path with non-ascii characters
ok 4 should be equal
ok 5 should end in ok
ok 6 should be equal
1..6
# tests 6
# pass 6
# ok

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@refack

Copy link
Copy Markdown
Contributor

Comment threadtest/test-addon.js
var execFile = require('child_process').execFile
var path = require('path')
var fs = require('graceful-fs')
var child_process = require('child_process')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question to @nodejs/node-gyp
Can we use destructuring?

const{ execFileSync, execFile }=require('child_process')

Or do we test on pre ES6 versions?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the CI still tests 0.10 and 0.12.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not any more 😄

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

CI test did not pass.

gyp: c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\node_modules\hello_world\?????\include\node\common.gypi not found (cwd: c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\node_modules\hello_world) while reading includes of binding.gyp while trying to load binding.gyp
gyp ERR! configure error gyp ERR! stack Error: `gyp` failed with exit code: 1
gyp ERR! stack at ChildProcess.onCpExit (c:\workspace\nodegyp-test-commit\nodes\win2012r2\lib\configure.js:336:16)
gyp ERR! stack at emitTwo (events.js:87:13)
gyp ERR! stack at ChildProcess.emit (events.js:172:7)
gyp ERR! stack at Process.ChildProcess._handle.onexit (internal/child_process.js:211:12)
gyp ERR! System Windows_NT 6.3.9600
gyp ERR! command "c:\\workspace\\nodegyp-test-commit\\nodes\\win2012r2\\local_node\\node.exe" "c:\\workspace\\nodegyp-test-commit\\nodes\\win2012r2\\bin\\node-gyp.js" "rebuild" "-C" "c:\\workspace\\nodegyp-test-commit\\nodes\\win2012r2\\test\\node_modules\\hello_world" "--loglevel=verbose" "-nodedir=c:\\workspace\\nodegyp-test-commit\\nodes\\win2012r2\\test\\node_modules\\hello_world\\�英文字符"
gyp ERR! cwd c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\node_modules\hello_world
gyp ERR! node -v v4.8.3
gyp ERR! node-gyp -v v3.6.1
gyp ERR! not ok 

@refack

Copy link
Copy Markdown
Contributor

Comment threadtest/test-addon.js
if (!checkCharmapValid()) {
return t.skip('python console app can\'t encode non-ascii character.')
}

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack I added the character map check, if python app can not convert non-ASCII characters, then skip this test. console output like this:

TAP version 13
# build simple addon
ok 1 should be equal
ok 2 should end in ok
ok 3 should be equal
# build simple addon in path with non-ascii characters
node : Traceback (most recent call last):
At line:5 char:1
+ node ./test/test-addon
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (Traceback (most recent call last)::String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
File "test-charmap.py", line 20, in <module>
print main()
File "test-charmap.py", line 15, in main
print textmap[encoding]
File "C:\Python27\lib\encodings\cp1252.py", line 12, in encode
return codecs.charmap_encode(input,errors,encoding_table)
UnicodeEncodeError: 'charmap' codec can't encode character u'\u012b' in position 3: character maps to <undefined>
ok 4 python console app can't encode non-ascii character. # SKIP
1..4
# tests 4
# pass 4
# ok

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

@refack
What else do I need to do for this PR ?

Comment threadpackage.json Outdated
},
"scripts": {
"test": "tape test/test-*"
"test": "tape test/test-*.js"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather you move test-charmap.py to test/fixtures

@refack

Copy link
Copy Markdown
Contributor

Comment threadtest/test-addon.js
var execFile = require('child_process').execFile
var path = require('path')
var fs = require('graceful-fs')
var child_process = require('child_process')

@lc-softlc-softJun 8, 2017

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack
Do I need rename child_process to childProcess ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack

Copy link
Copy Markdown
Contributor

If you could rebase on master it will make the CI not test on node < 4

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

https://ci.nodejs.org/job/nodegyp-test-commit/187/nodes=win2012r2/console
execFileSync is undefined ?

c:\workspace\nodegyp-test-commit\nodes\win2012r2>call npm test > node-gyp@3.6.1 test c:\workspace\nodegyp-test-commit\nodes\win2012r2
> tape test/test-*.js
TAP version 13
# build simple addon
ok 1 should be equal
ok 2 should end in ok
c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\test-addon.js:14
return execFileSync('node', ['-e', testCode], { cwd: __dirname }).toString()
^
TypeError: undefined is not a function
at runHello (c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\test-addon.js:14:10)
at c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\test-addon.js:43:19
at ChildProcess.exithandler (child_process.js:656:7)
at ChildProcess.emit (events.js:98:17)
at maybeClose (child_process.js:766:16)
at Process.ChildProcess._handle.onexit (child_process.js:833:5)
npm ERR! Test failed. See above for more details.
Build step 'Conditional steps (multiple)' marked build as failure
Notifying upstream pro

@refack

Copy link
Copy Markdown
Contributor

Ignore it's node@0.10https://ci.nodejs.org/job/nodegyp-test-commit/187/nodes=win2012r2/
As I said if you rebase onto master we bumped the version to 4 and don't test on node < 4

@refack

Copy link
Copy Markdown
Contributor

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

I need to modify this test to make it support node@0.10 ?

@refack

Copy link
Copy Markdown
Contributor

I need to modify this test to make it support node@0.10 ?

No. We stopped supporting node < 4 a week ago.

refack pushed a commit to refack/node-gyp that referenced this pull request Jun 8, 2017
* test: build simple addon in path with non-ascii characters
* test: add test-charmap.py
PR-URL: nodejs#1203
Reviewed-By: Refael Ackermann <refack@gmail.com>
@refack

Copy link
Copy Markdown
Contributor

Landed in d6139b5

@bnoordhuis

Copy link
Copy Markdown
Member

Kind of late to the party but I think there is a bug in the python script. It assumes that locale.getdefaultlocale()[1] is a string but that isn't always true:

$ env LC_ALL=C python -c 'import locale; print locale.getdefaultlocale()'
(None, None)

It makes the test fail (or rather: pass when it shouldn't) like this:

$ env LC_ALL=C node test/test-addon.js TAP version 13
# build simple addon
ok 1 should be equal
ok 2 should end in ok
ok 3 should be equal
# build simple addon in path with non-ascii characters
Traceback (most recent call last):
File "fixtures/test-charmap.py", line 19, in<module>
print main()
File "fixtures/test-charmap.py", line 8, in main
sys.setdefaultencoding(encoding)
TypeError: setdefaultencoding() argument 1 must be string, not None
ok 4 python console app can't encode non-ascii character. # SKIP1..4# tests 4# pass 4# ok

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

@bnoordhuis
I have not tested it when locale.getdefaultlocale()[1] value is None, and I do not know whether python can process non-ascii encoding string, So, in this case, I set default result is python can not process non-ascii encoding string, not need to run the test.

@refack

Copy link
Copy Markdown
Contributor

xml_string = unicode(xml_string, 'latin-1').encode(encoding)

default_encoding = locale.getdefaultlocale()[1]
if default_encoding.upper() != encoding.upper():

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should test default_encoding and default_encoding.upper() != encoding.upper():

@refack

Copy link
Copy Markdown
Contributor

@richardlaurichardlau mentioned this pull request Jul 20, 2018
2 tasks
duqingnian pushed a commit to duqingnian/gyp that referenced this pull request Apr 26, 2024
Bug: nodejs/node-gyp#1203
Change-Id: I30d71a2bb3d4b09e7bd9409c3c45c32bd182d736
duqingnian pushed a commit to duqingnian/gyp that referenced this pull request Apr 26, 2024
Bug: nodejs/node-gyp#1203
Change-Id: I30d71a2bb3d4b09e7bd9409c3c45c32bd182d736
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@lc-soft@gibfahn@refack@bnoordhuis@richardlau
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length \u003e 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

gyp: update xml string encoding conversion - #1203

Closed
lc-soft wants to merge 3 commits into
nodejs:masterfrom
lc-soft:fix_xml_encoding_bug
Closed

gyp: update xml string encoding conversion#1203
lc-soft wants to merge 3 commits into
nodejs:masterfrom
lc-soft:fix_xml_encoding_bug

Conversation

@lc-soft

@lc-softlc-soft commented May 20, 2017

Copy link
Copy Markdown
Contributor

My project depends on the node-sass, but it can not successfully install, so I tried using the npm rebuild node-sass --force command to build the node-sass on Windows 10. But it could not be built successfully, error message is: "node_version.h": No such file or directory

I guess this is the problem of compiling configuration, and I found the node-sass\build\binding.vcxproj file from the output information, so I opened it with the editor and found that the configuration item has garbled text:

qq 20170520130717

My username can not be displayed correctly, there seems to be a encoding conversion bug when writing to the binding.vcxproj file. I took some time to debug it, Eventually I found the problem out here: easy_xml.py#L120

qq 20170520130900

Since xml_string contains non-ascii characters, xml_string.encode() will fail and throw an exception, and then this string will be treated as latin-1 encoded string to convert, but my default locale character encoding is not latin-1, therefore, the binding.vcproj file is written with the wrong content.

After modification, the contents of the output file is correct.

qq 20170520130513

node-sass can be built successfully.

gyp info ok
Installed to F:\work\XXXXXX\node_modules\node-sass\vendor\win32-x64-48\binding.node
node-sass@4.5.3 F:\work\XXXXXX\node_modules\node-sass

@gibfahn

Copy link
Copy Markdown
Member

Maybe cc/ @joaocgreis@refack ?

Proposed change seems reasonable, but I don't know enough to review.

@refack

Copy link
Copy Markdown
Contributor

@lc-soft I'll have a look
Since it looks like a bug in GYP you should also open an issue at https://bugs.chromium.org/p/gyp/issues/list or even submit a patch

@refack

Copy link
Copy Markdown
Contributor

P.S. I keep forgetting to say...
Thank you very much for the contribution! 🥇

@lc-soft

lc-soft commented May 20, 2017

Copy link
Copy Markdown
ContributorAuthor

@refack I found these: #366#945#297.
This is old bug. but they did not submit a patch to upstream, this file has not been changed:
https://chromium.googlesource.com/external/gyp.git/+/master/pylib/gyp/easy_xml.py#105

@refack

Copy link
Copy Markdown
Contributor

I found these: #366#945#297, This is old bug. but they did not submit a patch to upstream, this file has not been changed:
https://chromium.googlesource.com/external/gyp.git/+/master/pylib/gyp/easy_xml.py#105

Yeah, for a long time upstream GYP was unresponsive so people didn't bother with submitting patches. They are trying to be better 🤷‍♂️ . Thank you for pointing me to those PRs!

I'm looking at your patch, we might land it here, and then try to push it upstream.

Anyway since AFAIK this is your first contribution, I'll give you some info on our review and landing process.
Ref: https://github.com/nodejs/node/blob/master/CONTRIBUTING.md#step-7-discuss-and-update
We keep the PR open for at least 48-72 hours so that anyone that might have some input to give will have get a chance. We will go over your code change, maybe ask a few question or request some changes. Then we run our automated test suite, and if everything is Ok we land the change.
In the case of node-gyp one of the package owners will need to decide when and how to release a new package version. Since this seems like semver-patch this stage will probably be quick.

@refackrefack self-assigned this May 20, 2017
Comment threadgyp/pylib/gyp/easy_xml.py Outdated
xml_string = unicode(xml_string, 'latin-1').encode(encoding)

default_encoding = locale.getdefaultlocale()[1]
if default_encoding != encoding.upper():

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not .upper or .lower both sides?
Also are you sure this won't throw?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, this is my negligence, I mistakenly thought it is capitalized, by this result:

image

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it makes sense to "normalize" both sides, since AFAIK there are no two Language Tags that differ only by case.

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

I can not run gyptest.py on Windows 10.

F:\repos\gyp>python gyptest.py test/win
[ 1/196] (msvs) test\win\generator-output-different-drive\gyptest-generator-output-different-drive.py failed 0.186s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 2e20748> ignored
[ 2/196] (msvs) test\win\gyptest-asm-files.py failed 0.184s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 2a53908> ignored
[ 3/196] (msvs) test\win\gyptest-cl-additional-include-dirs.py failed 0.195s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 29f3908> ignored
[ 4/196] (msvs) test\win\gyptest-cl-additional-options.py failed 0.185s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 2983a20> ignored
[ 6/196] (msvs) test\win\gyptest-cl-buffer-security-check.py failed 0.191s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 2a93978> ignored
[ 7/196] (msvs) test\win\gyptest-cl-calling-convention.py failed 0.199s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 29c3978> ignored
[ 8/196] (msvs) test\win\gyptest-cl-character-set.py failed 0.194s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 2ad3978> ignored

@refack

Copy link
Copy Markdown
Contributor

Which version of Visual Studio you got Installed? Cause if it's VS2017 Build Tools, gyptest can't find them...
You'll need to set an environment variable GYP_BUILD_TOOL to the full path of your msbuild.exe.

Also you could run node-gyp's tests by npm test

BTW: could you add a test case here (maybe add a copy of test\node_modules\hello_world in a unicode path and a call in in test\test-addon.js)

@lc-soft

lc-soft commented May 20, 2017

Copy link
Copy Markdown
ContributorAuthor

@refack OK, It has been running successfully.

F:\repos\gyp>set GYP_BUILD_TOOL=D:\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe
F:\repos\gyp>python gyptest.py test/win

But there are some errors:

[ 6/196] (msvs) test\win\gyptest-cl-buffer-security-check.py failed 3.843s
'D:\Microsoft' is not recognized as an internal or external command, operable program or batch file. Traceback (most recent call last):
File "test\win\gyptest-cl-buffer-security-check.py", line 42, in <module>
if 'security_cookie' not in GetDisassemblyOfMain('test_bsc_unset.exe'):
File "test\win\gyptest-cl-buffer-security-check.py", line 27, in GetDisassemblyOfMain
output = test.run_dumpbin('/disasm', full_path)
File "F:\repos\gyp\test\lib\TestGyp.py", line 813, in run_dumpbin
assert not proc.returncode
AssertionError
...
[ 18/196] (msvs) test\win\gyptest-cl-function-level-linking.py failed 2.896s
'D:\Microsoft' is not recognized as an internal or external command, operable program or batch file. Traceback (most recent call last):
File "test\win\gyptest-cl-function-level-linking.py", line 44, in <module>
should_exist=True)
File "test\win\gyptest-cl-function-level-linking.py", line 23, in CheckForSectionString
output = test.run_dumpbin('/headers', binary)
File "F:\repos\gyp\test\lib\TestGyp.py", line 813, in run_dumpbin
assert not proc.returncode
AssertionError
...

@lc-softlc-soft changed the title Improve xml string encoding conversiongyp: update xml string encoding conversionMay 20, 2017
@refack

Copy link
Copy Markdown
Contributor

Try set GYP_BUILD_TOOL="D:\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe"

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

@refack There will be more problems after using this method.

F:\repos\gyp>set GYP_BUILD_TOOL="D:\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe"
F:\repos\gyp>python gyptest.py test/win
[ 1/196] (msvs) test\win\generator-output-different-drive\gyptest-generator-output-different-drive.py failed 0.806s
STDOUT =========================================================================
STDERR =========================================================================
Exception trying to execute: ['F:\\repos\\gyp\\"D:\\Microsoft Visual Studio\\2017\\Community\\MSBuild\\15.0\\Bin\\MSBuild.exe"', 'prog.sln', '/t:Build', '/p:Configuration=Default']
Traceback (most recent call last):
File "test\win\generator-output-different-drive\gyptest-generator-output-different-drive.py", line 38, in <module>
test.build('prog.gyp', test.ALL, chdir=os.path.join(output_drive, 'output'))
File "F:\repos\gyp\test\lib\TestGyp.py", line 937, in build
return self.run(program=self.build_tool, **kw)
File "F:\repos\gyp\test\lib\TestGyp.py", line 333, in run
super(TestGypBase, self).run(*args, **kw)
File "F:\repos\gyp\test\lib\TestCommon.py", line 542, in run
apply(TestCmd.run, [self], kw)
File "F:\repos\gyp\test\lib\TestCmd.py", line 1224, in run
stdin=stdin)
File "F:\repos\gyp\test\lib\TestCommon.py", line 484, in start
raise e
WindowsError: [Error 5]
[ 2/196] (msvs) test\win\gyptest-asm-files.py failed 1.532s
STDOUT =========================================================================
STDERR =========================================================================
Exception trying to execute: ['F:\\repos\\gyp\\"D:\\Microsoft Visual Studio\\2017\\Community\\MSBuild\\15.0\\Bin\\MSBuild.exe"', 'asm-files.sln', '/t:Build', '/p:Configuration=Default']
Traceback (most recent call last):
File "test\win\gyptest-asm-files.py", line 24, in <module>
test.build('asm-files.gyp', test.ALL, chdir=CHDIR)
File "F:\repos\gyp\test\lib\TestGyp.py", line 937, in build
return self.run(program=self.build_tool, **kw)
File "F:\repos\gyp\test\lib\TestGyp.py", line 333, in run
super(TestGypBase, self).run(*args, **kw)
File "F:\repos\gyp\test\lib\TestCommon.py", line 542, in run
apply(TestCmd.run, [self], kw)
File "F:\repos\gyp\test\lib\TestCmd.py", line 1224, in run
stdin=stdin)
File "F:\repos\gyp\test\lib\TestCommon.py", line 484, in start
raise e
WindowsError: [Error 5]

@refack

Copy link
Copy Markdown
Contributor

Yeah, the test harness is very rusty.
I've pushed your patch to the Chromium code review system, and I've started a CI there - https://chromium-review.googlesource.com/c/509632/

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

@refack Good job! 👍

@refack

Copy link
Copy Markdown
Contributor

@refack

refack commented May 21, 2017

Copy link
Copy Markdown
Contributor

Did I click submit on a comment asking you to add a test?

Anyway, please do. I can suggest copying test\node_modules\hello_world to a path with non latin-1 characters in it, and adding a test case in "test\test-addon.js" building it.

Bonus points if you add a test also to https://github.com/refack/GYP/tree/node-gyp-1203 😉

@refackrefack left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, pending addition of a test.

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

OK, I will take a few days to add test.

Comment threadtest/test-addon.js Outdated
}
runCmd(t, [nodeGyp, 'configure', '-C', addonPath, '--loglevel=verbose',
'-nodedir=' + testNodeDir])
runCmd(t, [nodeGyp, 'build', '-C', addonPath, '--loglevel=verbose'])

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a clean up (try { fs.unlinkSync...)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack I have tried to use the rebuild command before, but there will be errors:

...
gyp verb clean removing "build" directory
gyp ERR! clean error
gyp ERR! stack Error: EPERM: operation not permitted, unlink 'F:\repos\GitHub\node-gyp\test\node_modules\hello_world\build\Release\hello.node'
...

how to solve this problem? a temporary solution is to use configure and build commands.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the reason hello.node can not be deleted is that it is occupied at the time of execution to require('hello_world'). so, solution is to create a new project (E.g:
hello_world_2), and rebuild it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO execFileSync is also completely fine.
OR you could create a hello_非英文字符 fixture.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean something like execFileSync(node, ['-e', "var x = require('hello_world'); if (x.hello() !== 'hello') process.exit(2)"])
Which is more sanitary anyway.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tried to use execFileSync before, but there have been some error messages, so I switched to the current solution.
OK, I will try to use execFileSync again.

@refack

Copy link
Copy Markdown
Contributor

Thank you!
One comment and I'll land this.

Comment threadtest/test-addon.js Outdated
t.plan(5)

configure(t).on('exit', function () {
var data, config, nodeDir, testNodeDir

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack I'am directly merged this test into the test build simple addon.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it works I'm +1
Another solution is to use execFileSync

Comment threadtest/test-addon.js Outdated
}
}

rebuild(t, testNodeDir).on('exit', function () {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Comment threadtest/test-addon.js Outdated
})

test('build simple addon in path with non-ascii characters', function (t) {
t.plan(3)

@lc-softlc-softMay 24, 2017

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack OK, this test has been able to run successfully.

F:\repos\GitHub\node-gyp>node ./test/test-addon.js
TAP version 13
# build simple addon
ok 1 should be equal
ok 2 should end in ok
ok 3 should be equal
# build simple addon in path with non-ascii characters
ok 4 should be equal
ok 5 should end in ok
ok 6 should be equal
1..6
# tests 6
# pass 6
# ok

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@refack

Copy link
Copy Markdown
Contributor

Comment threadtest/test-addon.js
var execFile = require('child_process').execFile
var path = require('path')
var fs = require('graceful-fs')
var child_process = require('child_process')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question to @nodejs/node-gyp
Can we use destructuring?

const{ execFileSync, execFile }=require('child_process')

Or do we test on pre ES6 versions?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the CI still tests 0.10 and 0.12.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not any more 😄

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

CI test did not pass.

gyp: c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\node_modules\hello_world\?????\include\node\common.gypi not found (cwd: c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\node_modules\hello_world) while reading includes of binding.gyp while trying to load binding.gyp
gyp ERR! configure error gyp ERR! stack Error: `gyp` failed with exit code: 1
gyp ERR! stack at ChildProcess.onCpExit (c:\workspace\nodegyp-test-commit\nodes\win2012r2\lib\configure.js:336:16)
gyp ERR! stack at emitTwo (events.js:87:13)
gyp ERR! stack at ChildProcess.emit (events.js:172:7)
gyp ERR! stack at Process.ChildProcess._handle.onexit (internal/child_process.js:211:12)
gyp ERR! System Windows_NT 6.3.9600
gyp ERR! command "c:\\workspace\\nodegyp-test-commit\\nodes\\win2012r2\\local_node\\node.exe" "c:\\workspace\\nodegyp-test-commit\\nodes\\win2012r2\\bin\\node-gyp.js" "rebuild" "-C" "c:\\workspace\\nodegyp-test-commit\\nodes\\win2012r2\\test\\node_modules\\hello_world" "--loglevel=verbose" "-nodedir=c:\\workspace\\nodegyp-test-commit\\nodes\\win2012r2\\test\\node_modules\\hello_world\\�英文字符"
gyp ERR! cwd c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\node_modules\hello_world
gyp ERR! node -v v4.8.3
gyp ERR! node-gyp -v v3.6.1
gyp ERR! not ok 

@refack

Copy link
Copy Markdown
Contributor

Comment threadtest/test-addon.js
if (!checkCharmapValid()) {
return t.skip('python console app can\'t encode non-ascii character.')
}

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack I added the character map check, if python app can not convert non-ASCII characters, then skip this test. console output like this:

TAP version 13
# build simple addon
ok 1 should be equal
ok 2 should end in ok
ok 3 should be equal
# build simple addon in path with non-ascii characters
node : Traceback (most recent call last):
At line:5 char:1
+ node ./test/test-addon
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (Traceback (most recent call last)::String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
File "test-charmap.py", line 20, in <module>
print main()
File "test-charmap.py", line 15, in main
print textmap[encoding]
File "C:\Python27\lib\encodings\cp1252.py", line 12, in encode
return codecs.charmap_encode(input,errors,encoding_table)
UnicodeEncodeError: 'charmap' codec can't encode character u'\u012b' in position 3: character maps to <undefined>
ok 4 python console app can't encode non-ascii character. # SKIP
1..4
# tests 4
# pass 4
# ok

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

@refack
What else do I need to do for this PR ?

Comment threadpackage.json Outdated
},
"scripts": {
"test": "tape test/test-*"
"test": "tape test/test-*.js"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather you move test-charmap.py to test/fixtures

@refack

Copy link
Copy Markdown
Contributor

Comment threadtest/test-addon.js
var execFile = require('child_process').execFile
var path = require('path')
var fs = require('graceful-fs')
var child_process = require('child_process')

@lc-softlc-softJun 8, 2017

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack
Do I need rename child_process to childProcess ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack

Copy link
Copy Markdown
Contributor

If you could rebase on master it will make the CI not test on node < 4

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

https://ci.nodejs.org/job/nodegyp-test-commit/187/nodes=win2012r2/console
execFileSync is undefined ?

c:\workspace\nodegyp-test-commit\nodes\win2012r2>call npm test > node-gyp@3.6.1 test c:\workspace\nodegyp-test-commit\nodes\win2012r2
> tape test/test-*.js
TAP version 13
# build simple addon
ok 1 should be equal
ok 2 should end in ok
c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\test-addon.js:14
return execFileSync('node', ['-e', testCode], { cwd: __dirname }).toString()
^
TypeError: undefined is not a function
at runHello (c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\test-addon.js:14:10)
at c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\test-addon.js:43:19
at ChildProcess.exithandler (child_process.js:656:7)
at ChildProcess.emit (events.js:98:17)
at maybeClose (child_process.js:766:16)
at Process.ChildProcess._handle.onexit (child_process.js:833:5)
npm ERR! Test failed. See above for more details.
Build step 'Conditional steps (multiple)' marked build as failure
Notifying upstream pro

@refack

Copy link
Copy Markdown
Contributor

Ignore it's node@0.10https://ci.nodejs.org/job/nodegyp-test-commit/187/nodes=win2012r2/
As I said if you rebase onto master we bumped the version to 4 and don't test on node < 4

@refack

Copy link
Copy Markdown
Contributor

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

I need to modify this test to make it support node@0.10 ?

@refack

Copy link
Copy Markdown
Contributor

I need to modify this test to make it support node@0.10 ?

No. We stopped supporting node < 4 a week ago.

refack pushed a commit to refack/node-gyp that referenced this pull request Jun 8, 2017
* test: build simple addon in path with non-ascii characters
* test: add test-charmap.py
PR-URL: nodejs#1203
Reviewed-By: Refael Ackermann <refack@gmail.com>
@refack

Copy link
Copy Markdown
Contributor

Landed in d6139b5

@bnoordhuis

Copy link
Copy Markdown
Member

Kind of late to the party but I think there is a bug in the python script. It assumes that locale.getdefaultlocale()[1] is a string but that isn't always true:

$ env LC_ALL=C python -c 'import locale; print locale.getdefaultlocale()'
(None, None)

It makes the test fail (or rather: pass when it shouldn't) like this:

$ env LC_ALL=C node test/test-addon.js TAP version 13
# build simple addon
ok 1 should be equal
ok 2 should end in ok
ok 3 should be equal
# build simple addon in path with non-ascii characters
Traceback (most recent call last):
File "fixtures/test-charmap.py", line 19, in<module>
print main()
File "fixtures/test-charmap.py", line 8, in main
sys.setdefaultencoding(encoding)
TypeError: setdefaultencoding() argument 1 must be string, not None
ok 4 python console app can't encode non-ascii character. # SKIP1..4# tests 4# pass 4# ok

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

@bnoordhuis
I have not tested it when locale.getdefaultlocale()[1] value is None, and I do not know whether python can process non-ascii encoding string, So, in this case, I set default result is python can not process non-ascii encoding string, not need to run the test.

@refack

Copy link
Copy Markdown
Contributor

xml_string = unicode(xml_string, 'latin-1').encode(encoding)

default_encoding = locale.getdefaultlocale()[1]
if default_encoding.upper() != encoding.upper():

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should test default_encoding and default_encoding.upper() != encoding.upper():

@refack

Copy link
Copy Markdown
Contributor

@richardlaurichardlau mentioned this pull request Jul 20, 2018
2 tasks
duqingnian pushed a commit to duqingnian/gyp that referenced this pull request Apr 26, 2024
Bug: nodejs/node-gyp#1203
Change-Id: I30d71a2bb3d4b09e7bd9409c3c45c32bd182d736
duqingnian pushed a commit to duqingnian/gyp that referenced this pull request Apr 26, 2024
Bug: nodejs/node-gyp#1203
Change-Id: I30d71a2bb3d4b09e7bd9409c3c45c32bd182d736
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@lc-soft@gibfahn@refack@bnoordhuis@richardlau
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

gyp: update xml string encoding conversion - #1203

Closed
lc-soft wants to merge 3 commits into
nodejs:masterfrom
lc-soft:fix_xml_encoding_bug
Closed

gyp: update xml string encoding conversion#1203
lc-soft wants to merge 3 commits into
nodejs:masterfrom
lc-soft:fix_xml_encoding_bug

Conversation

@lc-soft

@lc-softlc-soft commented May 20, 2017

Copy link
Copy Markdown
Contributor

My project depends on the node-sass, but it can not successfully install, so I tried using the npm rebuild node-sass --force command to build the node-sass on Windows 10. But it could not be built successfully, error message is: "node_version.h": No such file or directory

I guess this is the problem of compiling configuration, and I found the node-sass\build\binding.vcxproj file from the output information, so I opened it with the editor and found that the configuration item has garbled text:

qq 20170520130717

My username can not be displayed correctly, there seems to be a encoding conversion bug when writing to the binding.vcxproj file. I took some time to debug it, Eventually I found the problem out here: easy_xml.py#L120

qq 20170520130900

Since xml_string contains non-ascii characters, xml_string.encode() will fail and throw an exception, and then this string will be treated as latin-1 encoded string to convert, but my default locale character encoding is not latin-1, therefore, the binding.vcproj file is written with the wrong content.

After modification, the contents of the output file is correct.

qq 20170520130513

node-sass can be built successfully.

gyp info ok
Installed to F:\work\XXXXXX\node_modules\node-sass\vendor\win32-x64-48\binding.node
node-sass@4.5.3 F:\work\XXXXXX\node_modules\node-sass

@gibfahn

Copy link
Copy Markdown
Member

Maybe cc/ @joaocgreis@refack ?

Proposed change seems reasonable, but I don't know enough to review.

@refack

Copy link
Copy Markdown
Contributor

@lc-soft I'll have a look
Since it looks like a bug in GYP you should also open an issue at https://bugs.chromium.org/p/gyp/issues/list or even submit a patch

@refack

Copy link
Copy Markdown
Contributor

P.S. I keep forgetting to say...
Thank you very much for the contribution! 🥇

@lc-soft

lc-soft commented May 20, 2017

Copy link
Copy Markdown
ContributorAuthor

@refack I found these: #366#945#297.
This is old bug. but they did not submit a patch to upstream, this file has not been changed:
https://chromium.googlesource.com/external/gyp.git/+/master/pylib/gyp/easy_xml.py#105

@refack

Copy link
Copy Markdown
Contributor

I found these: #366#945#297, This is old bug. but they did not submit a patch to upstream, this file has not been changed:
https://chromium.googlesource.com/external/gyp.git/+/master/pylib/gyp/easy_xml.py#105

Yeah, for a long time upstream GYP was unresponsive so people didn't bother with submitting patches. They are trying to be better 🤷‍♂️ . Thank you for pointing me to those PRs!

I'm looking at your patch, we might land it here, and then try to push it upstream.

Anyway since AFAIK this is your first contribution, I'll give you some info on our review and landing process.
Ref: https://github.com/nodejs/node/blob/master/CONTRIBUTING.md#step-7-discuss-and-update
We keep the PR open for at least 48-72 hours so that anyone that might have some input to give will have get a chance. We will go over your code change, maybe ask a few question or request some changes. Then we run our automated test suite, and if everything is Ok we land the change.
In the case of node-gyp one of the package owners will need to decide when and how to release a new package version. Since this seems like semver-patch this stage will probably be quick.

@refackrefack self-assigned this May 20, 2017
Comment threadgyp/pylib/gyp/easy_xml.py Outdated
xml_string = unicode(xml_string, 'latin-1').encode(encoding)

default_encoding = locale.getdefaultlocale()[1]
if default_encoding != encoding.upper():

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not .upper or .lower both sides?
Also are you sure this won't throw?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, this is my negligence, I mistakenly thought it is capitalized, by this result:

image

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it makes sense to "normalize" both sides, since AFAIK there are no two Language Tags that differ only by case.

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

I can not run gyptest.py on Windows 10.

F:\repos\gyp>python gyptest.py test/win
[ 1/196] (msvs) test\win\generator-output-different-drive\gyptest-generator-output-different-drive.py failed 0.186s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 2e20748> ignored
[ 2/196] (msvs) test\win\gyptest-asm-files.py failed 0.184s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 2a53908> ignored
[ 3/196] (msvs) test\win\gyptest-cl-additional-include-dirs.py failed 0.195s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 29f3908> ignored
[ 4/196] (msvs) test\win\gyptest-cl-additional-options.py failed 0.185s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 2983a20> ignored
[ 6/196] (msvs) test\win\gyptest-cl-buffer-security-check.py failed 0.191s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 2a93978> ignored
[ 7/196] (msvs) test\win\gyptest-cl-calling-convention.py failed 0.199s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 29c3978> ignored
[ 8/196] (msvs) test\win\gyptest-cl-character-set.py failed 0.194s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 2ad3978> ignored

@refack

Copy link
Copy Markdown
Contributor

Which version of Visual Studio you got Installed? Cause if it's VS2017 Build Tools, gyptest can't find them...
You'll need to set an environment variable GYP_BUILD_TOOL to the full path of your msbuild.exe.

Also you could run node-gyp's tests by npm test

BTW: could you add a test case here (maybe add a copy of test\node_modules\hello_world in a unicode path and a call in in test\test-addon.js)

@lc-soft

lc-soft commented May 20, 2017

Copy link
Copy Markdown
ContributorAuthor

@refack OK, It has been running successfully.

F:\repos\gyp>set GYP_BUILD_TOOL=D:\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe
F:\repos\gyp>python gyptest.py test/win

But there are some errors:

[ 6/196] (msvs) test\win\gyptest-cl-buffer-security-check.py failed 3.843s
'D:\Microsoft' is not recognized as an internal or external command, operable program or batch file. Traceback (most recent call last):
File "test\win\gyptest-cl-buffer-security-check.py", line 42, in <module>
if 'security_cookie' not in GetDisassemblyOfMain('test_bsc_unset.exe'):
File "test\win\gyptest-cl-buffer-security-check.py", line 27, in GetDisassemblyOfMain
output = test.run_dumpbin('/disasm', full_path)
File "F:\repos\gyp\test\lib\TestGyp.py", line 813, in run_dumpbin
assert not proc.returncode
AssertionError
...
[ 18/196] (msvs) test\win\gyptest-cl-function-level-linking.py failed 2.896s
'D:\Microsoft' is not recognized as an internal or external command, operable program or batch file. Traceback (most recent call last):
File "test\win\gyptest-cl-function-level-linking.py", line 44, in <module>
should_exist=True)
File "test\win\gyptest-cl-function-level-linking.py", line 23, in CheckForSectionString
output = test.run_dumpbin('/headers', binary)
File "F:\repos\gyp\test\lib\TestGyp.py", line 813, in run_dumpbin
assert not proc.returncode
AssertionError
...

@lc-softlc-soft changed the title Improve xml string encoding conversiongyp: update xml string encoding conversionMay 20, 2017
@refack

Copy link
Copy Markdown
Contributor

Try set GYP_BUILD_TOOL="D:\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe"

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

@refack There will be more problems after using this method.

F:\repos\gyp>set GYP_BUILD_TOOL="D:\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe"
F:\repos\gyp>python gyptest.py test/win
[ 1/196] (msvs) test\win\generator-output-different-drive\gyptest-generator-output-different-drive.py failed 0.806s
STDOUT =========================================================================
STDERR =========================================================================
Exception trying to execute: ['F:\\repos\\gyp\\"D:\\Microsoft Visual Studio\\2017\\Community\\MSBuild\\15.0\\Bin\\MSBuild.exe"', 'prog.sln', '/t:Build', '/p:Configuration=Default']
Traceback (most recent call last):
File "test\win\generator-output-different-drive\gyptest-generator-output-different-drive.py", line 38, in <module>
test.build('prog.gyp', test.ALL, chdir=os.path.join(output_drive, 'output'))
File "F:\repos\gyp\test\lib\TestGyp.py", line 937, in build
return self.run(program=self.build_tool, **kw)
File "F:\repos\gyp\test\lib\TestGyp.py", line 333, in run
super(TestGypBase, self).run(*args, **kw)
File "F:\repos\gyp\test\lib\TestCommon.py", line 542, in run
apply(TestCmd.run, [self], kw)
File "F:\repos\gyp\test\lib\TestCmd.py", line 1224, in run
stdin=stdin)
File "F:\repos\gyp\test\lib\TestCommon.py", line 484, in start
raise e
WindowsError: [Error 5]
[ 2/196] (msvs) test\win\gyptest-asm-files.py failed 1.532s
STDOUT =========================================================================
STDERR =========================================================================
Exception trying to execute: ['F:\\repos\\gyp\\"D:\\Microsoft Visual Studio\\2017\\Community\\MSBuild\\15.0\\Bin\\MSBuild.exe"', 'asm-files.sln', '/t:Build', '/p:Configuration=Default']
Traceback (most recent call last):
File "test\win\gyptest-asm-files.py", line 24, in <module>
test.build('asm-files.gyp', test.ALL, chdir=CHDIR)
File "F:\repos\gyp\test\lib\TestGyp.py", line 937, in build
return self.run(program=self.build_tool, **kw)
File "F:\repos\gyp\test\lib\TestGyp.py", line 333, in run
super(TestGypBase, self).run(*args, **kw)
File "F:\repos\gyp\test\lib\TestCommon.py", line 542, in run
apply(TestCmd.run, [self], kw)
File "F:\repos\gyp\test\lib\TestCmd.py", line 1224, in run
stdin=stdin)
File "F:\repos\gyp\test\lib\TestCommon.py", line 484, in start
raise e
WindowsError: [Error 5]

@refack

Copy link
Copy Markdown
Contributor

Yeah, the test harness is very rusty.
I've pushed your patch to the Chromium code review system, and I've started a CI there - https://chromium-review.googlesource.com/c/509632/

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

@refack Good job! 👍

@refack

Copy link
Copy Markdown
Contributor

@refack

refack commented May 21, 2017

Copy link
Copy Markdown
Contributor

Did I click submit on a comment asking you to add a test?

Anyway, please do. I can suggest copying test\node_modules\hello_world to a path with non latin-1 characters in it, and adding a test case in "test\test-addon.js" building it.

Bonus points if you add a test also to https://github.com/refack/GYP/tree/node-gyp-1203 😉

@refackrefack left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, pending addition of a test.

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

OK, I will take a few days to add test.

Comment threadtest/test-addon.js Outdated
}
runCmd(t, [nodeGyp, 'configure', '-C', addonPath, '--loglevel=verbose',
'-nodedir=' + testNodeDir])
runCmd(t, [nodeGyp, 'build', '-C', addonPath, '--loglevel=verbose'])

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a clean up (try { fs.unlinkSync...)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack I have tried to use the rebuild command before, but there will be errors:

...
gyp verb clean removing "build" directory
gyp ERR! clean error
gyp ERR! stack Error: EPERM: operation not permitted, unlink 'F:\repos\GitHub\node-gyp\test\node_modules\hello_world\build\Release\hello.node'
...

how to solve this problem? a temporary solution is to use configure and build commands.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the reason hello.node can not be deleted is that it is occupied at the time of execution to require('hello_world'). so, solution is to create a new project (E.g:
hello_world_2), and rebuild it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO execFileSync is also completely fine.
OR you could create a hello_非英文字符 fixture.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean something like execFileSync(node, ['-e', "var x = require('hello_world'); if (x.hello() !== 'hello') process.exit(2)"])
Which is more sanitary anyway.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tried to use execFileSync before, but there have been some error messages, so I switched to the current solution.
OK, I will try to use execFileSync again.

@refack

Copy link
Copy Markdown
Contributor

Thank you!
One comment and I'll land this.

Comment threadtest/test-addon.js Outdated
t.plan(5)

configure(t).on('exit', function () {
var data, config, nodeDir, testNodeDir

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack I'am directly merged this test into the test build simple addon.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it works I'm +1
Another solution is to use execFileSync

Comment threadtest/test-addon.js Outdated
}
}

rebuild(t, testNodeDir).on('exit', function () {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Comment threadtest/test-addon.js Outdated
})

test('build simple addon in path with non-ascii characters', function (t) {
t.plan(3)

@lc-softlc-softMay 24, 2017

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack OK, this test has been able to run successfully.

F:\repos\GitHub\node-gyp>node ./test/test-addon.js
TAP version 13
# build simple addon
ok 1 should be equal
ok 2 should end in ok
ok 3 should be equal
# build simple addon in path with non-ascii characters
ok 4 should be equal
ok 5 should end in ok
ok 6 should be equal
1..6
# tests 6
# pass 6
# ok

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@refack

Copy link
Copy Markdown
Contributor

Comment threadtest/test-addon.js
var execFile = require('child_process').execFile
var path = require('path')
var fs = require('graceful-fs')
var child_process = require('child_process')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question to @nodejs/node-gyp
Can we use destructuring?

const{ execFileSync, execFile }=require('child_process')

Or do we test on pre ES6 versions?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the CI still tests 0.10 and 0.12.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not any more 😄

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

CI test did not pass.

gyp: c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\node_modules\hello_world\?????\include\node\common.gypi not found (cwd: c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\node_modules\hello_world) while reading includes of binding.gyp while trying to load binding.gyp
gyp ERR! configure error gyp ERR! stack Error: `gyp` failed with exit code: 1
gyp ERR! stack at ChildProcess.onCpExit (c:\workspace\nodegyp-test-commit\nodes\win2012r2\lib\configure.js:336:16)
gyp ERR! stack at emitTwo (events.js:87:13)
gyp ERR! stack at ChildProcess.emit (events.js:172:7)
gyp ERR! stack at Process.ChildProcess._handle.onexit (internal/child_process.js:211:12)
gyp ERR! System Windows_NT 6.3.9600
gyp ERR! command "c:\\workspace\\nodegyp-test-commit\\nodes\\win2012r2\\local_node\\node.exe" "c:\\workspace\\nodegyp-test-commit\\nodes\\win2012r2\\bin\\node-gyp.js" "rebuild" "-C" "c:\\workspace\\nodegyp-test-commit\\nodes\\win2012r2\\test\\node_modules\\hello_world" "--loglevel=verbose" "-nodedir=c:\\workspace\\nodegyp-test-commit\\nodes\\win2012r2\\test\\node_modules\\hello_world\\�英文字符"
gyp ERR! cwd c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\node_modules\hello_world
gyp ERR! node -v v4.8.3
gyp ERR! node-gyp -v v3.6.1
gyp ERR! not ok 

@refack

Copy link
Copy Markdown
Contributor

Comment threadtest/test-addon.js
if (!checkCharmapValid()) {
return t.skip('python console app can\'t encode non-ascii character.')
}

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack I added the character map check, if python app can not convert non-ASCII characters, then skip this test. console output like this:

TAP version 13
# build simple addon
ok 1 should be equal
ok 2 should end in ok
ok 3 should be equal
# build simple addon in path with non-ascii characters
node : Traceback (most recent call last):
At line:5 char:1
+ node ./test/test-addon
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (Traceback (most recent call last)::String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
File "test-charmap.py", line 20, in <module>
print main()
File "test-charmap.py", line 15, in main
print textmap[encoding]
File "C:\Python27\lib\encodings\cp1252.py", line 12, in encode
return codecs.charmap_encode(input,errors,encoding_table)
UnicodeEncodeError: 'charmap' codec can't encode character u'\u012b' in position 3: character maps to <undefined>
ok 4 python console app can't encode non-ascii character. # SKIP
1..4
# tests 4
# pass 4
# ok

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

@refack
What else do I need to do for this PR ?

Comment threadpackage.json Outdated
},
"scripts": {
"test": "tape test/test-*"
"test": "tape test/test-*.js"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather you move test-charmap.py to test/fixtures

@refack

Copy link
Copy Markdown
Contributor

Comment threadtest/test-addon.js
var execFile = require('child_process').execFile
var path = require('path')
var fs = require('graceful-fs')
var child_process = require('child_process')

@lc-softlc-softJun 8, 2017

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack
Do I need rename child_process to childProcess ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack

Copy link
Copy Markdown
Contributor

If you could rebase on master it will make the CI not test on node < 4

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

https://ci.nodejs.org/job/nodegyp-test-commit/187/nodes=win2012r2/console
execFileSync is undefined ?

c:\workspace\nodegyp-test-commit\nodes\win2012r2>call npm test > node-gyp@3.6.1 test c:\workspace\nodegyp-test-commit\nodes\win2012r2
> tape test/test-*.js
TAP version 13
# build simple addon
ok 1 should be equal
ok 2 should end in ok
c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\test-addon.js:14
return execFileSync('node', ['-e', testCode], { cwd: __dirname }).toString()
^
TypeError: undefined is not a function
at runHello (c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\test-addon.js:14:10)
at c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\test-addon.js:43:19
at ChildProcess.exithandler (child_process.js:656:7)
at ChildProcess.emit (events.js:98:17)
at maybeClose (child_process.js:766:16)
at Process.ChildProcess._handle.onexit (child_process.js:833:5)
npm ERR! Test failed. See above for more details.
Build step 'Conditional steps (multiple)' marked build as failure
Notifying upstream pro

@refack

Copy link
Copy Markdown
Contributor

Ignore it's node@0.10https://ci.nodejs.org/job/nodegyp-test-commit/187/nodes=win2012r2/
As I said if you rebase onto master we bumped the version to 4 and don't test on node < 4

@refack

Copy link
Copy Markdown
Contributor

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

I need to modify this test to make it support node@0.10 ?

@refack

Copy link
Copy Markdown
Contributor

I need to modify this test to make it support node@0.10 ?

No. We stopped supporting node < 4 a week ago.

refack pushed a commit to refack/node-gyp that referenced this pull request Jun 8, 2017
* test: build simple addon in path with non-ascii characters
* test: add test-charmap.py
PR-URL: nodejs#1203
Reviewed-By: Refael Ackermann <refack@gmail.com>
@refack

Copy link
Copy Markdown
Contributor

Landed in d6139b5

@bnoordhuis

Copy link
Copy Markdown
Member

Kind of late to the party but I think there is a bug in the python script. It assumes that locale.getdefaultlocale()[1] is a string but that isn't always true:

$ env LC_ALL=C python -c 'import locale; print locale.getdefaultlocale()'
(None, None)

It makes the test fail (or rather: pass when it shouldn't) like this:

$ env LC_ALL=C node test/test-addon.js TAP version 13
# build simple addon
ok 1 should be equal
ok 2 should end in ok
ok 3 should be equal
# build simple addon in path with non-ascii characters
Traceback (most recent call last):
File "fixtures/test-charmap.py", line 19, in<module>
print main()
File "fixtures/test-charmap.py", line 8, in main
sys.setdefaultencoding(encoding)
TypeError: setdefaultencoding() argument 1 must be string, not None
ok 4 python console app can't encode non-ascii character. # SKIP1..4# tests 4# pass 4# ok

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

@bnoordhuis
I have not tested it when locale.getdefaultlocale()[1] value is None, and I do not know whether python can process non-ascii encoding string, So, in this case, I set default result is python can not process non-ascii encoding string, not need to run the test.

@refack

Copy link
Copy Markdown
Contributor

xml_string = unicode(xml_string, 'latin-1').encode(encoding)

default_encoding = locale.getdefaultlocale()[1]
if default_encoding.upper() != encoding.upper():

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should test default_encoding and default_encoding.upper() != encoding.upper():

@refack

Copy link
Copy Markdown
Contributor

@richardlaurichardlau mentioned this pull request Jul 20, 2018
2 tasks
duqingnian pushed a commit to duqingnian/gyp that referenced this pull request Apr 26, 2024
Bug: nodejs/node-gyp#1203
Change-Id: I30d71a2bb3d4b09e7bd9409c3c45c32bd182d736
duqingnian pushed a commit to duqingnian/gyp that referenced this pull request Apr 26, 2024
Bug: nodejs/node-gyp#1203
Change-Id: I30d71a2bb3d4b09e7bd9409c3c45c32bd182d736
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@lc-soft@gibfahn@refack@bnoordhuis@richardlau
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

gyp: update xml string encoding conversion - #1203

Closed
lc-soft wants to merge 3 commits into
nodejs:masterfrom
lc-soft:fix_xml_encoding_bug
Closed

gyp: update xml string encoding conversion#1203
lc-soft wants to merge 3 commits into
nodejs:masterfrom
lc-soft:fix_xml_encoding_bug

Conversation

@lc-soft

@lc-softlc-soft commented May 20, 2017

Copy link
Copy Markdown
Contributor

My project depends on the node-sass, but it can not successfully install, so I tried using the npm rebuild node-sass --force command to build the node-sass on Windows 10. But it could not be built successfully, error message is: "node_version.h": No such file or directory

I guess this is the problem of compiling configuration, and I found the node-sass\build\binding.vcxproj file from the output information, so I opened it with the editor and found that the configuration item has garbled text:

qq 20170520130717

My username can not be displayed correctly, there seems to be a encoding conversion bug when writing to the binding.vcxproj file. I took some time to debug it, Eventually I found the problem out here: easy_xml.py#L120

qq 20170520130900

Since xml_string contains non-ascii characters, xml_string.encode() will fail and throw an exception, and then this string will be treated as latin-1 encoded string to convert, but my default locale character encoding is not latin-1, therefore, the binding.vcproj file is written with the wrong content.

After modification, the contents of the output file is correct.

qq 20170520130513

node-sass can be built successfully.

gyp info ok
Installed to F:\work\XXXXXX\node_modules\node-sass\vendor\win32-x64-48\binding.node
node-sass@4.5.3 F:\work\XXXXXX\node_modules\node-sass

@gibfahn

Copy link
Copy Markdown
Member

Maybe cc/ @joaocgreis@refack ?

Proposed change seems reasonable, but I don't know enough to review.

@refack

Copy link
Copy Markdown
Contributor

@lc-soft I'll have a look
Since it looks like a bug in GYP you should also open an issue at https://bugs.chromium.org/p/gyp/issues/list or even submit a patch

@refack

Copy link
Copy Markdown
Contributor

P.S. I keep forgetting to say...
Thank you very much for the contribution! 🥇

@lc-soft

lc-soft commented May 20, 2017

Copy link
Copy Markdown
ContributorAuthor

@refack I found these: #366#945#297.
This is old bug. but they did not submit a patch to upstream, this file has not been changed:
https://chromium.googlesource.com/external/gyp.git/+/master/pylib/gyp/easy_xml.py#105

@refack

Copy link
Copy Markdown
Contributor

I found these: #366#945#297, This is old bug. but they did not submit a patch to upstream, this file has not been changed:
https://chromium.googlesource.com/external/gyp.git/+/master/pylib/gyp/easy_xml.py#105

Yeah, for a long time upstream GYP was unresponsive so people didn't bother with submitting patches. They are trying to be better 🤷‍♂️ . Thank you for pointing me to those PRs!

I'm looking at your patch, we might land it here, and then try to push it upstream.

Anyway since AFAIK this is your first contribution, I'll give you some info on our review and landing process.
Ref: https://github.com/nodejs/node/blob/master/CONTRIBUTING.md#step-7-discuss-and-update
We keep the PR open for at least 48-72 hours so that anyone that might have some input to give will have get a chance. We will go over your code change, maybe ask a few question or request some changes. Then we run our automated test suite, and if everything is Ok we land the change.
In the case of node-gyp one of the package owners will need to decide when and how to release a new package version. Since this seems like semver-patch this stage will probably be quick.

@refackrefack self-assigned this May 20, 2017
Comment threadgyp/pylib/gyp/easy_xml.py Outdated
xml_string = unicode(xml_string, 'latin-1').encode(encoding)

default_encoding = locale.getdefaultlocale()[1]
if default_encoding != encoding.upper():

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not .upper or .lower both sides?
Also are you sure this won't throw?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, this is my negligence, I mistakenly thought it is capitalized, by this result:

image

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it makes sense to "normalize" both sides, since AFAIK there are no two Language Tags that differ only by case.

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

I can not run gyptest.py on Windows 10.

F:\repos\gyp>python gyptest.py test/win
[ 1/196] (msvs) test\win\generator-output-different-drive\gyptest-generator-output-different-drive.py failed 0.186s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 2e20748> ignored
[ 2/196] (msvs) test\win\gyptest-asm-files.py failed 0.184s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 2a53908> ignored
[ 3/196] (msvs) test\win\gyptest-cl-additional-include-dirs.py failed 0.195s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 29f3908> ignored
[ 4/196] (msvs) test\win\gyptest-cl-additional-options.py failed 0.185s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 2983a20> ignored
[ 6/196] (msvs) test\win\gyptest-cl-buffer-security-check.py failed 0.191s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 2a93978> ignored
[ 7/196] (msvs) test\win\gyptest-cl-calling-convention.py failed 0.199s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 29c3978> ignored
[ 8/196] (msvs) test\win\gyptest-cl-character-set.py failed 0.194s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 2ad3978> ignored

@refack

Copy link
Copy Markdown
Contributor

Which version of Visual Studio you got Installed? Cause if it's VS2017 Build Tools, gyptest can't find them...
You'll need to set an environment variable GYP_BUILD_TOOL to the full path of your msbuild.exe.

Also you could run node-gyp's tests by npm test

BTW: could you add a test case here (maybe add a copy of test\node_modules\hello_world in a unicode path and a call in in test\test-addon.js)

@lc-soft

lc-soft commented May 20, 2017

Copy link
Copy Markdown
ContributorAuthor

@refack OK, It has been running successfully.

F:\repos\gyp>set GYP_BUILD_TOOL=D:\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe
F:\repos\gyp>python gyptest.py test/win

But there are some errors:

[ 6/196] (msvs) test\win\gyptest-cl-buffer-security-check.py failed 3.843s
'D:\Microsoft' is not recognized as an internal or external command, operable program or batch file. Traceback (most recent call last):
File "test\win\gyptest-cl-buffer-security-check.py", line 42, in <module>
if 'security_cookie' not in GetDisassemblyOfMain('test_bsc_unset.exe'):
File "test\win\gyptest-cl-buffer-security-check.py", line 27, in GetDisassemblyOfMain
output = test.run_dumpbin('/disasm', full_path)
File "F:\repos\gyp\test\lib\TestGyp.py", line 813, in run_dumpbin
assert not proc.returncode
AssertionError
...
[ 18/196] (msvs) test\win\gyptest-cl-function-level-linking.py failed 2.896s
'D:\Microsoft' is not recognized as an internal or external command, operable program or batch file. Traceback (most recent call last):
File "test\win\gyptest-cl-function-level-linking.py", line 44, in <module>
should_exist=True)
File "test\win\gyptest-cl-function-level-linking.py", line 23, in CheckForSectionString
output = test.run_dumpbin('/headers', binary)
File "F:\repos\gyp\test\lib\TestGyp.py", line 813, in run_dumpbin
assert not proc.returncode
AssertionError
...

@lc-softlc-soft changed the title Improve xml string encoding conversiongyp: update xml string encoding conversionMay 20, 2017
@refack

Copy link
Copy Markdown
Contributor

Try set GYP_BUILD_TOOL="D:\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe"

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

@refack There will be more problems after using this method.

F:\repos\gyp>set GYP_BUILD_TOOL="D:\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe"
F:\repos\gyp>python gyptest.py test/win
[ 1/196] (msvs) test\win\generator-output-different-drive\gyptest-generator-output-different-drive.py failed 0.806s
STDOUT =========================================================================
STDERR =========================================================================
Exception trying to execute: ['F:\\repos\\gyp\\"D:\\Microsoft Visual Studio\\2017\\Community\\MSBuild\\15.0\\Bin\\MSBuild.exe"', 'prog.sln', '/t:Build', '/p:Configuration=Default']
Traceback (most recent call last):
File "test\win\generator-output-different-drive\gyptest-generator-output-different-drive.py", line 38, in <module>
test.build('prog.gyp', test.ALL, chdir=os.path.join(output_drive, 'output'))
File "F:\repos\gyp\test\lib\TestGyp.py", line 937, in build
return self.run(program=self.build_tool, **kw)
File "F:\repos\gyp\test\lib\TestGyp.py", line 333, in run
super(TestGypBase, self).run(*args, **kw)
File "F:\repos\gyp\test\lib\TestCommon.py", line 542, in run
apply(TestCmd.run, [self], kw)
File "F:\repos\gyp\test\lib\TestCmd.py", line 1224, in run
stdin=stdin)
File "F:\repos\gyp\test\lib\TestCommon.py", line 484, in start
raise e
WindowsError: [Error 5]
[ 2/196] (msvs) test\win\gyptest-asm-files.py failed 1.532s
STDOUT =========================================================================
STDERR =========================================================================
Exception trying to execute: ['F:\\repos\\gyp\\"D:\\Microsoft Visual Studio\\2017\\Community\\MSBuild\\15.0\\Bin\\MSBuild.exe"', 'asm-files.sln', '/t:Build', '/p:Configuration=Default']
Traceback (most recent call last):
File "test\win\gyptest-asm-files.py", line 24, in <module>
test.build('asm-files.gyp', test.ALL, chdir=CHDIR)
File "F:\repos\gyp\test\lib\TestGyp.py", line 937, in build
return self.run(program=self.build_tool, **kw)
File "F:\repos\gyp\test\lib\TestGyp.py", line 333, in run
super(TestGypBase, self).run(*args, **kw)
File "F:\repos\gyp\test\lib\TestCommon.py", line 542, in run
apply(TestCmd.run, [self], kw)
File "F:\repos\gyp\test\lib\TestCmd.py", line 1224, in run
stdin=stdin)
File "F:\repos\gyp\test\lib\TestCommon.py", line 484, in start
raise e
WindowsError: [Error 5]

@refack

Copy link
Copy Markdown
Contributor

Yeah, the test harness is very rusty.
I've pushed your patch to the Chromium code review system, and I've started a CI there - https://chromium-review.googlesource.com/c/509632/

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

@refack Good job! 👍

@refack

Copy link
Copy Markdown
Contributor

@refack

refack commented May 21, 2017

Copy link
Copy Markdown
Contributor

Did I click submit on a comment asking you to add a test?

Anyway, please do. I can suggest copying test\node_modules\hello_world to a path with non latin-1 characters in it, and adding a test case in "test\test-addon.js" building it.

Bonus points if you add a test also to https://github.com/refack/GYP/tree/node-gyp-1203 😉

@refackrefack left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, pending addition of a test.

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

OK, I will take a few days to add test.

Comment threadtest/test-addon.js Outdated
}
runCmd(t, [nodeGyp, 'configure', '-C', addonPath, '--loglevel=verbose',
'-nodedir=' + testNodeDir])
runCmd(t, [nodeGyp, 'build', '-C', addonPath, '--loglevel=verbose'])

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a clean up (try { fs.unlinkSync...)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack I have tried to use the rebuild command before, but there will be errors:

...
gyp verb clean removing "build" directory
gyp ERR! clean error
gyp ERR! stack Error: EPERM: operation not permitted, unlink 'F:\repos\GitHub\node-gyp\test\node_modules\hello_world\build\Release\hello.node'
...

how to solve this problem? a temporary solution is to use configure and build commands.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the reason hello.node can not be deleted is that it is occupied at the time of execution to require('hello_world'). so, solution is to create a new project (E.g:
hello_world_2), and rebuild it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO execFileSync is also completely fine.
OR you could create a hello_非英文字符 fixture.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean something like execFileSync(node, ['-e', "var x = require('hello_world'); if (x.hello() !== 'hello') process.exit(2)"])
Which is more sanitary anyway.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tried to use execFileSync before, but there have been some error messages, so I switched to the current solution.
OK, I will try to use execFileSync again.

@refack

Copy link
Copy Markdown
Contributor

Thank you!
One comment and I'll land this.

Comment threadtest/test-addon.js Outdated
t.plan(5)

configure(t).on('exit', function () {
var data, config, nodeDir, testNodeDir

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack I'am directly merged this test into the test build simple addon.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it works I'm +1
Another solution is to use execFileSync

Comment threadtest/test-addon.js Outdated
}
}

rebuild(t, testNodeDir).on('exit', function () {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Comment threadtest/test-addon.js Outdated
})

test('build simple addon in path with non-ascii characters', function (t) {
t.plan(3)

@lc-softlc-softMay 24, 2017

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack OK, this test has been able to run successfully.

F:\repos\GitHub\node-gyp>node ./test/test-addon.js
TAP version 13
# build simple addon
ok 1 should be equal
ok 2 should end in ok
ok 3 should be equal
# build simple addon in path with non-ascii characters
ok 4 should be equal
ok 5 should end in ok
ok 6 should be equal
1..6
# tests 6
# pass 6
# ok

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@refack

Copy link
Copy Markdown
Contributor

Comment threadtest/test-addon.js
var execFile = require('child_process').execFile
var path = require('path')
var fs = require('graceful-fs')
var child_process = require('child_process')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question to @nodejs/node-gyp
Can we use destructuring?

const{ execFileSync, execFile }=require('child_process')

Or do we test on pre ES6 versions?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the CI still tests 0.10 and 0.12.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not any more 😄

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

CI test did not pass.

gyp: c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\node_modules\hello_world\?????\include\node\common.gypi not found (cwd: c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\node_modules\hello_world) while reading includes of binding.gyp while trying to load binding.gyp
gyp ERR! configure error gyp ERR! stack Error: `gyp` failed with exit code: 1
gyp ERR! stack at ChildProcess.onCpExit (c:\workspace\nodegyp-test-commit\nodes\win2012r2\lib\configure.js:336:16)
gyp ERR! stack at emitTwo (events.js:87:13)
gyp ERR! stack at ChildProcess.emit (events.js:172:7)
gyp ERR! stack at Process.ChildProcess._handle.onexit (internal/child_process.js:211:12)
gyp ERR! System Windows_NT 6.3.9600
gyp ERR! command "c:\\workspace\\nodegyp-test-commit\\nodes\\win2012r2\\local_node\\node.exe" "c:\\workspace\\nodegyp-test-commit\\nodes\\win2012r2\\bin\\node-gyp.js" "rebuild" "-C" "c:\\workspace\\nodegyp-test-commit\\nodes\\win2012r2\\test\\node_modules\\hello_world" "--loglevel=verbose" "-nodedir=c:\\workspace\\nodegyp-test-commit\\nodes\\win2012r2\\test\\node_modules\\hello_world\\�英文字符"
gyp ERR! cwd c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\node_modules\hello_world
gyp ERR! node -v v4.8.3
gyp ERR! node-gyp -v v3.6.1
gyp ERR! not ok 

@refack

Copy link
Copy Markdown
Contributor

Comment threadtest/test-addon.js
if (!checkCharmapValid()) {
return t.skip('python console app can\'t encode non-ascii character.')
}

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack I added the character map check, if python app can not convert non-ASCII characters, then skip this test. console output like this:

TAP version 13
# build simple addon
ok 1 should be equal
ok 2 should end in ok
ok 3 should be equal
# build simple addon in path with non-ascii characters
node : Traceback (most recent call last):
At line:5 char:1
+ node ./test/test-addon
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (Traceback (most recent call last)::String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
File "test-charmap.py", line 20, in <module>
print main()
File "test-charmap.py", line 15, in main
print textmap[encoding]
File "C:\Python27\lib\encodings\cp1252.py", line 12, in encode
return codecs.charmap_encode(input,errors,encoding_table)
UnicodeEncodeError: 'charmap' codec can't encode character u'\u012b' in position 3: character maps to <undefined>
ok 4 python console app can't encode non-ascii character. # SKIP
1..4
# tests 4
# pass 4
# ok

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

@refack
What else do I need to do for this PR ?

Comment threadpackage.json Outdated
},
"scripts": {
"test": "tape test/test-*"
"test": "tape test/test-*.js"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather you move test-charmap.py to test/fixtures

@refack

Copy link
Copy Markdown
Contributor

Comment threadtest/test-addon.js
var execFile = require('child_process').execFile
var path = require('path')
var fs = require('graceful-fs')
var child_process = require('child_process')

@lc-softlc-softJun 8, 2017

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack
Do I need rename child_process to childProcess ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack

Copy link
Copy Markdown
Contributor

If you could rebase on master it will make the CI not test on node < 4

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

https://ci.nodejs.org/job/nodegyp-test-commit/187/nodes=win2012r2/console
execFileSync is undefined ?

c:\workspace\nodegyp-test-commit\nodes\win2012r2>call npm test > node-gyp@3.6.1 test c:\workspace\nodegyp-test-commit\nodes\win2012r2
> tape test/test-*.js
TAP version 13
# build simple addon
ok 1 should be equal
ok 2 should end in ok
c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\test-addon.js:14
return execFileSync('node', ['-e', testCode], { cwd: __dirname }).toString()
^
TypeError: undefined is not a function
at runHello (c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\test-addon.js:14:10)
at c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\test-addon.js:43:19
at ChildProcess.exithandler (child_process.js:656:7)
at ChildProcess.emit (events.js:98:17)
at maybeClose (child_process.js:766:16)
at Process.ChildProcess._handle.onexit (child_process.js:833:5)
npm ERR! Test failed. See above for more details.
Build step 'Conditional steps (multiple)' marked build as failure
Notifying upstream pro

@refack

Copy link
Copy Markdown
Contributor

Ignore it's node@0.10https://ci.nodejs.org/job/nodegyp-test-commit/187/nodes=win2012r2/
As I said if you rebase onto master we bumped the version to 4 and don't test on node < 4

@refack

Copy link
Copy Markdown
Contributor

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

I need to modify this test to make it support node@0.10 ?

@refack

Copy link
Copy Markdown
Contributor

I need to modify this test to make it support node@0.10 ?

No. We stopped supporting node < 4 a week ago.

refack pushed a commit to refack/node-gyp that referenced this pull request Jun 8, 2017
* test: build simple addon in path with non-ascii characters
* test: add test-charmap.py
PR-URL: nodejs#1203
Reviewed-By: Refael Ackermann <refack@gmail.com>
@refack

Copy link
Copy Markdown
Contributor

Landed in d6139b5

@bnoordhuis

Copy link
Copy Markdown
Member

Kind of late to the party but I think there is a bug in the python script. It assumes that locale.getdefaultlocale()[1] is a string but that isn't always true:

$ env LC_ALL=C python -c 'import locale; print locale.getdefaultlocale()'
(None, None)

It makes the test fail (or rather: pass when it shouldn't) like this:

$ env LC_ALL=C node test/test-addon.js TAP version 13
# build simple addon
ok 1 should be equal
ok 2 should end in ok
ok 3 should be equal
# build simple addon in path with non-ascii characters
Traceback (most recent call last):
File "fixtures/test-charmap.py", line 19, in<module>
print main()
File "fixtures/test-charmap.py", line 8, in main
sys.setdefaultencoding(encoding)
TypeError: setdefaultencoding() argument 1 must be string, not None
ok 4 python console app can't encode non-ascii character. # SKIP1..4# tests 4# pass 4# ok

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

@bnoordhuis
I have not tested it when locale.getdefaultlocale()[1] value is None, and I do not know whether python can process non-ascii encoding string, So, in this case, I set default result is python can not process non-ascii encoding string, not need to run the test.

@refack

Copy link
Copy Markdown
Contributor

xml_string = unicode(xml_string, 'latin-1').encode(encoding)

default_encoding = locale.getdefaultlocale()[1]
if default_encoding.upper() != encoding.upper():

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should test default_encoding and default_encoding.upper() != encoding.upper():

@refack

Copy link
Copy Markdown
Contributor

@richardlaurichardlau mentioned this pull request Jul 20, 2018
2 tasks
duqingnian pushed a commit to duqingnian/gyp that referenced this pull request Apr 26, 2024
Bug: nodejs/node-gyp#1203
Change-Id: I30d71a2bb3d4b09e7bd9409c3c45c32bd182d736
duqingnian pushed a commit to duqingnian/gyp that referenced this pull request Apr 26, 2024
Bug: nodejs/node-gyp#1203
Change-Id: I30d71a2bb3d4b09e7bd9409c3c45c32bd182d736
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@lc-soft@gibfahn@refack@bnoordhuis@richardlau
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

gyp: update xml string encoding conversion - #1203

Closed
lc-soft wants to merge 3 commits into
nodejs:masterfrom
lc-soft:fix_xml_encoding_bug
Closed

gyp: update xml string encoding conversion#1203
lc-soft wants to merge 3 commits into
nodejs:masterfrom
lc-soft:fix_xml_encoding_bug

Conversation

@lc-soft

@lc-softlc-soft commented May 20, 2017

Copy link
Copy Markdown
Contributor

My project depends on the node-sass, but it can not successfully install, so I tried using the npm rebuild node-sass --force command to build the node-sass on Windows 10. But it could not be built successfully, error message is: "node_version.h": No such file or directory

I guess this is the problem of compiling configuration, and I found the node-sass\build\binding.vcxproj file from the output information, so I opened it with the editor and found that the configuration item has garbled text:

qq 20170520130717

My username can not be displayed correctly, there seems to be a encoding conversion bug when writing to the binding.vcxproj file. I took some time to debug it, Eventually I found the problem out here: easy_xml.py#L120

qq 20170520130900

Since xml_string contains non-ascii characters, xml_string.encode() will fail and throw an exception, and then this string will be treated as latin-1 encoded string to convert, but my default locale character encoding is not latin-1, therefore, the binding.vcproj file is written with the wrong content.

After modification, the contents of the output file is correct.

qq 20170520130513

node-sass can be built successfully.

gyp info ok
Installed to F:\work\XXXXXX\node_modules\node-sass\vendor\win32-x64-48\binding.node
node-sass@4.5.3 F:\work\XXXXXX\node_modules\node-sass

@gibfahn

Copy link
Copy Markdown
Member

Maybe cc/ @joaocgreis@refack ?

Proposed change seems reasonable, but I don't know enough to review.

@refack

Copy link
Copy Markdown
Contributor

@lc-soft I'll have a look
Since it looks like a bug in GYP you should also open an issue at https://bugs.chromium.org/p/gyp/issues/list or even submit a patch

@refack

Copy link
Copy Markdown
Contributor

P.S. I keep forgetting to say...
Thank you very much for the contribution! 🥇

@lc-soft

lc-soft commented May 20, 2017

Copy link
Copy Markdown
ContributorAuthor

@refack I found these: #366#945#297.
This is old bug. but they did not submit a patch to upstream, this file has not been changed:
https://chromium.googlesource.com/external/gyp.git/+/master/pylib/gyp/easy_xml.py#105

@refack

Copy link
Copy Markdown
Contributor

I found these: #366#945#297, This is old bug. but they did not submit a patch to upstream, this file has not been changed:
https://chromium.googlesource.com/external/gyp.git/+/master/pylib/gyp/easy_xml.py#105

Yeah, for a long time upstream GYP was unresponsive so people didn't bother with submitting patches. They are trying to be better 🤷‍♂️ . Thank you for pointing me to those PRs!

I'm looking at your patch, we might land it here, and then try to push it upstream.

Anyway since AFAIK this is your first contribution, I'll give you some info on our review and landing process.
Ref: https://github.com/nodejs/node/blob/master/CONTRIBUTING.md#step-7-discuss-and-update
We keep the PR open for at least 48-72 hours so that anyone that might have some input to give will have get a chance. We will go over your code change, maybe ask a few question or request some changes. Then we run our automated test suite, and if everything is Ok we land the change.
In the case of node-gyp one of the package owners will need to decide when and how to release a new package version. Since this seems like semver-patch this stage will probably be quick.

@refackrefack self-assigned this May 20, 2017
Comment threadgyp/pylib/gyp/easy_xml.py Outdated
xml_string = unicode(xml_string, 'latin-1').encode(encoding)

default_encoding = locale.getdefaultlocale()[1]
if default_encoding != encoding.upper():

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not .upper or .lower both sides?
Also are you sure this won't throw?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, this is my negligence, I mistakenly thought it is capitalized, by this result:

image

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it makes sense to "normalize" both sides, since AFAIK there are no two Language Tags that differ only by case.

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

I can not run gyptest.py on Windows 10.

F:\repos\gyp>python gyptest.py test/win
[ 1/196] (msvs) test\win\generator-output-different-drive\gyptest-generator-output-different-drive.py failed 0.186s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 2e20748> ignored
[ 2/196] (msvs) test\win\gyptest-asm-files.py failed 0.184s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 2a53908> ignored
[ 3/196] (msvs) test\win\gyptest-cl-additional-include-dirs.py failed 0.195s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 29f3908> ignored
[ 4/196] (msvs) test\win\gyptest-cl-additional-options.py failed 0.185s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 2983a20> ignored
[ 6/196] (msvs) test\win\gyptest-cl-buffer-security-check.py failed 0.191s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 2a93978> ignored
[ 7/196] (msvs) test\win\gyptest-cl-calling-convention.py failed 0.199s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 29c3978> ignored
[ 8/196] (msvs) test\win\gyptest-cl-character-set.py failed 0.194s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 2ad3978> ignored

@refack

Copy link
Copy Markdown
Contributor

Which version of Visual Studio you got Installed? Cause if it's VS2017 Build Tools, gyptest can't find them...
You'll need to set an environment variable GYP_BUILD_TOOL to the full path of your msbuild.exe.

Also you could run node-gyp's tests by npm test

BTW: could you add a test case here (maybe add a copy of test\node_modules\hello_world in a unicode path and a call in in test\test-addon.js)

@lc-soft

lc-soft commented May 20, 2017

Copy link
Copy Markdown
ContributorAuthor

@refack OK, It has been running successfully.

F:\repos\gyp>set GYP_BUILD_TOOL=D:\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe
F:\repos\gyp>python gyptest.py test/win

But there are some errors:

[ 6/196] (msvs) test\win\gyptest-cl-buffer-security-check.py failed 3.843s
'D:\Microsoft' is not recognized as an internal or external command, operable program or batch file. Traceback (most recent call last):
File "test\win\gyptest-cl-buffer-security-check.py", line 42, in <module>
if 'security_cookie' not in GetDisassemblyOfMain('test_bsc_unset.exe'):
File "test\win\gyptest-cl-buffer-security-check.py", line 27, in GetDisassemblyOfMain
output = test.run_dumpbin('/disasm', full_path)
File "F:\repos\gyp\test\lib\TestGyp.py", line 813, in run_dumpbin
assert not proc.returncode
AssertionError
...
[ 18/196] (msvs) test\win\gyptest-cl-function-level-linking.py failed 2.896s
'D:\Microsoft' is not recognized as an internal or external command, operable program or batch file. Traceback (most recent call last):
File "test\win\gyptest-cl-function-level-linking.py", line 44, in <module>
should_exist=True)
File "test\win\gyptest-cl-function-level-linking.py", line 23, in CheckForSectionString
output = test.run_dumpbin('/headers', binary)
File "F:\repos\gyp\test\lib\TestGyp.py", line 813, in run_dumpbin
assert not proc.returncode
AssertionError
...

@lc-softlc-soft changed the title Improve xml string encoding conversiongyp: update xml string encoding conversionMay 20, 2017
@refack

Copy link
Copy Markdown
Contributor

Try set GYP_BUILD_TOOL="D:\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe"

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

@refack There will be more problems after using this method.

F:\repos\gyp>set GYP_BUILD_TOOL="D:\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe"
F:\repos\gyp>python gyptest.py test/win
[ 1/196] (msvs) test\win\generator-output-different-drive\gyptest-generator-output-different-drive.py failed 0.806s
STDOUT =========================================================================
STDERR =========================================================================
Exception trying to execute: ['F:\\repos\\gyp\\"D:\\Microsoft Visual Studio\\2017\\Community\\MSBuild\\15.0\\Bin\\MSBuild.exe"', 'prog.sln', '/t:Build', '/p:Configuration=Default']
Traceback (most recent call last):
File "test\win\generator-output-different-drive\gyptest-generator-output-different-drive.py", line 38, in <module>
test.build('prog.gyp', test.ALL, chdir=os.path.join(output_drive, 'output'))
File "F:\repos\gyp\test\lib\TestGyp.py", line 937, in build
return self.run(program=self.build_tool, **kw)
File "F:\repos\gyp\test\lib\TestGyp.py", line 333, in run
super(TestGypBase, self).run(*args, **kw)
File "F:\repos\gyp\test\lib\TestCommon.py", line 542, in run
apply(TestCmd.run, [self], kw)
File "F:\repos\gyp\test\lib\TestCmd.py", line 1224, in run
stdin=stdin)
File "F:\repos\gyp\test\lib\TestCommon.py", line 484, in start
raise e
WindowsError: [Error 5]
[ 2/196] (msvs) test\win\gyptest-asm-files.py failed 1.532s
STDOUT =========================================================================
STDERR =========================================================================
Exception trying to execute: ['F:\\repos\\gyp\\"D:\\Microsoft Visual Studio\\2017\\Community\\MSBuild\\15.0\\Bin\\MSBuild.exe"', 'asm-files.sln', '/t:Build', '/p:Configuration=Default']
Traceback (most recent call last):
File "test\win\gyptest-asm-files.py", line 24, in <module>
test.build('asm-files.gyp', test.ALL, chdir=CHDIR)
File "F:\repos\gyp\test\lib\TestGyp.py", line 937, in build
return self.run(program=self.build_tool, **kw)
File "F:\repos\gyp\test\lib\TestGyp.py", line 333, in run
super(TestGypBase, self).run(*args, **kw)
File "F:\repos\gyp\test\lib\TestCommon.py", line 542, in run
apply(TestCmd.run, [self], kw)
File "F:\repos\gyp\test\lib\TestCmd.py", line 1224, in run
stdin=stdin)
File "F:\repos\gyp\test\lib\TestCommon.py", line 484, in start
raise e
WindowsError: [Error 5]

@refack

Copy link
Copy Markdown
Contributor

Yeah, the test harness is very rusty.
I've pushed your patch to the Chromium code review system, and I've started a CI there - https://chromium-review.googlesource.com/c/509632/

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

@refack Good job! 👍

@refack

Copy link
Copy Markdown
Contributor

@refack

refack commented May 21, 2017

Copy link
Copy Markdown
Contributor

Did I click submit on a comment asking you to add a test?

Anyway, please do. I can suggest copying test\node_modules\hello_world to a path with non latin-1 characters in it, and adding a test case in "test\test-addon.js" building it.

Bonus points if you add a test also to https://github.com/refack/GYP/tree/node-gyp-1203 😉

@refackrefack left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, pending addition of a test.

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

OK, I will take a few days to add test.

Comment threadtest/test-addon.js Outdated
}
runCmd(t, [nodeGyp, 'configure', '-C', addonPath, '--loglevel=verbose',
'-nodedir=' + testNodeDir])
runCmd(t, [nodeGyp, 'build', '-C', addonPath, '--loglevel=verbose'])

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a clean up (try { fs.unlinkSync...)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack I have tried to use the rebuild command before, but there will be errors:

...
gyp verb clean removing "build" directory
gyp ERR! clean error
gyp ERR! stack Error: EPERM: operation not permitted, unlink 'F:\repos\GitHub\node-gyp\test\node_modules\hello_world\build\Release\hello.node'
...

how to solve this problem? a temporary solution is to use configure and build commands.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the reason hello.node can not be deleted is that it is occupied at the time of execution to require('hello_world'). so, solution is to create a new project (E.g:
hello_world_2), and rebuild it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO execFileSync is also completely fine.
OR you could create a hello_非英文字符 fixture.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean something like execFileSync(node, ['-e', "var x = require('hello_world'); if (x.hello() !== 'hello') process.exit(2)"])
Which is more sanitary anyway.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tried to use execFileSync before, but there have been some error messages, so I switched to the current solution.
OK, I will try to use execFileSync again.

@refack

Copy link
Copy Markdown
Contributor

Thank you!
One comment and I'll land this.

Comment threadtest/test-addon.js Outdated
t.plan(5)

configure(t).on('exit', function () {
var data, config, nodeDir, testNodeDir

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack I'am directly merged this test into the test build simple addon.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it works I'm +1
Another solution is to use execFileSync

Comment threadtest/test-addon.js Outdated
}
}

rebuild(t, testNodeDir).on('exit', function () {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Comment threadtest/test-addon.js Outdated
})

test('build simple addon in path with non-ascii characters', function (t) {
t.plan(3)

@lc-softlc-softMay 24, 2017

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack OK, this test has been able to run successfully.

F:\repos\GitHub\node-gyp>node ./test/test-addon.js
TAP version 13
# build simple addon
ok 1 should be equal
ok 2 should end in ok
ok 3 should be equal
# build simple addon in path with non-ascii characters
ok 4 should be equal
ok 5 should end in ok
ok 6 should be equal
1..6
# tests 6
# pass 6
# ok

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@refack

Copy link
Copy Markdown
Contributor

Comment threadtest/test-addon.js
var execFile = require('child_process').execFile
var path = require('path')
var fs = require('graceful-fs')
var child_process = require('child_process')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question to @nodejs/node-gyp
Can we use destructuring?

const{ execFileSync, execFile }=require('child_process')

Or do we test on pre ES6 versions?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the CI still tests 0.10 and 0.12.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not any more 😄

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

CI test did not pass.

gyp: c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\node_modules\hello_world\?????\include\node\common.gypi not found (cwd: c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\node_modules\hello_world) while reading includes of binding.gyp while trying to load binding.gyp
gyp ERR! configure error gyp ERR! stack Error: `gyp` failed with exit code: 1
gyp ERR! stack at ChildProcess.onCpExit (c:\workspace\nodegyp-test-commit\nodes\win2012r2\lib\configure.js:336:16)
gyp ERR! stack at emitTwo (events.js:87:13)
gyp ERR! stack at ChildProcess.emit (events.js:172:7)
gyp ERR! stack at Process.ChildProcess._handle.onexit (internal/child_process.js:211:12)
gyp ERR! System Windows_NT 6.3.9600
gyp ERR! command "c:\\workspace\\nodegyp-test-commit\\nodes\\win2012r2\\local_node\\node.exe" "c:\\workspace\\nodegyp-test-commit\\nodes\\win2012r2\\bin\\node-gyp.js" "rebuild" "-C" "c:\\workspace\\nodegyp-test-commit\\nodes\\win2012r2\\test\\node_modules\\hello_world" "--loglevel=verbose" "-nodedir=c:\\workspace\\nodegyp-test-commit\\nodes\\win2012r2\\test\\node_modules\\hello_world\\�英文字符"
gyp ERR! cwd c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\node_modules\hello_world
gyp ERR! node -v v4.8.3
gyp ERR! node-gyp -v v3.6.1
gyp ERR! not ok 

@refack

Copy link
Copy Markdown
Contributor

Comment threadtest/test-addon.js
if (!checkCharmapValid()) {
return t.skip('python console app can\'t encode non-ascii character.')
}

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack I added the character map check, if python app can not convert non-ASCII characters, then skip this test. console output like this:

TAP version 13
# build simple addon
ok 1 should be equal
ok 2 should end in ok
ok 3 should be equal
# build simple addon in path with non-ascii characters
node : Traceback (most recent call last):
At line:5 char:1
+ node ./test/test-addon
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (Traceback (most recent call last)::String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
File "test-charmap.py", line 20, in <module>
print main()
File "test-charmap.py", line 15, in main
print textmap[encoding]
File "C:\Python27\lib\encodings\cp1252.py", line 12, in encode
return codecs.charmap_encode(input,errors,encoding_table)
UnicodeEncodeError: 'charmap' codec can't encode character u'\u012b' in position 3: character maps to <undefined>
ok 4 python console app can't encode non-ascii character. # SKIP
1..4
# tests 4
# pass 4
# ok

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

@refack
What else do I need to do for this PR ?

Comment threadpackage.json Outdated
},
"scripts": {
"test": "tape test/test-*"
"test": "tape test/test-*.js"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather you move test-charmap.py to test/fixtures

@refack

Copy link
Copy Markdown
Contributor

Comment threadtest/test-addon.js
var execFile = require('child_process').execFile
var path = require('path')
var fs = require('graceful-fs')
var child_process = require('child_process')

@lc-softlc-softJun 8, 2017

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack
Do I need rename child_process to childProcess ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack

Copy link
Copy Markdown
Contributor

If you could rebase on master it will make the CI not test on node < 4

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

https://ci.nodejs.org/job/nodegyp-test-commit/187/nodes=win2012r2/console
execFileSync is undefined ?

c:\workspace\nodegyp-test-commit\nodes\win2012r2>call npm test > node-gyp@3.6.1 test c:\workspace\nodegyp-test-commit\nodes\win2012r2
> tape test/test-*.js
TAP version 13
# build simple addon
ok 1 should be equal
ok 2 should end in ok
c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\test-addon.js:14
return execFileSync('node', ['-e', testCode], { cwd: __dirname }).toString()
^
TypeError: undefined is not a function
at runHello (c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\test-addon.js:14:10)
at c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\test-addon.js:43:19
at ChildProcess.exithandler (child_process.js:656:7)
at ChildProcess.emit (events.js:98:17)
at maybeClose (child_process.js:766:16)
at Process.ChildProcess._handle.onexit (child_process.js:833:5)
npm ERR! Test failed. See above for more details.
Build step 'Conditional steps (multiple)' marked build as failure
Notifying upstream pro

@refack

Copy link
Copy Markdown
Contributor

Ignore it's node@0.10https://ci.nodejs.org/job/nodegyp-test-commit/187/nodes=win2012r2/
As I said if you rebase onto master we bumped the version to 4 and don't test on node < 4

@refack

Copy link
Copy Markdown
Contributor

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

I need to modify this test to make it support node@0.10 ?

@refack

Copy link
Copy Markdown
Contributor

I need to modify this test to make it support node@0.10 ?

No. We stopped supporting node < 4 a week ago.

refack pushed a commit to refack/node-gyp that referenced this pull request Jun 8, 2017
* test: build simple addon in path with non-ascii characters
* test: add test-charmap.py
PR-URL: nodejs#1203
Reviewed-By: Refael Ackermann <refack@gmail.com>
@refack

Copy link
Copy Markdown
Contributor

Landed in d6139b5

@bnoordhuis

Copy link
Copy Markdown
Member

Kind of late to the party but I think there is a bug in the python script. It assumes that locale.getdefaultlocale()[1] is a string but that isn't always true:

$ env LC_ALL=C python -c 'import locale; print locale.getdefaultlocale()'
(None, None)

It makes the test fail (or rather: pass when it shouldn't) like this:

$ env LC_ALL=C node test/test-addon.js TAP version 13
# build simple addon
ok 1 should be equal
ok 2 should end in ok
ok 3 should be equal
# build simple addon in path with non-ascii characters
Traceback (most recent call last):
File "fixtures/test-charmap.py", line 19, in<module>
print main()
File "fixtures/test-charmap.py", line 8, in main
sys.setdefaultencoding(encoding)
TypeError: setdefaultencoding() argument 1 must be string, not None
ok 4 python console app can't encode non-ascii character. # SKIP1..4# tests 4# pass 4# ok

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

@bnoordhuis
I have not tested it when locale.getdefaultlocale()[1] value is None, and I do not know whether python can process non-ascii encoding string, So, in this case, I set default result is python can not process non-ascii encoding string, not need to run the test.

@refack

Copy link
Copy Markdown
Contributor

xml_string = unicode(xml_string, 'latin-1').encode(encoding)

default_encoding = locale.getdefaultlocale()[1]
if default_encoding.upper() != encoding.upper():

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should test default_encoding and default_encoding.upper() != encoding.upper():

@refack

Copy link
Copy Markdown
Contributor

@richardlaurichardlau mentioned this pull request Jul 20, 2018
2 tasks
duqingnian pushed a commit to duqingnian/gyp that referenced this pull request Apr 26, 2024
Bug: nodejs/node-gyp#1203
Change-Id: I30d71a2bb3d4b09e7bd9409c3c45c32bd182d736
duqingnian pushed a commit to duqingnian/gyp that referenced this pull request Apr 26, 2024
Bug: nodejs/node-gyp#1203
Change-Id: I30d71a2bb3d4b09e7bd9409c3c45c32bd182d736
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@lc-soft@gibfahn@refack@bnoordhuis@richardlau
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

gyp: update xml string encoding conversion - #1203

Closed
lc-soft wants to merge 3 commits into
nodejs:masterfrom
lc-soft:fix_xml_encoding_bug
Closed

gyp: update xml string encoding conversion#1203
lc-soft wants to merge 3 commits into
nodejs:masterfrom
lc-soft:fix_xml_encoding_bug

Conversation

@lc-soft

@lc-softlc-soft commented May 20, 2017

Copy link
Copy Markdown
Contributor

My project depends on the node-sass, but it can not successfully install, so I tried using the npm rebuild node-sass --force command to build the node-sass on Windows 10. But it could not be built successfully, error message is: "node_version.h": No such file or directory

I guess this is the problem of compiling configuration, and I found the node-sass\build\binding.vcxproj file from the output information, so I opened it with the editor and found that the configuration item has garbled text:

qq 20170520130717

My username can not be displayed correctly, there seems to be a encoding conversion bug when writing to the binding.vcxproj file. I took some time to debug it, Eventually I found the problem out here: easy_xml.py#L120

qq 20170520130900

Since xml_string contains non-ascii characters, xml_string.encode() will fail and throw an exception, and then this string will be treated as latin-1 encoded string to convert, but my default locale character encoding is not latin-1, therefore, the binding.vcproj file is written with the wrong content.

After modification, the contents of the output file is correct.

qq 20170520130513

node-sass can be built successfully.

gyp info ok
Installed to F:\work\XXXXXX\node_modules\node-sass\vendor\win32-x64-48\binding.node
node-sass@4.5.3 F:\work\XXXXXX\node_modules\node-sass

@gibfahn

Copy link
Copy Markdown
Member

Maybe cc/ @joaocgreis@refack ?

Proposed change seems reasonable, but I don't know enough to review.

@refack

Copy link
Copy Markdown
Contributor

@lc-soft I'll have a look
Since it looks like a bug in GYP you should also open an issue at https://bugs.chromium.org/p/gyp/issues/list or even submit a patch

@refack

Copy link
Copy Markdown
Contributor

P.S. I keep forgetting to say...
Thank you very much for the contribution! 🥇

@lc-soft

lc-soft commented May 20, 2017

Copy link
Copy Markdown
ContributorAuthor

@refack I found these: #366#945#297.
This is old bug. but they did not submit a patch to upstream, this file has not been changed:
https://chromium.googlesource.com/external/gyp.git/+/master/pylib/gyp/easy_xml.py#105

@refack

Copy link
Copy Markdown
Contributor

I found these: #366#945#297, This is old bug. but they did not submit a patch to upstream, this file has not been changed:
https://chromium.googlesource.com/external/gyp.git/+/master/pylib/gyp/easy_xml.py#105

Yeah, for a long time upstream GYP was unresponsive so people didn't bother with submitting patches. They are trying to be better 🤷‍♂️ . Thank you for pointing me to those PRs!

I'm looking at your patch, we might land it here, and then try to push it upstream.

Anyway since AFAIK this is your first contribution, I'll give you some info on our review and landing process.
Ref: https://github.com/nodejs/node/blob/master/CONTRIBUTING.md#step-7-discuss-and-update
We keep the PR open for at least 48-72 hours so that anyone that might have some input to give will have get a chance. We will go over your code change, maybe ask a few question or request some changes. Then we run our automated test suite, and if everything is Ok we land the change.
In the case of node-gyp one of the package owners will need to decide when and how to release a new package version. Since this seems like semver-patch this stage will probably be quick.

@refackrefack self-assigned this May 20, 2017
Comment threadgyp/pylib/gyp/easy_xml.py Outdated
xml_string = unicode(xml_string, 'latin-1').encode(encoding)

default_encoding = locale.getdefaultlocale()[1]
if default_encoding != encoding.upper():

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not .upper or .lower both sides?
Also are you sure this won't throw?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, this is my negligence, I mistakenly thought it is capitalized, by this result:

image

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it makes sense to "normalize" both sides, since AFAIK there are no two Language Tags that differ only by case.

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

I can not run gyptest.py on Windows 10.

F:\repos\gyp>python gyptest.py test/win
[ 1/196] (msvs) test\win\generator-output-different-drive\gyptest-generator-output-different-drive.py failed 0.186s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 2e20748> ignored
[ 2/196] (msvs) test\win\gyptest-asm-files.py failed 0.184s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 2a53908> ignored
[ 3/196] (msvs) test\win\gyptest-cl-additional-include-dirs.py failed 0.195s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 29f3908> ignored
[ 4/196] (msvs) test\win\gyptest-cl-additional-options.py failed 0.185s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 2983a20> ignored
[ 6/196] (msvs) test\win\gyptest-cl-buffer-security-check.py failed 0.191s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 2a93978> ignored
[ 7/196] (msvs) test\win\gyptest-cl-calling-convention.py failed 0.199s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 29c3978> ignored
[ 8/196] (msvs) test\win\gyptest-cl-character-set.py failed 0.194s
Error: could not find devenv
Exception AttributeError: "'TestGypMSVS' object has no attribute '_dirlist'" in <bound method TestGypMSVS.__del__ of 2ad3978> ignored

@refack

Copy link
Copy Markdown
Contributor

Which version of Visual Studio you got Installed? Cause if it's VS2017 Build Tools, gyptest can't find them...
You'll need to set an environment variable GYP_BUILD_TOOL to the full path of your msbuild.exe.

Also you could run node-gyp's tests by npm test

BTW: could you add a test case here (maybe add a copy of test\node_modules\hello_world in a unicode path and a call in in test\test-addon.js)

@lc-soft

lc-soft commented May 20, 2017

Copy link
Copy Markdown
ContributorAuthor

@refack OK, It has been running successfully.

F:\repos\gyp>set GYP_BUILD_TOOL=D:\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe
F:\repos\gyp>python gyptest.py test/win

But there are some errors:

[ 6/196] (msvs) test\win\gyptest-cl-buffer-security-check.py failed 3.843s
'D:\Microsoft' is not recognized as an internal or external command, operable program or batch file. Traceback (most recent call last):
File "test\win\gyptest-cl-buffer-security-check.py", line 42, in <module>
if 'security_cookie' not in GetDisassemblyOfMain('test_bsc_unset.exe'):
File "test\win\gyptest-cl-buffer-security-check.py", line 27, in GetDisassemblyOfMain
output = test.run_dumpbin('/disasm', full_path)
File "F:\repos\gyp\test\lib\TestGyp.py", line 813, in run_dumpbin
assert not proc.returncode
AssertionError
...
[ 18/196] (msvs) test\win\gyptest-cl-function-level-linking.py failed 2.896s
'D:\Microsoft' is not recognized as an internal or external command, operable program or batch file. Traceback (most recent call last):
File "test\win\gyptest-cl-function-level-linking.py", line 44, in <module>
should_exist=True)
File "test\win\gyptest-cl-function-level-linking.py", line 23, in CheckForSectionString
output = test.run_dumpbin('/headers', binary)
File "F:\repos\gyp\test\lib\TestGyp.py", line 813, in run_dumpbin
assert not proc.returncode
AssertionError
...

@lc-softlc-soft changed the title Improve xml string encoding conversiongyp: update xml string encoding conversionMay 20, 2017
@refack

Copy link
Copy Markdown
Contributor

Try set GYP_BUILD_TOOL="D:\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe"

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

@refack There will be more problems after using this method.

F:\repos\gyp>set GYP_BUILD_TOOL="D:\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe"
F:\repos\gyp>python gyptest.py test/win
[ 1/196] (msvs) test\win\generator-output-different-drive\gyptest-generator-output-different-drive.py failed 0.806s
STDOUT =========================================================================
STDERR =========================================================================
Exception trying to execute: ['F:\\repos\\gyp\\"D:\\Microsoft Visual Studio\\2017\\Community\\MSBuild\\15.0\\Bin\\MSBuild.exe"', 'prog.sln', '/t:Build', '/p:Configuration=Default']
Traceback (most recent call last):
File "test\win\generator-output-different-drive\gyptest-generator-output-different-drive.py", line 38, in <module>
test.build('prog.gyp', test.ALL, chdir=os.path.join(output_drive, 'output'))
File "F:\repos\gyp\test\lib\TestGyp.py", line 937, in build
return self.run(program=self.build_tool, **kw)
File "F:\repos\gyp\test\lib\TestGyp.py", line 333, in run
super(TestGypBase, self).run(*args, **kw)
File "F:\repos\gyp\test\lib\TestCommon.py", line 542, in run
apply(TestCmd.run, [self], kw)
File "F:\repos\gyp\test\lib\TestCmd.py", line 1224, in run
stdin=stdin)
File "F:\repos\gyp\test\lib\TestCommon.py", line 484, in start
raise e
WindowsError: [Error 5]
[ 2/196] (msvs) test\win\gyptest-asm-files.py failed 1.532s
STDOUT =========================================================================
STDERR =========================================================================
Exception trying to execute: ['F:\\repos\\gyp\\"D:\\Microsoft Visual Studio\\2017\\Community\\MSBuild\\15.0\\Bin\\MSBuild.exe"', 'asm-files.sln', '/t:Build', '/p:Configuration=Default']
Traceback (most recent call last):
File "test\win\gyptest-asm-files.py", line 24, in <module>
test.build('asm-files.gyp', test.ALL, chdir=CHDIR)
File "F:\repos\gyp\test\lib\TestGyp.py", line 937, in build
return self.run(program=self.build_tool, **kw)
File "F:\repos\gyp\test\lib\TestGyp.py", line 333, in run
super(TestGypBase, self).run(*args, **kw)
File "F:\repos\gyp\test\lib\TestCommon.py", line 542, in run
apply(TestCmd.run, [self], kw)
File "F:\repos\gyp\test\lib\TestCmd.py", line 1224, in run
stdin=stdin)
File "F:\repos\gyp\test\lib\TestCommon.py", line 484, in start
raise e
WindowsError: [Error 5]

@refack

Copy link
Copy Markdown
Contributor

Yeah, the test harness is very rusty.
I've pushed your patch to the Chromium code review system, and I've started a CI there - https://chromium-review.googlesource.com/c/509632/

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

@refack Good job! 👍

@refack

Copy link
Copy Markdown
Contributor

@refack

refack commented May 21, 2017

Copy link
Copy Markdown
Contributor

Did I click submit on a comment asking you to add a test?

Anyway, please do. I can suggest copying test\node_modules\hello_world to a path with non latin-1 characters in it, and adding a test case in "test\test-addon.js" building it.

Bonus points if you add a test also to https://github.com/refack/GYP/tree/node-gyp-1203 😉

@refackrefack left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, pending addition of a test.

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

OK, I will take a few days to add test.

Comment threadtest/test-addon.js Outdated
}
runCmd(t, [nodeGyp, 'configure', '-C', addonPath, '--loglevel=verbose',
'-nodedir=' + testNodeDir])
runCmd(t, [nodeGyp, 'build', '-C', addonPath, '--loglevel=verbose'])

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a clean up (try { fs.unlinkSync...)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack I have tried to use the rebuild command before, but there will be errors:

...
gyp verb clean removing "build" directory
gyp ERR! clean error
gyp ERR! stack Error: EPERM: operation not permitted, unlink 'F:\repos\GitHub\node-gyp\test\node_modules\hello_world\build\Release\hello.node'
...

how to solve this problem? a temporary solution is to use configure and build commands.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the reason hello.node can not be deleted is that it is occupied at the time of execution to require('hello_world'). so, solution is to create a new project (E.g:
hello_world_2), and rebuild it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO execFileSync is also completely fine.
OR you could create a hello_非英文字符 fixture.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean something like execFileSync(node, ['-e', "var x = require('hello_world'); if (x.hello() !== 'hello') process.exit(2)"])
Which is more sanitary anyway.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tried to use execFileSync before, but there have been some error messages, so I switched to the current solution.
OK, I will try to use execFileSync again.

@refack

Copy link
Copy Markdown
Contributor

Thank you!
One comment and I'll land this.

Comment threadtest/test-addon.js Outdated
t.plan(5)

configure(t).on('exit', function () {
var data, config, nodeDir, testNodeDir

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack I'am directly merged this test into the test build simple addon.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it works I'm +1
Another solution is to use execFileSync

Comment threadtest/test-addon.js Outdated
}
}

rebuild(t, testNodeDir).on('exit', function () {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Comment threadtest/test-addon.js Outdated
})

test('build simple addon in path with non-ascii characters', function (t) {
t.plan(3)

@lc-softlc-softMay 24, 2017

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack OK, this test has been able to run successfully.

F:\repos\GitHub\node-gyp>node ./test/test-addon.js
TAP version 13
# build simple addon
ok 1 should be equal
ok 2 should end in ok
ok 3 should be equal
# build simple addon in path with non-ascii characters
ok 4 should be equal
ok 5 should end in ok
ok 6 should be equal
1..6
# tests 6
# pass 6
# ok

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@refack

Copy link
Copy Markdown
Contributor

Comment threadtest/test-addon.js
var execFile = require('child_process').execFile
var path = require('path')
var fs = require('graceful-fs')
var child_process = require('child_process')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question to @nodejs/node-gyp
Can we use destructuring?

const{ execFileSync, execFile }=require('child_process')

Or do we test on pre ES6 versions?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the CI still tests 0.10 and 0.12.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not any more 😄

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

CI test did not pass.

gyp: c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\node_modules\hello_world\?????\include\node\common.gypi not found (cwd: c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\node_modules\hello_world) while reading includes of binding.gyp while trying to load binding.gyp
gyp ERR! configure error gyp ERR! stack Error: `gyp` failed with exit code: 1
gyp ERR! stack at ChildProcess.onCpExit (c:\workspace\nodegyp-test-commit\nodes\win2012r2\lib\configure.js:336:16)
gyp ERR! stack at emitTwo (events.js:87:13)
gyp ERR! stack at ChildProcess.emit (events.js:172:7)
gyp ERR! stack at Process.ChildProcess._handle.onexit (internal/child_process.js:211:12)
gyp ERR! System Windows_NT 6.3.9600
gyp ERR! command "c:\\workspace\\nodegyp-test-commit\\nodes\\win2012r2\\local_node\\node.exe" "c:\\workspace\\nodegyp-test-commit\\nodes\\win2012r2\\bin\\node-gyp.js" "rebuild" "-C" "c:\\workspace\\nodegyp-test-commit\\nodes\\win2012r2\\test\\node_modules\\hello_world" "--loglevel=verbose" "-nodedir=c:\\workspace\\nodegyp-test-commit\\nodes\\win2012r2\\test\\node_modules\\hello_world\\�英文字符"
gyp ERR! cwd c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\node_modules\hello_world
gyp ERR! node -v v4.8.3
gyp ERR! node-gyp -v v3.6.1
gyp ERR! not ok 

@refack

Copy link
Copy Markdown
Contributor

Comment threadtest/test-addon.js
if (!checkCharmapValid()) {
return t.skip('python console app can\'t encode non-ascii character.')
}

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack I added the character map check, if python app can not convert non-ASCII characters, then skip this test. console output like this:

TAP version 13
# build simple addon
ok 1 should be equal
ok 2 should end in ok
ok 3 should be equal
# build simple addon in path with non-ascii characters
node : Traceback (most recent call last):
At line:5 char:1
+ node ./test/test-addon
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (Traceback (most recent call last)::String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
File "test-charmap.py", line 20, in <module>
print main()
File "test-charmap.py", line 15, in main
print textmap[encoding]
File "C:\Python27\lib\encodings\cp1252.py", line 12, in encode
return codecs.charmap_encode(input,errors,encoding_table)
UnicodeEncodeError: 'charmap' codec can't encode character u'\u012b' in position 3: character maps to <undefined>
ok 4 python console app can't encode non-ascii character. # SKIP
1..4
# tests 4
# pass 4
# ok

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

@refack
What else do I need to do for this PR ?

Comment threadpackage.json Outdated
},
"scripts": {
"test": "tape test/test-*"
"test": "tape test/test-*.js"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather you move test-charmap.py to test/fixtures

@refack

Copy link
Copy Markdown
Contributor

Comment threadtest/test-addon.js
var execFile = require('child_process').execFile
var path = require('path')
var fs = require('graceful-fs')
var child_process = require('child_process')

@lc-softlc-softJun 8, 2017

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack
Do I need rename child_process to childProcess ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@refack

Copy link
Copy Markdown
Contributor

If you could rebase on master it will make the CI not test on node < 4

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

https://ci.nodejs.org/job/nodegyp-test-commit/187/nodes=win2012r2/console
execFileSync is undefined ?

c:\workspace\nodegyp-test-commit\nodes\win2012r2>call npm test > node-gyp@3.6.1 test c:\workspace\nodegyp-test-commit\nodes\win2012r2
> tape test/test-*.js
TAP version 13
# build simple addon
ok 1 should be equal
ok 2 should end in ok
c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\test-addon.js:14
return execFileSync('node', ['-e', testCode], { cwd: __dirname }).toString()
^
TypeError: undefined is not a function
at runHello (c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\test-addon.js:14:10)
at c:\workspace\nodegyp-test-commit\nodes\win2012r2\test\test-addon.js:43:19
at ChildProcess.exithandler (child_process.js:656:7)
at ChildProcess.emit (events.js:98:17)
at maybeClose (child_process.js:766:16)
at Process.ChildProcess._handle.onexit (child_process.js:833:5)
npm ERR! Test failed. See above for more details.
Build step 'Conditional steps (multiple)' marked build as failure
Notifying upstream pro

@refack

Copy link
Copy Markdown
Contributor

Ignore it's node@0.10https://ci.nodejs.org/job/nodegyp-test-commit/187/nodes=win2012r2/
As I said if you rebase onto master we bumped the version to 4 and don't test on node < 4

@refack

Copy link
Copy Markdown
Contributor

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

I need to modify this test to make it support node@0.10 ?

@refack

Copy link
Copy Markdown
Contributor

I need to modify this test to make it support node@0.10 ?

No. We stopped supporting node < 4 a week ago.

refack pushed a commit to refack/node-gyp that referenced this pull request Jun 8, 2017
* test: build simple addon in path with non-ascii characters
* test: add test-charmap.py
PR-URL: nodejs#1203
Reviewed-By: Refael Ackermann <refack@gmail.com>
@refack

Copy link
Copy Markdown
Contributor

Landed in d6139b5

@bnoordhuis

Copy link
Copy Markdown
Member

Kind of late to the party but I think there is a bug in the python script. It assumes that locale.getdefaultlocale()[1] is a string but that isn't always true:

$ env LC_ALL=C python -c 'import locale; print locale.getdefaultlocale()'
(None, None)

It makes the test fail (or rather: pass when it shouldn't) like this:

$ env LC_ALL=C node test/test-addon.js TAP version 13
# build simple addon
ok 1 should be equal
ok 2 should end in ok
ok 3 should be equal
# build simple addon in path with non-ascii characters
Traceback (most recent call last):
File "fixtures/test-charmap.py", line 19, in<module>
print main()
File "fixtures/test-charmap.py", line 8, in main
sys.setdefaultencoding(encoding)
TypeError: setdefaultencoding() argument 1 must be string, not None
ok 4 python console app can't encode non-ascii character. # SKIP1..4# tests 4# pass 4# ok

@lc-soft

Copy link
Copy Markdown
ContributorAuthor

@bnoordhuis
I have not tested it when locale.getdefaultlocale()[1] value is None, and I do not know whether python can process non-ascii encoding string, So, in this case, I set default result is python can not process non-ascii encoding string, not need to run the test.

@refack

Copy link
Copy Markdown
Contributor

xml_string = unicode(xml_string, 'latin-1').encode(encoding)

default_encoding = locale.getdefaultlocale()[1]
if default_encoding.upper() != encoding.upper():

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should test default_encoding and default_encoding.upper() != encoding.upper():

@refack

Copy link
Copy Markdown
Contributor

@richardlaurichardlau mentioned this pull request Jul 20, 2018
2 tasks
duqingnian pushed a commit to duqingnian/gyp that referenced this pull request Apr 26, 2024
Bug: nodejs/node-gyp#1203
Change-Id: I30d71a2bb3d4b09e7bd9409c3c45c32bd182d736
duqingnian pushed a commit to duqingnian/gyp that referenced this pull request Apr 26, 2024
Bug: nodejs/node-gyp#1203
Change-Id: I30d71a2bb3d4b09e7bd9409c3c45c32bd182d736
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@lc-soft@gibfahn@refack@bnoordhuis@richardlau