sassconf 0.1.5 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 680e1904ad775caa81e4c706e348487c17eb519e
4
- data.tar.gz: a581a9c6c1dc47fc20144c940ba6f0e73e9e31c5
3
+ metadata.gz: 55c75af5543053a7b3af4c7e645b4a1a14df089e
4
+ data.tar.gz: 1bb53359e87bb07c2157b2e947fd0cb317753e2a
5
5
  SHA512:
6
- metadata.gz: 4efdada8a4926789346e1712e8037889bc8e92c3d8df9d3e042e071bd42475a2cf8502984b27cbaba4188775b1608080c023a7ee8cab829826cbdff6c8a46b52
7
- data.tar.gz: a453267953ca8b2d46672e5df40d21d2f5f3e4b4b2bbc3309ea315b880325da6c9138502d79a98f950f77f67a23a1a09e789787a6d39eebd8eb2174cde43a235
6
+ metadata.gz: c652465dbbd47a37a5642532e2a06461baee18d92b15c96eb19f86be76d86ccd6d7dd831f6439068fcab1d21b222887541065624b0a08b1d056f55a70dc5be27
7
+ data.tar.gz: cd261ab416fe18b6c040a4f85987e05f9b6da33aba30e97dbb49dceebc19c4f5fc30bab76329a4b1e2119df5c7ac673c59ba4df3023833966448bb310f2ea995
data/README.md CHANGED
@@ -8,6 +8,19 @@ With the Sassconf command tool you can use a config file for defining your [Sass
8
8
  If you liked the config file in any Compass environment then you'll like that one also because it's very similar :)
9
9
 
10
10
  ## ChangeLog
11
+ #### Version 0.1.7 (0.1.6 was yanked)
12
+ - Improved live reloading of config file.
13
+ - Works now in all exception cases.
14
+
15
+ - Fixed OSX 'ps' command execution.
16
+
17
+ - Added command check.
18
+
19
+ - Improved process handling.
20
+ - Fixed 'no such process' exception.
21
+
22
+ - Some minor fixes.
23
+
11
24
  #### Version 0.1.5
12
25
  - Fixed Exception handling.
13
26
 
data/bin/sassconf CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require File.dirname(__FILE__) + '/../lib/sassconf'
4
- Sassconf::start
4
+ Sassconf.start
data/lib/sassconf.rb CHANGED
@@ -15,8 +15,8 @@ module Sassconf
15
15
  DESCRIPTION = 'Description:'
16
16
  .newline.blank(3) { 'Adds configuration file to Sass preprocessor.' }
17
17
  .newline.blank(3) { "Version #{Sassconf::VERSION}" }
18
- .newline.blank(3) {'Homepage: http://sassconf.schlegel11.de'}
19
- .newline.blank(3) {'Email: develop@schlegel11.de'}
18
+ .newline.blank(3) { 'Homepage: http://sassconf.schlegel11.de' }
19
+ .newline.blank(3) { 'Email: develop@schlegel11.de' }
20
20
  .paragraph
21
21
  REQUIRED = 'Required:'
22
22
  OPTIONAL = 'Optional:'.newline(1, :left)
@@ -70,32 +70,56 @@ module Sassconf
70
70
 
71
71
  def self.start
72
72
  begin
73
- option_args = Parser.parse(ARGV)
74
- config_manager = ConfigManager.new
75
- executor = SassExecutor.new(ARGV[0], ARGV[1])
76
-
77
- Sassconf.eval_and_execute(config_manager, executor, option_args)
78
-
79
- config_manager.watch_update(option_args.config_path, option_args.reload_active) do |filename|
80
- logger.info("Config reload: #{filename}")
81
- Sassconf.eval_and_execute(config_manager, executor, option_args)
82
- puts "Config reloaded: #{filename}".newline(1, :left).paragraph
83
- end
84
-
85
- executor.wait
73
+ cmd_check
74
+ @@option_args = Parser.parse(ARGV)
75
+ @@config_manager = ConfigManager.new
76
+ @@executor = SassExecutor.new(ARGV[0], ARGV[1])
77
+
78
+ eval_and_execute
79
+ live_reload(@@option_args.reload_active)
80
+ @@executor.wait
86
81
  rescue StandardError, ScriptError => e
87
82
  puts e.message
88
83
  logger.error(e)
89
84
  ensure
85
+ @@executor.detach_and_kill if defined?(@@executor)
90
86
  exit
91
87
  end
92
88
  end
93
89
 
94
- def self.eval_and_execute(config_manager, sass_executor, option_args)
95
- sass_executor.detach_and_kill
96
- config_manager.eval_rb_file(option_args.config_path, option_args.extern_args)
97
- argument_string = sass_executor.create_all_argument_strings(config_manager.variable_with_value_hash, config_manager.variable_hash)
98
- sass_executor.execute(argument_string)
90
+ def live_reload(activate)
91
+ Util.pre_check(activate.boolean?, 'Activate is no boolean type.')
92
+ if (activate)
93
+ @@config_manager.watch_update(@@option_args.config_path) do |filename|
94
+ begin
95
+ logger.info("Config reload: #{filename}")
96
+ eval_and_execute
97
+ puts "Config reloaded: #{filename}".newline(1, :left).paragraph
98
+ rescue StandardError, ScriptError => e
99
+ puts e.message
100
+ logger.error(e)
101
+ @@executor.detach_and_kill
102
+ end
103
+ end
104
+ end
105
+ end
106
+
107
+ def eval_and_execute
108
+ @@executor.detach_and_kill
109
+ @@config_manager.eval_rb_file(@@option_args.config_path, @@option_args.extern_args)
110
+ argument_string = @@executor.create_all_argument_strings(@@config_manager.variable_with_value_hash, @@config_manager.variable_hash)
111
+ @@executor.execute(argument_string)
112
+ end
113
+
114
+ def cmd_check
115
+ message = if Util.windows?
116
+ '"WMIC" command not found!' unless Util.commands_exist?('WMIC')
117
+ else
118
+ '"ps" and/or "pgrep" command not found!' unless Util.commands_exist?('ps', 'pgrep')
119
+ end
120
+
121
+ raise(StandardError, message.newline { 'Please make sure that your system supports the command.' }) if message.string?
99
122
  end
100
123
 
124
+ module_function :eval_and_execute, :cmd_check, :live_reload
101
125
  end
@@ -11,8 +11,8 @@ module Sassconf
11
11
  ARRAY_FROM_STRING_SEPARATOR = ','
12
12
 
13
13
  def eval_rb_file(file_path, extern_string_array = String.empty)
14
- Util.pre_check((file_path.is_string? and file_path.is_not_nil_or_empty? and File.exist?(file_path)), "\"rb\" file path is no string, nil, empty or doesn't exist.")
15
- Util.pre_check((extern_string_array.is_string? and !extern_string_array.nil?), 'Extern string array is no string or nil.')
14
+ Util.pre_check((file_path.string? and file_path.not_nil_or_empty? and File.exist?(file_path)), "\"rb\" file path is no string, nil, empty or doesn't exist.")
15
+ Util.pre_check(extern_string_array.string?, 'Extern string array is no string.')
16
16
 
17
17
  @bind_extern_string_array = extern_string_array
18
18
  inject_array = 'extern_args = create_array_from_string(@bind_extern_string_array);'
@@ -23,14 +23,11 @@ module Sassconf
23
23
  eval("#{inject_array} \n #{source_file} \n #{collect_variables}", reader_binding, file_path, __LINE__ - eval_line)
24
24
  end
25
25
 
26
- def watch_update(file_path, activate)
27
- Util.pre_check(activate.is_boolean?, 'Activate is no boolean type.')
28
- if (activate)
29
- Util.pre_check((file_path.is_string? and file_path.is_not_nil_or_empty? and File.exist?(file_path)), "\"rb\" file path is no string, nil, empty or doesn't exist.")
30
- FileWatcher.new([file_path]).watch do |filename, event|
31
- if (event == :changed)
32
- yield(filename)
33
- end
26
+ def watch_update(file_path)
27
+ Util.pre_check((file_path.string? and file_path.not_nil_or_empty? and File.exist?(file_path)), "\"rb\" file path is no string, nil, empty or doesn't exist.")
28
+ FileWatcher.new([file_path]).watch do |filename, event|
29
+ if (event == :changed)
30
+ yield(filename)
34
31
  end
35
32
  end
36
33
  end
@@ -3,29 +3,28 @@ require_relative 'util'
3
3
  module Sassconf
4
4
  module CoreExtensions
5
5
  module Object
6
- def is_string?
7
- false
8
- end
9
-
10
- def is_hash?
11
- false
6
+ def self.def_false(*args)
7
+ raise ArgumentError, 'Argument is not a symbol' unless args.all? { |arg| arg.is_a?(Symbol) }
8
+ args.each { |arg| alias_method arg, :false_ }
12
9
  end
13
10
 
14
- def is_boolean?
11
+ def false_()
15
12
  false
16
13
  end
17
14
  end
18
15
 
16
+ Object.def_false(:string?, :hash?, :boolean?, :integer?, :array?, :not_nil_or_empty?)
17
+
19
18
  module String
20
19
  def self.included(base)
21
20
  base.extend(ClassMethods)
22
21
  end
23
22
 
24
- def is_string?
23
+ def string?
25
24
  true
26
25
  end
27
26
 
28
- def is_not_nil_or_empty?
27
+ def not_nil_or_empty?
29
28
  !(self.nil? || self.empty?)
30
29
  end
31
30
 
@@ -53,17 +52,22 @@ module Sassconf
53
52
  end
54
53
 
55
54
  module_function :base_manipulation
56
-
57
55
  end
58
56
 
59
57
  module Hash
60
- def is_hash?
58
+ def hash?
59
+ true
60
+ end
61
+ end
62
+
63
+ module Array
64
+ def array?
61
65
  true
62
66
  end
63
67
  end
64
68
 
65
69
  module Boolean
66
- def is_boolean?
70
+ def boolean?
67
71
  true
68
72
  end
69
73
  end
@@ -82,10 +86,14 @@ class Hash
82
86
  include Sassconf::CoreExtensions::Hash
83
87
  end
84
88
 
89
+ class Array
90
+ include Sassconf::CoreExtensions::Array
91
+ end
92
+
85
93
  class TrueClass
86
- include Sassconf::CoreExtensions::Boolean
94
+ include Sassconf::CoreExtensions::Boolean
87
95
  end
88
96
 
89
97
  class FalseClass
90
- include Sassconf::CoreExtensions::Boolean
98
+ include Sassconf::CoreExtensions::Boolean
91
99
  end
@@ -29,44 +29,36 @@ module Sassconf
29
29
  end
30
30
 
31
31
  def execute(argument_string)
32
- Util.pre_check((argument_string.is_string? and argument_string.is_not_nil_or_empty?), 'Argument string is no string, nil or empty.')
32
+ Util.pre_check((argument_string.string? and argument_string.not_nil_or_empty?), 'Argument string is no string, nil or empty.')
33
33
 
34
34
  @pid = spawn(SASS_PROCESS % [argument_string, @sass_input, @sass_output])
35
35
  logger.info("Spawn Sass process: #{@pid}")
36
36
  end
37
37
 
38
38
  def detach_and_kill
39
- unless @pid.nil?
39
+ if @pid.integer? && Util.process_exists?(@pid)
40
40
  logger.info("Detach Sass process: #{@pid}")
41
41
  Process.detach(@pid)
42
- out, status = if Util.windows? then
43
- logger.info("Find child processes on MS-DOS")
44
- Open3.capture2("wmic process where (ParentProcessId=#{@pid.to_s}) get ProcessId")
45
- else
46
- logger.info("Find child processes on UNIX")
47
- Open3.capture2('ps', 'h', '--ppid', @pid.to_s, '-o', 'pid')
48
- end
42
+
49
43
  logger.info("Kill process: #{@pid}")
50
44
  Process.kill('KILL', @pid)
51
- out.each_line do |elem|
52
- pid = elem.to_i;
53
- unless pid == 0
54
- Process.kill('KILL', pid)
55
- logger.info("Killed child process: #{pid}")
56
- end
45
+
46
+ Util.process_childs(@pid) do |pid|
47
+ Process.kill('KILL', pid)
48
+ logger.info("Killed child process: #{pid}")
57
49
  end
58
50
  end
59
51
  end
60
52
 
61
53
  def wait
62
54
  logger.info("Wait for Sass process: #{@pid}")
63
- Process.wait(@pid) unless @pid.nil?
55
+ Process.wait(@pid) if @pid.integer? && Util.process_exists?(@pid)
64
56
  end
65
57
 
66
58
  private
67
59
  def create_string(argument_type, argument_hash)
68
- Util.pre_check(argument_type.is_string?, 'Argument type is no string.')
69
- Util.pre_check((argument_hash.is_hash? and !argument_hash.nil?), 'Argument hash is no hash or nil.')
60
+ Util.pre_check(argument_type.string?, 'Argument type is no string.')
61
+ Util.pre_check(argument_hash.hash?, 'Argument hash is no hash.')
70
62
 
71
63
  logger.info("Create argument string from hash: #{argument_hash}")
72
64
  argument_hash.each { |key, value| argument_hash[key] = String.empty if value == :no_value }
@@ -74,3 +66,4 @@ module Sassconf
74
66
  end
75
67
  end
76
68
  end
69
+
data/lib/sassconf/util.rb CHANGED
@@ -1,19 +1,103 @@
1
+ require_relative 'core_extensions'
2
+
1
3
  module Sassconf
4
+ module MsDos
5
+ def self.included(base)
6
+ base.extend(ClassMethods)
7
+ end
8
+
9
+ module ClassMethods
10
+ def process_childs(ppid, &block)
11
+ Util.pre_check((ppid.integer? and ppid > 0), 'Ppid is no integer.')
12
+ CrossSystem.process_childs("wmic process where (ParentProcessId=#{ppid.to_s}) get ProcessId", &block)
13
+ end
14
+
15
+ def process_exists?(pid)
16
+ Util.pre_check((pid.integer? and pid > 0), 'Pid is no integer.')
17
+ CrossSystem.process_exists?("wmic process where (ProcessId=#{pid.to_s}) get ProcessId")
18
+ end
19
+ end
20
+ end
21
+
22
+ module Unix
23
+ def self.included(base)
24
+ base.extend(ClassMethods)
25
+ end
26
+
27
+ module ClassMethods
28
+ def process_childs(ppid, &block)
29
+ Util.pre_check((ppid.integer? and ppid > 0), 'Ppid is no integer.')
30
+ CrossSystem.process_childs('pgrep', '-P', ppid.to_s, &block)
31
+ end
32
+
33
+ def process_exists?(pid)
34
+ Util.pre_check((pid.integer? and pid > 0), 'Pid is no integer.')
35
+ CrossSystem.process_exists?('ps', '-o', 'pid=', pid.to_s)
36
+ end
37
+ end
38
+ end
39
+
40
+ module CrossSystem
41
+ module_function
42
+
43
+ def process_childs(*cmds)
44
+ Util.pre_check((cmds.any? and cmds.all? { |elem| elem.string? }), 'cmds is empty or element is no string.')
45
+
46
+ out, status = Open3.capture2(*cmds)
47
+ out.each_line do |elem|
48
+ pid = elem.to_i;
49
+ unless pid == 0 && block_given?
50
+ yield(pid)
51
+ end
52
+ end
53
+ end
54
+
55
+ def process_exists?(*cmds)
56
+ Util.pre_check((cmds.any? and cmds.all? { |elem| elem.string? }), 'cmds is empty or element is no string.')
57
+
58
+ out, status = Open3.capture2(*cmds)
59
+ out.each_line.select { |elem| elem.to_i != 0 }.any?
60
+ end
61
+ end
62
+
2
63
  class Util
3
- def self.pre_check(term, message)
4
- raise ArgumentError, message unless term
64
+ def self.init
65
+ windows? ? include(Sassconf::MsDos) : include(Sassconf::Unix)
66
+ end
67
+
68
+ private_class_method :new, :init
69
+
70
+ def self.pre_check(term, message = String.empty)
71
+ raise(ArgumentError, message) unless term
72
+ end
73
+
74
+ def self.which(cmd)
75
+ exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
76
+ ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
77
+ exts.each { |ext|
78
+ exe = File.join(path, "#{cmd}#{ext}")
79
+ return exe if File.executable?(exe) && !File.directory?(exe)
80
+ }
81
+ end
82
+ nil
83
+ end
84
+
85
+ def self.commands_exist?(*cmds)
86
+ cmds.all? { |cmd| which(cmd).not_nil_or_empty? }
5
87
  end
6
88
 
7
89
  #Credits go to https://github.com/rdp/os
8
90
  def self.windows?
9
- if RUBY_PLATFORM =~ /cygwin/ # i386-cygwin
10
- false
11
- elsif ENV['OS'] == 'Windows_NT'
12
- true
13
- else
14
- false
15
- end
91
+ if RUBY_PLATFORM =~ /cygwin/ # i386-cygwin
92
+ false
93
+ elsif ENV['OS'] == 'Windows_NT'
94
+ true
95
+ else
96
+ false
16
97
  end
98
+ end
99
+
100
+ init
17
101
  end
18
102
  end
19
103
 
@@ -1,3 +1,3 @@
1
1
  module Sassconf
2
- VERSION = '0.1.5'
2
+ VERSION = '0.1.7'
3
3
  end
@@ -40,10 +40,10 @@ class TestConfigReader < Minitest::Test
40
40
  assert_equal("\"rb\" file path is no string, nil, empty or doesn't exist.", exception.message)
41
41
 
42
42
  exception = assert_raises(ArgumentError) { @config_manager.eval_rb_file(CONFIG_PATH, 0) }
43
- assert_equal('Extern string array is no string or nil.', exception.message)
43
+ assert_equal('Extern string array is no string.', exception.message)
44
44
 
45
45
  exception = assert_raises(ArgumentError) { @config_manager.eval_rb_file(CONFIG_PATH, nil) }
46
- assert_equal('Extern string array is no string or nil.', exception.message)
46
+ assert_equal('Extern string array is no string.', exception.message)
47
47
 
48
48
  assert_equal(nil, @config_manager.variable_with_value_hash)
49
49
  assert_equal(nil, @config_manager.variable_hash)
@@ -53,7 +53,11 @@ class TestConfigReader < Minitest::Test
53
53
  end
54
54
 
55
55
  def test_negative_watch_update
56
- exception = assert_raises(ArgumentError) { @config_manager.watch_update(nil, 0) }
57
- assert_equal('Activate is no boolean type.', exception.message)
56
+ exception = assert_raises(ArgumentError) { @config_manager.watch_update(nil) }
57
+ assert_equal("\"rb\" file path is no string, nil, empty or doesn't exist.", exception.message)
58
+ exception = assert_raises(ArgumentError) { @config_manager.watch_update(String.empty) }
59
+ assert_equal("\"rb\" file path is no string, nil, empty or doesn't exist.", exception.message)
60
+ exception = assert_raises(ArgumentError) { @config_manager.watch_update('/no/path') }
61
+ assert_equal("\"rb\" file path is no string, nil, empty or doesn't exist.", exception.message)
58
62
  end
59
63
  end
@@ -22,10 +22,10 @@ class TestSassExecuter < Minitest::Test
22
22
 
23
23
  def test_negative_create_argument_with_value_string
24
24
  exception = assert_raises(ArgumentError) { @sass_executor.create_argument_with_value_string(String.empty) }
25
- assert_equal('Argument hash is no hash or nil.', exception.message)
25
+ assert_equal('Argument hash is no hash.', exception.message)
26
26
 
27
27
  exception = assert_raises(ArgumentError) { @sass_executor.create_argument_with_value_string(nil) }
28
- assert_equal('Argument hash is no hash or nil.', exception.message)
28
+ assert_equal('Argument hash is no hash.', exception.message)
29
29
  end
30
30
 
31
31
  def test_positive_create_argument_string
@@ -36,10 +36,10 @@ class TestSassExecuter < Minitest::Test
36
36
 
37
37
  def test_negative_create_argument_string
38
38
  exception = assert_raises(ArgumentError) { @sass_executor.create_argument_string(String.empty) }
39
- assert_equal('Argument hash is no hash or nil.', exception.message)
39
+ assert_equal('Argument hash is no hash.', exception.message)
40
40
 
41
41
  exception = assert_raises(ArgumentError) { @sass_executor.create_argument_string(nil) }
42
- assert_equal('Argument hash is no hash or nil.', exception.message)
42
+ assert_equal('Argument hash is no hash.', exception.message)
43
43
  end
44
44
 
45
45
  def test_positive_create_all_argument_strings
@@ -50,16 +50,16 @@ class TestSassExecuter < Minitest::Test
50
50
 
51
51
  def test_negative_create_all_argument_strings
52
52
  exception = assert_raises(ArgumentError) { @sass_executor.create_all_argument_strings(@config_manager.variable_with_value_hash, String.empty) }
53
- assert_equal('Argument hash is no hash or nil.', exception.message)
53
+ assert_equal('Argument hash is no hash.', exception.message)
54
54
 
55
55
  exception = assert_raises(ArgumentError) { @sass_executor.create_all_argument_strings(@config_manager.variable_with_value_hash, nil) }
56
- assert_equal('Argument hash is no hash or nil.', exception.message)
56
+ assert_equal('Argument hash is no hash.', exception.message)
57
57
 
58
58
  exception = assert_raises(ArgumentError) { @sass_executor.create_all_argument_strings(String.empty, @config_manager.variable_hash) }
59
- assert_equal('Argument hash is no hash or nil.', exception.message)
59
+ assert_equal('Argument hash is no hash.', exception.message)
60
60
 
61
61
  exception = assert_raises(ArgumentError) { @sass_executor.create_all_argument_strings(nil, @config_manager.variable_hash) }
62
- assert_equal('Argument hash is no hash or nil.', exception.message)
62
+ assert_equal('Argument hash is no hash.', exception.message)
63
63
  end
64
64
 
65
65
  def test_positive_execute
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sassconf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marcel Schlegel
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-05 00:00:00.000000000 Z
11
+ date: 2015-06-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sass
@@ -115,7 +115,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
115
115
  version: '0'
116
116
  requirements: []
117
117
  rubyforge_project:
118
- rubygems_version: 2.4.7
118
+ rubygems_version: 2.4.8
119
119
  signing_key:
120
120
  specification_version: 4
121
121
  summary: Adds configuration file to Sass converter.