@@ -6,6 +6,10 @@ module ArduinoCI
6
6
7
7
# Tools for interacting with the host machine
8
8
class Host
9
+ # TODO: this came from https://stackoverflow.com/a/22716582/2063546
10
+ # and I'm not sure if it can be replaced by self.os == :windows
11
+ WINDOWS_VARIANT_REGEX = /mswin32|cygwin|mingw|bccwin/ . freeze
12
+
9
13
# Cross-platform way of finding an executable in the $PATH.
10
14
# via https://stackoverflow.com/a/5471032/2063546
11
15
# which('ruby') #=> /usr/bin/ruby
@@ -38,13 +42,15 @@ def self.os
38
42
return :windows if OS . windows?
39
43
end
40
44
45
+ # Cross-platform symlinking
41
46
# if on windows, call mklink, else self.symlink
42
47
# @param [Pathname] old_path
43
48
# @param [Pathname] new_path
44
49
def self . symlink ( old_path , new_path )
45
- return FileUtils . ln_s ( old_path . to_s , new_path . to_s ) unless RUBY_PLATFORM =~ /mswin32|cygwin|mingw|bccwin/
50
+ # we would prefer `new_path.make_symlink(old_path)` but "symlink function is unimplemented on this machine" with windows
51
+ return new_path . make_symlink ( old_path ) unless RUBY_PLATFORM =~ WINDOWS_VARIANT_REGEX
46
52
47
- # https://stackoverflow.com/a/22716582/2063546
53
+ # via https://stackoverflow.com/a/22716582/2063546
48
54
# windows mklink syntax is reverse of unix ln -s
49
55
# windows mklink is built into cmd.exe
50
56
# vulnerable to command injection, but okay because this is a hack to make a cli tool work.
@@ -54,5 +60,36 @@ def self.symlink(old_path, new_path)
54
60
_stdout , _stderr , exitstatus = Open3 . capture3 ( 'cmd.exe' , "/C mklink /D #{ np } #{ orp } " )
55
61
exitstatus . success?
56
62
end
63
+
64
+ # Cross-platform is-this-a-symlink function
65
+ # @param [Pathname] path
66
+ # @return [String] the output of a dir command
67
+ def self . get_windows_link_info ( path )
68
+ # via https://stackoverflow.com/a/22716582/2063546
69
+ # vulnerable to command injection, but okay because this is a hack to make a cli tool work.
70
+ np = path . to_s . tr ( "/" , "\\ " ) # work around Pathname bug
71
+
72
+ stdout , _stderr , _exitstatus = Open3 . capture3 ( 'cmd.exe' , "/c dir #{ np } " )
73
+ puts "get_windows_link_info got:\n #{ stdout } "
74
+ stdout
75
+ end
76
+
77
+ # Cross-platform is-this-a-symlink function
78
+ # @param [Pathname] path
79
+ # @return [bool] Whether the file is a symlink
80
+ def self . symlink? ( path )
81
+ return path . symlink? unless RUBY_PLATFORM =~ WINDOWS_VARIANT_REGEX
82
+
83
+ get_windows_link_info . include? ( "SYMLINK" )
84
+ end
85
+
86
+ # Cross-platform "read link" function
87
+ # @param [Pathname] path
88
+ # @return [Pathname] the link target
89
+ def self . readlink ( path )
90
+ return path . readlink unless RUBY_PLATFORM =~ WINDOWS_VARIANT_REGEX
91
+
92
+ get_windows_link_info
93
+ end
57
94
end
58
95
end
0 commit comments