patheditor 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/Rakefile +1 -1
  2. data/bin/path_editor +40 -17
  3. data/lib/windows_path.rb +62 -58
  4. metadata +2 -2
data/Rakefile CHANGED
@@ -5,7 +5,7 @@ require 'rake/gempackagetask'
5
5
  spec = Gem::Specification.new do |s|
6
6
  s.name = "patheditor"
7
7
  s.summary = "A simple program to manage the Windows PATH environment variable."
8
- s.version = "1.0.0"
8
+ s.version = "1.0.1"
9
9
  s.author = "Justin Bailey"
10
10
  s.email = "jgbailey@nospam@gmail.com"
11
11
 
data/bin/path_editor CHANGED
@@ -63,18 +63,33 @@ Forces changes to occur with confirmation. True by default unless paths are bein
63
63
 
64
64
  def main
65
65
  @hl = HighLine.new
66
- @paths = WindowsPath.new
66
+ @currPath = WindowsPath.new
67
67
 
68
68
  if @clean || @add || @remove
69
69
  if @clean
70
- paths_to_remove = []
71
- @paths.each { |p| paths_to_remove << p unless Pathname.new(p).exist? }
72
- remove_paths(paths_to_remove) unless paths_to_remove.empty?
70
+ nonexistent = []
71
+ found = WindowsPathArray.new
72
+ duplicates = []
73
+ idx = 0
74
+ @currPath.paths.each do |p|
75
+ pathname = Pathname.new(p).cleanpath
76
+ if ! pathname.exist?
77
+ nonexistent << p
78
+ elsif found.include?(pathname)
79
+ duplicates << idx
80
+ else
81
+ found << pathname
82
+ end
83
+ idx += 1
84
+ end
85
+
86
+ remove_paths(duplicates) unless duplicates.empty?
87
+ remove_paths(nonexistent) unless nonexistent.empty?
73
88
  end
74
89
 
75
90
  if @add
76
- unless @paths.include? @add
77
- @paths.add(@add)
91
+ unless @currPath.paths.include? @add
92
+ @currPath.paths.add(@add)
78
93
  @path_updated = true
79
94
  @hl.say "Added #{@add} to path."
80
95
  else
@@ -91,26 +106,26 @@ Forces changes to occur with confirmation. True by default unless paths are bein
91
106
  exp = @case_sensitive ? Regexp.new("^#{@remove}$") : Regexp.new("^#{@remove}$", Regexp::IGNORECASE)
92
107
  paths_to_remove = []
93
108
 
94
- @paths.each { |p| paths_to_remove << p if exp.match(p) }
109
+ @currPath.paths.each { |p| paths_to_remove << p if exp.match(p) }
95
110
  remove_paths(paths_to_remove) unless paths_to_remove.empty?
96
- elsif @paths.include?(@remove)
111
+ elsif @currPath.paths.include?(@remove)
97
112
  @hl.say "Removing path #{@remove}"
98
- @paths.remove(@remove)
113
+ @currPath.paths.remove(@remove)
99
114
  @path_updated = true
100
115
  end
101
116
  end
102
117
 
103
118
  if @path_updated
104
119
  if confirmation_needed?
105
- @paths.update if @hl.agree("Would you like to commit the changes made? [Yn] ", true)
120
+ @currPath.update if @hl.agree("Would you like to commit the changes made? [Yn] ", true)
106
121
  else
107
- @paths.update
122
+ @currPath.update
108
123
  end
109
124
  end
110
125
  else
111
126
  # Print path
112
127
  @hl.say "Current path entries:"
113
- @paths.each { |p| @hl.say "\t#{p}" }
128
+ @currPath.paths.each { |p| @hl.say "\t#{p}" }
114
129
  end
115
130
  rescue
116
131
  puts "Exception: #{$!.message}"
@@ -123,14 +138,22 @@ Forces changes to occur with confirmation. True by default unless paths are bein
123
138
  (@automatic_confirm && ! @confirm_disabled) || false
124
139
  end
125
140
 
141
+ # Takes an array of paths or indices and removes them from the current path
126
142
  def remove_paths(paths_to_remove)
127
143
  cnt = 0
128
144
  paths_to_remove.each do |p|
129
- @hl.say "Removing #{p}"
130
- @paths.remove p
131
- @path_updated = true
132
- # If more than one path matches and the user did not specify "--no-confirmation", make
133
- # sure to enable it here.
145
+ if p.is_a?(Fixnum)
146
+ idx = p - cnt # adjust index based on paths removed so far.
147
+ @hl.say "Removing #{@currPath.paths[idx]}"
148
+ @currPath.paths.delete_at(idx)
149
+ else
150
+ @hl.say "Removing #{p}"
151
+ @currPath.paths.delete p
152
+ end
153
+
154
+ # If more than one path matches and the user did not specify "--no-confirmation", make
155
+ # sure to enable it here.
156
+ @path_updated = true
134
157
  @automatic_confirm = true if cnt > 0
135
158
  cnt += 1
136
159
  end
data/lib/windows_path.rb CHANGED
@@ -1,74 +1,78 @@
1
1
  require 'win32ole'
2
+ require 'pathname'
2
3
 
3
- # Manages access to and updating of windows path setting. Also manages
4
- # enumerating paths available, and checking if a given path exists.
5
- class WindowsPath
6
- include Enumerable
7
- FILE_SEPARATOR = File::ALT_SEPARATOR
4
+ # Specialized array that knows how to compare paths.
5
+ class WindowsPathArray < Array
6
+
7
+ def include?(path)
8
+ # Compare paths case-insensitive, and also checking
9
+ # trailing separators (so c:\program files == c:\program files\)
10
+ self.any? { |p| compare_paths(path, p) }
11
+ end
8
12
 
9
- def initialize
10
- @shell = WIN32OLE.new("WScript.Shell")
11
- @system = @shell.Environment("System")
12
- @paths = []
13
- @paths = @system.Item("Path").split(";").collect { |p| p.strip }
14
- end
15
-
16
- def expand_vars(val)
17
- while m = val.match(/%.*?%/)
18
- val = val.gsub(m[0], @shell.ExpandEnvironmentStrings(m[0]))
19
- end
13
+ def compare_paths(left, right)
14
+ left = Pathname.new(WindowsPath.expand_vars(left.to_s).downcase).cleanpath
15
+ right = Pathname.new(WindowsPath.expand_vars(right.to_s).downcase).cleanpath
20
16
 
21
- val
17
+ return left.eql?(right)
22
18
  end
23
19
 
24
- def add(p)
25
- @paths << p.to_s unless self.include?(p)
20
+ def <<(p)
21
+ super(p.to_s)
26
22
  end
23
+
24
+ alias_method :add, :<<
27
25
 
28
- alias_method :<<, :add
29
-
30
- def remove(r)
31
- # Find all paths that match and delete them.
32
- @paths = @paths.delete_if { |p| compare_paths(r, p) }
33
- end
34
-
35
- # Update any changes
36
- def update
37
- @system["Item", "Path"] = @paths.join(";")
38
- end
39
-
40
- def each
41
- @paths.each { |p| yield expand_vars(p) }
42
- end
26
+ def delete(path)
27
+ self.delete_if { |p| compare_paths(path, p) }
28
+ end
29
+
30
+ def each
31
+ for i in 0..size - 1
32
+ yield WindowsPath.expand_vars(raw_item(i))
33
+ end
34
+ end
35
+
36
+ # Preserve access to base class definition of []
37
+ alias_method :raw_item, :[]
38
+
39
+ def [](idx)
40
+ WindowsPath.expand_vars(super)
41
+ end
42
+ end
43
43
 
44
- def compare_paths(left, right)
45
- left = expand_vars(left.to_s).downcase
46
- right = expand_vars(right.to_s).downcase
47
-
48
- if left == right
49
- true
50
- else
51
- left_sep = left.length > 1 && left.rindex(FILE_SEPARATOR) == left.length - 1
52
- right_sep = right.length > 1 && right.rindex(FILE_SEPARATOR) == right.length - 1
53
-
54
- if ! left_sep && right_sep
55
- left == right[0, right.length - 1]
56
- elsif left_sep && ! right_sep
57
- left[0, left.length - 1] == right
58
- else
59
- false
60
- end
44
+ # Manages access to and updating of windows path setting.
45
+ class WindowsPath
46
+ include Enumerable
47
+ FILE_SEPARATOR = File::ALT_SEPARATOR
48
+
49
+ # paths is a WindowsPathArray holding all paths in the system.
50
+ attr_accessor :paths
51
+
52
+ # Holds a reference to the Win32 Shell COM object.
53
+ def self.shell
54
+ @shell ||= WIN32OLE.new("WScript.Shell")
55
+ end
56
+
57
+ # Given a path, expands any environment variables found in it.
58
+ # Returns the expanded path.
59
+ def self.expand_vars(path)
60
+ while m = path.match(/%.*?%/)
61
+ path = path.gsub(m[0], shell.ExpandEnvironmentStrings(m[0]))
61
62
  end
63
+
64
+ path
62
65
  end
63
-
64
- def include?(path)
65
- # Compare paths case-insensitive, and also checking
66
- # trailing separators (so c:\program files == c:\program files\)
67
- @paths.any? { |p| compare_paths(path, p) }
66
+
67
+ def initialize
68
+ @system = WindowsPath.shell.Environment("System")
69
+ @paths = WindowsPathArray.new
70
+ @system.Item("Path").split(";").each { |p| @paths.add(p.strip) }
68
71
  end
69
72
 
70
- def inspect
71
- @paths.inspect
73
+ # Update any changes
74
+ def update
75
+ @system["Item", "Path"] = @paths.join(";")
72
76
  end
73
77
 
74
78
  end
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.0
3
3
  specification_version: 1
4
4
  name: patheditor
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.0.0
7
- date: 2007-02-05 00:00:00 -08:00
6
+ version: 1.0.1
7
+ date: 2007-02-06 00:00:00 -08:00
8
8
  summary: A simple program to manage the Windows PATH environment variable.
9
9
  require_paths:
10
10
  - lib