patheditor 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
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.2"
8
+ s.version = "1.0.3"
9
9
  s.author = "Justin Bailey"
10
10
  s.email = "jgbailey@nospam@gmail.com"
11
11
 
@@ -14,7 +14,7 @@ This gem provides an application, path_editor, which makes it easy to add, remov
14
14
  EOS
15
15
 
16
16
  s.platform = Gem::Platform::RUBY
17
- s.files = FileList["lib/**/*", "*.txt", "Rakefile"].to_a
17
+ s.files = FileList["lib/**/*", "test/**/*", "*.txt", "Rakefile"].to_a
18
18
 
19
19
  s.bindir = "bin"
20
20
  s.executables = ["path_editor"]
data/bin/path_editor CHANGED
@@ -39,9 +39,10 @@ Adds the given path to the PATH environment variable. If the path already exists
39
39
  @remove = opt_args.first
40
40
  },
41
41
  :opt_description => <<-EOS
42
- Removes the given path from the environment variable. If characters such as "*" or "?" appear in the path, it will be treated as a regular expression, and any back slashes should be escaped (i.e. "C:\\Program Files\\*" vs "C:\Program Files").
43
-
44
- When a non-regular expression is given, the path must match exactly to be removed.
42
+ Removes the given path from the environment variable. Special characters such as "?" and "*" will be treated
43
+ as wildcards, just like at the command line. Be sure to enclose the expression in quotes, or the command prompt will
44
+ attempt to expand them for you. Note also that the command prompt seems to switch "\" characters to "/", so matches
45
+ with those characters will appear odd.
45
46
  EOS
46
47
 
47
48
  option :names => %w(--case-sensitive), :arity => 0,
@@ -67,33 +68,20 @@ Forces changes to occur with confirmation. True by default unless paths are bein
67
68
 
68
69
  if @clean || @add || @remove
69
70
  if @clean
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
71
+ @currPath.clean do |path, reason|
72
+ case reason
73
+ when :dup
74
+ @hl.say "Removing #{path} (duplicate)"
75
+ when :notfound
76
+ @hl.say "Removing #{path} (doesn't exist)"
82
77
  end
83
- idx += 1
84
- end
85
-
86
- unless duplicates.empty?
87
- remove_paths(duplicates) { |p| @hl.say "Removing #{p} (duplicate)" }
88
- end
89
-
90
- unless nonexistent.empty?
91
- remove_paths(nonexistent){ |p| @hl.say "Removing #{p} (doesn't exist)" }
78
+
79
+ path_removed
92
80
  end
93
81
  end
94
82
 
95
83
  if @add
96
- unless @currPath.paths.include? @add
84
+ unless @currPath.paths.include?(@add)
97
85
  @currPath.paths.add(@add)
98
86
  @path_updated = true
99
87
  @hl.say "Added #{@add} to path."
@@ -103,20 +91,9 @@ Forces changes to occur with confirmation. True by default unless paths are bein
103
91
  end
104
92
 
105
93
  if @remove
106
- # See if @remove looks like a regular expression
107
- if @remove.index("*") || @remove.index("?")
108
- # File glob "*" not quite the same as reg ex "*" - need to add "." character
109
- # to make sure any and all characters following are matched
110
- @remove = @remove.gsub('\\', '\\\\\\\\').gsub("*", ".*").gsub("?", ".")
111
- exp = @case_sensitive ? Regexp.new("^#{@remove}$") : Regexp.new("^#{@remove}$", Regexp::IGNORECASE)
112
- paths_to_remove = []
113
-
114
- @currPath.paths.each { |p| paths_to_remove << p if exp.match(p) }
115
- remove_paths(paths_to_remove) unless paths_to_remove.empty?
116
- elsif @currPath.paths.include?(@remove)
117
- @hl.say "Removing path #{@remove}"
118
- @currPath.paths.remove(@remove)
119
- @path_updated = true
94
+ @currPath.remove(@remove) do |p|
95
+ @hl.say "Removing path #{p}"
96
+ path_removed
120
97
  end
121
98
  end
122
99
 
@@ -143,30 +120,14 @@ Forces changes to occur with confirmation. True by default unless paths are bein
143
120
  (@automatic_confirm && ! @confirm_disabled) || false
144
121
  end
145
122
 
146
- # Takes an array of paths or indices and removes them from the current path. Yields
147
- # each path before deleting it, if a block was provided
148
- def remove_paths(paths_to_remove)
149
- @paths_removed ||= 0
150
- adjust = 0
151
- paths_to_remove.each do |p|
152
- if p.is_a?(Fixnum)
153
- idx = p - adjust # adjust index based on paths removed so far.
154
- yield @currPath.paths[idx] if block_given?
155
- @currPath.paths.delete_at(idx)
156
- else
157
- yield p if block_given?
158
- @currPath.paths.delete p
159
- end
160
-
161
- # If more than one path matches and the user did not specify "--no-confirmation", make
162
- # sure to enable it here.
163
- @path_updated = true
164
- @automatic_confirm = true if @paths_removed > 0
165
- @paths_removed += 1
166
- adjust += 1
167
- end
123
+ # Records that a path was removed
124
+ def path_removed
125
+ @path_updated = true
126
+ # first time through, @paths_removed is false. Automatic confimration
127
+ # should happen with more than one directory, therefore this will succeed.
128
+ @automatic_confirm = true if @paths_removed
129
+ @paths_removed = true
168
130
  end
169
-
170
131
  end
171
132
 
172
133
  App.run unless $0 == __FILE__
data/lib/windows_path.rb CHANGED
@@ -74,5 +74,75 @@ class WindowsPath
74
74
  def update
75
75
  @system["Item", "Path"] = @paths.join(";")
76
76
  end
77
+
78
+ # Cleans the current path of any non-existent or duplicate directories.
79
+ # If a block is given, yields each directory removed along with a
80
+ # the symbol :dup or :notfound.
81
+ def clean # :yields: path, reason
82
+ nonexistent = []
83
+ found = WindowsPathArray.new
84
+ duplicates = []
85
+ idx = 0
86
+ @paths.each do |p|
87
+ pathname = Pathname.new(p).cleanpath
88
+ if ! pathname.exist?
89
+ nonexistent << p
90
+ elsif found.include?(pathname)
91
+ duplicates << idx
92
+ else
93
+ found << pathname
94
+ end
95
+ idx += 1
96
+ end
97
+
98
+ unless duplicates.empty?
99
+ remove_paths(duplicates) { |p| yield p, :dup if block_given? }
100
+ end
101
+
102
+ unless nonexistent.empty?
103
+ remove_paths(nonexistent) { |p| yield p, :notfound if block_given? }
104
+ end
105
+ end
106
+
107
+ # Removes paths matching the path given. If path is regular
108
+ # expression, it is matched directly. Any other
109
+ # pattern is treated as a potential shell "glob"
110
+ # match, which means "*" and "?" are treated
111
+ # specially.
112
+ #
113
+ # In all cases, the path(s) removed are yielded.
114
+ def remove(pattern) # :yields: path
115
+ paths_to_remove = []
116
+ @paths.each do |p|
117
+ if pattern.is_a?(Regexp)
118
+ paths_to_remove << p if pattern.match(p)
119
+ else
120
+ paths_to_remove << p if File.fnmatch(pattern, p, File::FNM_CASEFOLD | File::FNM_NOESCAPE)
121
+ end
122
+ end
123
+
124
+ paths_to_remove.each do |p|
125
+ yield p if block_given?
126
+ @paths.delete(p)
127
+ end
128
+ end
129
+
130
+ private
131
+
132
+ def remove_paths(paths_to_remove)
133
+ adjust = 0
134
+ paths_to_remove.each do |p|
135
+ if p.is_a?(Fixnum)
136
+ idx = p - adjust # adjust index based on paths removed so far.
137
+ yield @paths[idx] if block_given?
138
+ @paths.delete_at(idx)
139
+ else
140
+ yield p if block_given?
141
+ @paths.delete p
142
+ end
143
+
144
+ adjust += 1
145
+ end
146
+ end
77
147
 
78
148
  end
@@ -0,0 +1,128 @@
1
+ require 'test/unit'
2
+ $:.unshift File.dirname(__FILE__) + "/../lib" unless $:.include?(File.dirname(__FILE__) + "../lib")
3
+ require 'windows_path'
4
+
5
+ class WindowsPathTests < Test::Unit::TestCase
6
+
7
+ def setup
8
+ @path = WindowsPath.new
9
+ end
10
+
11
+ def test_clean
12
+ # add some non-existent directories
13
+ fake = add_fake
14
+
15
+ assert_dir_found fake, "Fake directory not added to current path."
16
+ @path.clean
17
+ assert_dir_not_found fake, "Fake directory found in current path after cleaning!"
18
+ end
19
+
20
+ def test_clean_dups
21
+ fake = add_fake_dup
22
+
23
+ assert_dir_found fake, "Duplicate directory not found in path."
24
+ assert_dup_found fake, "Did not find the right number of duplicates directories in the path."
25
+
26
+ @path.clean
27
+ assert_dir_not_found fake, "Duplicate directory found in current path after cleaning!"
28
+ end
29
+
30
+ def test_clean_and_notfound
31
+ fake_dup = add_fake_dup
32
+ fake_not_found = add_fake
33
+
34
+ assert_dup_found fake_dup, "Did not find the right number of duplicates directories in the path."
35
+ assert_dir_found fake_not_found, "Nonexistent directory not found in path."
36
+
37
+ @path.clean
38
+ assert_dir_not_found fake_dup, "Duplicate directory found in current path after cleaning!"
39
+ assert_dir_not_found fake_not_found, "Nonexistent directory found in current path after cleaning!"
40
+ end
41
+
42
+ def test_remove_dir
43
+ fake_dir = add_fake
44
+ assert_dir_found fake_dir, "Fake directory not found in path."
45
+ @path.remove fake_dir
46
+ assert_dir_not_found fake_dir, "Fake directory found in path after removal."
47
+ end
48
+
49
+ def test_remove_glob
50
+ fake_dir = add_fake
51
+ assert_dir_found fake_dir, "Fake directory not found in path."
52
+ fake_glob = fake_dir.chop << "*"
53
+ @path.remove fake_glob
54
+ assert_dir_not_found fake_dir, "Fake directory not removed by glob: #{fake_glob}"
55
+ end
56
+
57
+ def test_remove_regexp
58
+ fake_dir = add_fake
59
+ assert_dir_found fake_dir, "Fake directory not found in path."
60
+ fake_regex = Regexp.new("^" << fake_dir.gsub('\\', '\\\\\\\\') << "$")
61
+ @path.remove fake_regex
62
+ assert_dir_not_found fake_dir, "Fake directory not removed by regex: #{fake_regex}"
63
+ end
64
+
65
+ def test_remove_case_sensitive_glob
66
+ # Ensure matches with different case works.
67
+ fake_dir = add_fake "C:\\program files"
68
+ fake_glob = "C:\\PROGRAM*"
69
+ @path.remove fake_glob
70
+ assert_dir_not_found fake_dir, "Fake directory not removed by glob: #{fake_glob}"
71
+ end
72
+
73
+ def test_remove_glob_two_stars
74
+ # Test that a glob with wildcards on both ends works
75
+ fake_dir = add_fake "C:\\program files"
76
+ fake_glob = "*PROGRAM*"
77
+ @path.remove fake_glob
78
+ assert_dir_not_found fake_dir, "Fake directory not removed by glob: #{fake_glob}"
79
+ end
80
+
81
+ def test_remove_glob_single_char
82
+ # Test that a glob with question mark works
83
+ fake_dir = add_fake
84
+ fake_glob = fake_dir.chop << "?"
85
+ @path.remove fake_glob
86
+ assert_dir_not_found fake_dir, "Fake directory not removed by glob: #{fake_glob}"
87
+ end
88
+
89
+ # Makes a directory guarnteed not to exist
90
+ def make_fake_dir(dir)
91
+ cnt = 1
92
+ fake_dir = dir
93
+ while @path.paths.include? fake_dir
94
+ fake_dir = dir << cnt
95
+ cnt += 1
96
+ end
97
+
98
+ fake_dir
99
+ end
100
+
101
+ # Add a fake path
102
+ def add_fake(base = "C:\\foobar")
103
+ @path.paths << fake = make_fake_dir(base)
104
+ fake
105
+ end
106
+
107
+ # Add a duplicated fake path
108
+ def add_fake_dup
109
+ fake = add_fake
110
+ @path.paths << fake
111
+
112
+ fake
113
+ end
114
+
115
+ def assert_dir_found(dir, msg)
116
+ assert @path.paths.include?(dir), msg
117
+ end
118
+
119
+ def assert_dir_not_found(dir, msg)
120
+ assert ! @path.paths.include?(dir), msg
121
+ end
122
+
123
+ def assert_dup_found(dir, msg)
124
+ cnt = 0
125
+ @path.paths.each { |p| cnt += 1 if p == dir }
126
+ assert cnt == 2, msg
127
+ end
128
+ 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.2
7
- date: 2007-02-07 00:00:00 -08:00
6
+ version: 1.0.3
7
+ date: 2007-02-12 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
@@ -30,6 +30,7 @@ authors:
30
30
  - Justin Bailey
31
31
  files:
32
32
  - lib/windows_path.rb
33
+ - test/test_windows_path.rb
33
34
  - README.txt
34
35
  - Rakefile
35
36
  test_files: []