-
Notifications
You must be signed in to change notification settings - Fork 104
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
(maint) Expand Windows 8.3 paths in templatedir #82
Conversation
Poking around a bit in the win32 gems, I found that https://github.com/djberg96/win32-file has |
7c4085b
to
f9072d7
Compare
I have a branch where I was working on this with tragiccode in slack yesterday, but the win32 gem solution may be more robust, I was using relative paths: https://github.com/puppetlabs/pdk/compare/debug_windows_path |
according to the docs |
It actually seems to work fine, it just does |
6843126
to
192aafa
Compare
The errors in this PR seem to be connected to |
As an FYI, we actively try to remove any of the win32-* gems from Puppet due to a variety of reasons. Are you absolutely sure you need to bring in this gem to something as simple as 8.3 name expansion? |
10c161c
to
c32bf5a
Compare
@glennsarti @jpogran This PR has been updated to use fiddle to access GetLongPathNameA within kernel32.dll, instead of using win32-gem The PR still needs 1-2 test fixes plus a tidy-up; but a review specifically on this change would be appreciated, cheers |
c32bf5a
to
d9cae03
Compare
lib/pdk/util.rb
Outdated
buffer = nil | ||
loop do | ||
buffer = ' ' * bufferlen | ||
len = GetLongPathNameA(short_path.to_s, buffer, buffer.size) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There should be a check here if GetLongPathName fails (RC = 0)
https://msdn.microsoft.com/en-us/library/windows/desktop/aa364980(v=vs.85).aspx
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to use the W (GetLongPathNameW
) version of the API plus be able to handle double byte characters. Otherwise it'll break for non-English letters e.g. Jöhn
https://github.com/djberg96/win32-file/blob/ffi/lib/win32/file.rb#L189-L200
https://github.com/puppetlabs/puppet/blob/master/lib/puppet/util/windows/file.rb#L267-L279
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs changes for non-english characters
lib/pdk/util.rb
Outdated
end | ||
break | ||
end | ||
buffer.rstrip.chomp("\0") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, you need to free the buffer after use otherwise you'll leak memory
lib/pdk/util.rb
Outdated
len = GetLongPathNameA(short_path.to_s, buffer, buffer.size) | ||
# In the case of the path name being exceptionally long; resize the buffer | ||
# to the actual size, then re-get it | ||
if bufferlen < len |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The correct way to get the buffer length is to call GetLongPathName
with a buffer size of zero, which will then return the required buffer size. Then you can allocate the buffer and call with the correct size.
lib/pdk/util.rb
Outdated
if Gem.win_platform? | ||
extend Fiddle::Importer | ||
dlload 'kernel32.dll' | ||
extern('int GetLongPathNameA(char*, char*, int)', :stdcall) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a note - The actual return type is uint32 but the ruby equivalent is int
pdk.gemspec
Outdated
@@ -27,4 +27,6 @@ Gem::Specification.new do |spec| | |||
|
|||
# Used in the pdk-module-template | |||
spec.add_runtime_dependency 'deep_merge', '~> 1.1' | |||
|
|||
spec.add_runtime_dependency 'win32-file', '~> 0.8' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we remove this now?
28470ce
to
a50632d
Compare
@glennsarti This has been updated to re-use Puppet util code so we should be supporting wide strings now |
lib/pdk/cli/exec.rb
Outdated
@@ -135,7 +135,8 @@ def run_process! | |||
begin | |||
@process.start | |||
rescue ChildProcess::LaunchError => e | |||
raise PDK::CLI::FatalError, _("Failed to execute '%{command}': %{message}") % { command: argv.join(' '), message: e.message } | |||
raise PDK::CLI::FatalError, _('Failed to execute process: %{message}') % { message: e.message } unless @process.respond_to?(:argv) | |||
raise PDK::CLI::FatalError, _("Failed to execute '%{command}': %{message}") % { command: @process.argv.join(' '), message: e.message } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
double raise
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First raise is conditional. Rubocop preferred this raise x unless y form. I'll see if I can re-arrange it so that it is easily readable and passes rubocop.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ugh, yeah, the GuardClause cop is a little bit hit and miss. Maybe the better alternative would be to
message = if @process.respond_to?(:argv)
# ...
raise PDK::CLI::FatalError, message
a50632d
to
4c15a1f
Compare
PDK::Util.make_tmpdir_name might return a short (8.3) path on Windows. This commits adds a canonical path method to allow assurance of using the full path. This fixes module generation on Windows; previously PDK was failing to match C:\Users\Administrator and C:\Users\ADMIN~1
When run_process! fails, an unhandled exception could occur when forming the PDK exception message. This commit handles the case of run_process! failing and @process not having an argv member.
Where the bundle management acceptance tests use mv to backup and restore Gemfile, cascading failures can occur if a pending test fails and leaves no Gemfile on disk.
Setting of GEM_PATH needs to use PATH_SEPARATOR for OS compatibility. Also needs to allow for GEM_PATH to not be set in advance.
The pending test for bundle management fails on appveyor because it actually passes due to the presence of devkit. This test should not be pending - there should be a devkit installed. The test can be manually ignored on workstations that don't/can't have devkit.
4c15a1f
to
6a42e8f
Compare
require 'ffi' | ||
require 'puppet/util/windows/string' | ||
|
||
module Puppet::Util::Windows::APITypes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a plan to import the Puppet Gem into the PDK at some point? If so, this looks like a namespacing issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the PDK needs to be able to deal with multiple versions of puppet, the main binary will never reference the puppet gem.
For the record: I would prefer that utility code to live in a independent gem that others can use without having to depend on a full puppet package. But this is not relevant to this PR. In effect, we're treating this like a vendoring.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh ok.
Looks good to me. Since this incorporates the suggestions from @glennsarti and @Iristyle, I assume we'll be fine from that side too. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need spec tests for the 8.3 naming then?
https://github.com/puppetlabs/pdk/pull/82/files#diff-f1961fa3f901b19ee585c1962e910d5eR56 and friends is the thing we need to test. We've started down this rabbit hole, because in some situations the regex at https://github.com/puppetlabs/pdk/blob/master/lib/pdk/module/templatedir.rb#L198 did not match up due to different encodings of the same path. It should possible to finagle in a test exercising this part. I'll look into it tomorrow. |
Created SDK-286 to track the testing effort. |
PDK::Util.make_tmpdir_name might return a short (8.3) path on Windows.
This commits adds a canonical path method to allow assurance of using
the full path.
This fixes module generation on Windows; previously PDK was failing to
match C:\Users\Administrator and C:\Users\ADMIN~1