insup 0.1.2 → 0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 865c49f6dd236ccef3027dc04084c735b87f525a
4
- data.tar.gz: 97b3f43e5fa341d031b8f05e8fabfa26bd51f862
3
+ metadata.gz: 6ddabfbd03d3ec5598cf705493a8dbd48aeb1d3d
4
+ data.tar.gz: 511d852bd1c4cd25bb6214b22fff66b3f06655da
5
5
  SHA512:
6
- metadata.gz: e601f6a59cd8c163c34bc9e1448417c35db3abab1ae781f1753f40120161348a339d6299b8c736f63321c9b5e457a847ad75f6276ef1a5d76a86546d4fbf7382
7
- data.tar.gz: 3e7e51c70057e53e8d62d6f5b0b6e9d286d1f94105ca07b7a69e4f568dc15f67958a51f1b38b97db2225cfae8dc646331a8524aa92670ca4db771f3e7fe6ba0d
6
+ metadata.gz: 9ebc75e74472e577ac81b3cec28c882a3b3b23f294f540c8d8cb60b793728271b45a14bd04046be164ec899b635c7c95408d849af6babdd4d1a3856b5351b51b
7
+ data.tar.gz: 3cda1702f037ffc0efbccbeb73d353f37683b78b030b821ca64a3b40c32ce03afca0072a5413b8e468e7cb493c00d5c775a81956e0e09129cde754423ae30a77
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.1.1
1
+ 2.1.2
data/Gemfile.lock CHANGED
@@ -4,21 +4,21 @@ PATH
4
4
  insup (0.1.2)
5
5
  activeresource (~> 4.0)
6
6
  colorize (~> 0.7)
7
+ gli (~> 2.10)
7
8
  listen (~> 2.7)
8
- match_files (~> 0.1)
9
- trollop (~> 2.0)
9
+ match_files (~> 0.2)
10
10
 
11
11
  GEM
12
12
  remote: https://rubygems.org/
13
13
  specs:
14
- activemodel (4.1.0)
15
- activesupport (= 4.1.0)
14
+ activemodel (4.1.1)
15
+ activesupport (= 4.1.1)
16
16
  builder (~> 3.1)
17
17
  activeresource (4.0.0)
18
18
  activemodel (~> 4.0)
19
19
  activesupport (~> 4.0)
20
20
  rails-observers (~> 0.1.1)
21
- activesupport (4.1.0)
21
+ activesupport (4.1.1)
22
22
  i18n (~> 0.6, >= 0.6.9)
23
23
  json (~> 1.7, >= 1.7.7)
24
24
  minitest (~> 5.1)
@@ -27,10 +27,7 @@ GEM
27
27
  builder (3.2.2)
28
28
  celluloid (0.15.2)
29
29
  timers (~> 1.1.0)
30
- celluloid-io (0.15.0)
31
- celluloid (>= 0.15.0)
32
- nio4r (>= 0.5.0)
33
- colorize (0.7.2)
30
+ colorize (0.7.3)
34
31
  coveralls (0.7.0)
35
32
  multi_json (~> 1.3)
36
33
  rest-client
@@ -40,18 +37,17 @@ GEM
40
37
  diff-lcs (1.2.5)
41
38
  docile (1.1.3)
42
39
  ffi (1.9.3)
40
+ gli (2.10.0)
43
41
  i18n (0.6.9)
44
42
  json (1.8.1)
45
- listen (2.7.2)
43
+ listen (2.7.6)
46
44
  celluloid (>= 0.15.2)
47
- celluloid-io (>= 0.15.0)
48
45
  rb-fsevent (>= 0.9.3)
49
46
  rb-inotify (>= 0.9)
50
- match_files (0.1)
51
- mime-types (2.2)
52
- minitest (5.3.3)
53
- multi_json (1.9.3)
54
- nio4r (1.0.0)
47
+ match_files (0.2)
48
+ mime-types (2.3)
49
+ minitest (5.3.4)
50
+ multi_json (1.10.1)
55
51
  rails-observers (0.1.2)
56
52
  activemodel (~> 4.0)
57
53
  rb-fsevent (0.9.4)
@@ -59,14 +55,18 @@ GEM
59
55
  ffi (>= 0.5.0)
60
56
  rest-client (1.6.7)
61
57
  mime-types (>= 1.16)
62
- rspec (2.14.1)
63
- rspec-core (~> 2.14.0)
64
- rspec-expectations (~> 2.14.0)
65
- rspec-mocks (~> 2.14.0)
66
- rspec-core (2.14.8)
67
- rspec-expectations (2.14.5)
68
- diff-lcs (>= 1.1.3, < 2.0)
69
- rspec-mocks (2.14.6)
58
+ rspec (3.0.0)
59
+ rspec-core (~> 3.0.0)
60
+ rspec-expectations (~> 3.0.0)
61
+ rspec-mocks (~> 3.0.0)
62
+ rspec-core (3.0.0)
63
+ rspec-support (~> 3.0.0)
64
+ rspec-expectations (3.0.0)
65
+ diff-lcs (>= 1.2.0, < 2.0)
66
+ rspec-support (~> 3.0.0)
67
+ rspec-mocks (3.0.0)
68
+ rspec-support (~> 3.0.0)
69
+ rspec-support (3.0.0)
70
70
  simplecov (0.8.2)
71
71
  docile (~> 1.1.0)
72
72
  multi_json
@@ -75,11 +75,10 @@ GEM
75
75
  term-ansicolor (1.3.0)
76
76
  tins (~> 1.0)
77
77
  thor (0.19.1)
78
- thread_safe (0.3.3)
78
+ thread_safe (0.3.4)
79
79
  timers (1.1.0)
80
- tins (1.1.0)
81
- trollop (2.0)
82
- tzinfo (1.1.0)
80
+ tins (1.3.0)
81
+ tzinfo (1.2.1)
83
82
  thread_safe (~> 0.1)
84
83
 
85
84
  PLATFORMS
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 HttpLab
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md CHANGED
@@ -29,9 +29,10 @@ Open **.insup** file with your favourite text editor and modify the configuratio
29
29
 
30
30
  * **track** section is an array of directories which you want to track for changes. Specify locations relative to the working directory
31
31
  * **ignore** section specifies an array of patterns that are used to ignore files. Files that match ignore patterns will be neither tracked nor uploaded. The patterns must be specified in Git ignore format relative to the working directory.
32
- * **tracker** section specifies the tracker to use as well as its configuration. The tracker class is specified by the `class` option.
33
- * **uploader** section specifies the uploader to use as well as its configuration. The uploader class is specified by the `class` option.
32
+ * [**tracker**](#trackers) section specifies the tracker to use as well as its configuration. The tracker class is specified by the `class` option.
33
+ * [**uploader**](#uploaders) section specifies the uploader to use as well as its configuration. The uploader class is specified by the `class` option.
34
34
  * **insales** secion holds information for connecting to Insales shop. To use insales features you should specify `subdomain`, `api_key` and `password` parameters.
35
+ * **log** section sets logging parameters. Use `file` to specify a log file path, `level` to set log level (`unknown`, `debug`, `error`, `fatal`, `info`, `unknown` and `warn`), and `pattern` to specify log message pattern using `%{timestamp}`, `%{level}`, `%{message}`, and `%{backtrace}` substitutions.
35
36
 
36
37
  #### Trackers
37
38
 
@@ -58,11 +59,14 @@ Activate listen mode by typing
58
59
  ```bash
59
60
  insup listen
60
61
  ```
62
+ or just
63
+ ```bash
64
+ insup
65
+ ```
61
66
  in your working directory.
62
67
 
63
68
 
64
69
  #### Track mode
65
-
66
70
  In this mode you can periodically check for changes and upload changed files to the remote storage. Tracker specified in the .insup file is used to detect changes.
67
71
 
68
72
  Print working directory status accroding to the selected tracker
@@ -72,12 +76,10 @@ insup status
72
76
 
73
77
  Upload changes
74
78
  ```bash
75
- insup commit [file1 [file2 [file3 [...]]]]
79
+ insup commit
76
80
  ```
77
- Call `commit` command with the file list to upload only files specified.
78
81
 
79
82
  ### Other commands
80
-
81
83
  List all themes in the Insales shop if `insales` section is given in the .insup file:
82
84
  ```bash
83
85
  insup insales list-themes
@@ -88,3 +90,13 @@ List files under tracked locations:
88
90
  insup list-files [--all|--ignored]
89
91
  ```
90
92
  Use `--all` option to list *all* files, and `--ignored` to list only ignored files. Calling this command without options will result in a list of tracked files only.
93
+
94
+ #### Getting help
95
+ To see a full list of commands available, type:
96
+ ```bash
97
+ insup --help
98
+ ```
99
+ To see help message on the specific command, type:
100
+ ```bash
101
+ insup <command> --help
102
+ ```
data/bin/insup CHANGED
@@ -1,67 +1,101 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'trollop'
4
-
3
+ require 'gli'
5
4
  require_relative '../lib/insup/version'
6
- require_relative '../lib/insup.rb'
7
-
8
- SUB_COMMANDS = %w(init status config commit list-locations list-files listen insales)
9
-
10
- global_opts = Trollop::options do
11
- version "insup #{Insup::VERSION} (c) 2014 nuinuhin@gmail.com"
12
- banner <<-EOS
13
- Usage:
14
- insup status
15
- insup commit [file1, [file2, [...]]]
16
- insup config
17
- insup list-files
18
- insup listen
19
- insup init
20
- insup list-locations
21
- insup insales list-themes
22
- EOS
23
- stop_on SUB_COMMANDS
5
+ require_relative '../lib/insup/console'
6
+
7
+ include GLI::App
8
+
9
+ program_desc 'Insup uploader'
10
+ version Insup::VERSION
11
+ flag [:c,:config], default_value: '.insup'
12
+ switch [:v,:verbose], desc: 'Be verbose'
13
+ switch [:d, :debug], desc: 'Dump debug information upon error'
14
+
15
+ pre do |global_options, command, options, args|
16
+ settings_file = global_options[:config]
17
+ verbose = global_options[:verbose]
18
+ debug = global_options[:debug]
19
+ ENV['GLI_DEBUG'] = 'true' if debug
20
+ Insup::Console.start(settings_file, verbose, debug)
24
21
  end
25
22
 
26
- cmd = ARGV.shift
23
+ on_error do |ex|
24
+ Insup::Console.process_error(ex)
25
+ false
26
+ end
27
27
 
28
- if cmd.nil?
29
- raise Trollop::HelpNeeded
28
+ desc 'Initialize the directory with insup file'
29
+ arg_name 'directory', [:optional]
30
+ command :init do |c|
31
+ c.action do |global_options, options, args|
32
+ Insup::Console.init(args[0])
33
+ end
30
34
  end
31
35
 
32
- if(!SUB_COMMANDS.include? cmd)
33
- Trollop::die "unknown subcommand #{cmd.inspect}"
36
+ desc 'Show current status of working directory according to the selected tracker'
37
+ command :status do |c|
38
+ c.action do |global_options, options, args|
39
+ Insup::Console.status
40
+ end
41
+ end
42
+
43
+ desc 'Print current config and exit'
44
+ command :config do |c|
45
+ c.action do |global_options, options, args|
46
+ Insup::Console.print_config
47
+ end
48
+ end
49
+
50
+ desc 'Show tracked locations'
51
+ command 'list-locations' do |c|
52
+ c.action do |global_options, options, args|
53
+ Insup::Console.list_locations
54
+ end
34
55
  end
35
56
 
36
- begin
37
- case cmd
38
- when 'status'
39
- Insup.status
40
- when 'config'
41
- Insup.print_config
42
- when 'list-locations'
43
- Insup.list_locations
44
- when 'list-files'
45
- if ARGV.include?('--all')
46
- Insup.list_files(mode: :all)
47
- elsif ARGV.include?('--ignored')
48
- Insup.list_files(mode: :ignored)
57
+ desc 'List files under tracked locations'
58
+ command 'list-files' do |c|
59
+ c.switch [:a, :all], desc: 'List all files, including ignored ones', negatable: false
60
+ c.switch [:i, :ignored], desc: 'List only ignored files', negatable: false
61
+
62
+ c.action do |global_options, options, args|
63
+ if options[:all]
64
+ Insup::Console.list_files(mode: :all)
65
+ elsif options[:ignored]
66
+ Insup::Console.list_files(mode: :ignored)
49
67
  else
50
- Insup.list_files
68
+ Insup::Console.list_files
51
69
  end
52
- when 'commit'
53
- Insup.commit ARGV.map{|f| Insup::TrackedFile.new(f,Insup::TrackedFile::MODIFIED)}
54
- when 'listen'
55
- Insup.listen
56
- when 'init'
57
- Insup.init(ARGV[0])
58
- when 'insales'
59
- cmd = ARGV.shift
60
- case cmd
61
- when 'list-themes'
62
- Insup::Insales.list_themes
70
+ end
71
+ end
72
+
73
+ desc 'Apply changes to the remote storage'
74
+ arg_name 'file', [:optional, :multiple]
75
+ command :commit do |c|
76
+ c.action do |global_options, options, args|
77
+ Insup::Console.commit(args)
78
+ end
79
+ end
80
+
81
+ desc 'Initialize listen mode'
82
+ command :listen do |c|
83
+ c.action do |global_options, options, args|
84
+ Insup::Console.listen
85
+ end
86
+ end
87
+
88
+ desc 'Tasks related to insales'
89
+ command :insales do |c|
90
+ c.default_command 'list-themes'
91
+ c.desc 'List themes in the current Insales shop'
92
+ c.command 'list-themes' do |sc|
93
+ sc.action do |global_options, options, args|
94
+ Insup::Console.insales_list_themes
63
95
  end
64
96
  end
65
- rescue => ex
66
- puts ex.message
67
97
  end
98
+
99
+ default_command :listen
100
+
101
+ exit run(ARGV)
data/insup.gemspec CHANGED
@@ -14,9 +14,9 @@ Gem::Specification.new do |s|
14
14
  s.license = 'MIT'
15
15
 
16
16
  s.add_dependency 'colorize', '~> 0.7'
17
- s.add_dependency 'trollop', '~> 2.0'
17
+ s.add_dependency 'gli', '~> 2.10'
18
18
  s.add_dependency 'listen', '~> 2.7'
19
- s.add_dependency 'match_files', '~> 0.1'
19
+ s.add_dependency 'match_files', '~> 0.2'
20
20
  s.add_dependency 'activeresource', '~> 4.0'
21
21
 
22
22
  s.files = `git ls-files`.split("\n")
data/insup.template ADDED
@@ -0,0 +1,43 @@
1
+ # Tracked locations. List all subdirectories of the working directory you want Insup to track
2
+ track:
3
+ - media
4
+ - snippets
5
+ - templates
6
+
7
+ tracker:
8
+ class: git
9
+
10
+ insales:
11
+ subdomain:
12
+ api_key:
13
+ password:
14
+
15
+ # Uploader settings
16
+ # class: uploader class. Use 'insales' or 'dummy'
17
+ uploader:
18
+ class: insales
19
+ theme_id:
20
+
21
+ # Ignore patterns
22
+ # Insup ignore patterns follow the same rules as Git ignore. Remember that the patterns
23
+ # are considered to be relative to the working directory, not to the tracked locations.
24
+ ignore:
25
+ - '*.swp'
26
+ - '*.swx'
27
+ - '.*'
28
+ - 'thumbs.db'
29
+ - '.DS_Store'
30
+ - '*.log'
31
+
32
+ # Logging settings
33
+ # file: Path to the log file relative to the working directory
34
+ # level: Log error level. Available options are 'unknown', 'debug', 'error', 'fatal', 'info',
35
+ # and 'warn'
36
+ # pattern: A pattern to for logger to use when writing messages. Available substitutions are:
37
+ # %{timestamp}, %{level} and %{message}
38
+ #
39
+
40
+ log:
41
+ file: 'log/insup.log'
42
+ level: 'info'
43
+ pattern: "%{timestamp} - %{level}\t: %{message}\n"
@@ -0,0 +1,20 @@
1
+ require_relative '../uploader'
2
+ require 'colorize'
3
+
4
+ class Insup::Console::UploadObserver
5
+ def update(event, *args)
6
+ file = args[0]
7
+
8
+ case event
9
+ when Insup::Uploader::CREATING_FILE
10
+ puts "Creating file #{file.path}...".green
11
+ when Insup::Uploader::MODIFYING_FILE
12
+ puts "Uploading file #{file.path}...".yellow
13
+ when Insup::Uploader::DELETING_FILE
14
+ puts "Deleting file #{file.path}...".red
15
+ when Insup::Uploader::ERROR
16
+ message = args[1]
17
+ puts "Error in #{file.path}: #{message}".red
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,137 @@
1
+ require 'colorize'
2
+ require 'fileutils'
3
+ require_relative '../insup'
4
+
5
+ module Insup::Console
6
+
7
+ def self.start(settings_file = nil, verbose = false, debug = false)
8
+ settings_file ||= '.insup'
9
+ @settings = Insup::Settings.new(settings_file)
10
+ @insup = Insup.new(Dir.getwd, @settings)
11
+ @verbose = verbose
12
+ @debug = debug
13
+ self.init_log(@settings)
14
+ true
15
+ end
16
+
17
+ def self.init_log(settings)
18
+ if settings.log_file.nil? || settings.log_file.empty?
19
+ @logger = Logger.new($stdout)
20
+ else
21
+ log_dir = File.dirname(settings.log_file)
22
+ FileUtils.mkdir_p(log_dir) if !Dir.exist?(log_dir)
23
+ @logger = Logger.new(settings.log_file)
24
+ end
25
+
26
+ @logger.level = @debug ? Logger::DEBUG : settings.log_level
27
+ @logger.formatter = proc do |severity, datetime, progname, msg|
28
+
29
+ format_string = settings.log_pattern
30
+ values_hash = {
31
+ level: severity,
32
+ timestamp: datetime
33
+ }
34
+
35
+ if msg.is_a? Exception
36
+ values_hash[:message] = msg.message
37
+ values_hash[:backtrace] = "\n#{msg.backtrace.join("\n")}"
38
+ else
39
+ values_hash[:message] = msg.to_s
40
+ values_hash[:backtrace] = nil
41
+ end
42
+
43
+ format_string % values_hash
44
+ end
45
+
46
+ Insup.logger = @logger
47
+ end
48
+
49
+ def self.init(directory = nil)
50
+ directory ||= Dir.getwd
51
+ Insup.create_insup_file(directory)
52
+ end
53
+
54
+ def self.list_locations
55
+ @insup.tracked_locations.each do |loc|
56
+ puts loc
57
+ end
58
+ end
59
+
60
+ def self.list_files(options = {})
61
+ @insup.files(options).each do |f|
62
+ puts f
63
+ end
64
+ end
65
+
66
+ def self.insales_list_themes
67
+ theme_id = @settings.uploader['theme_id']
68
+ @insup.insales.themes.each do |theme|
69
+ prefix = theme.id == theme_id ? '=>' : ' '
70
+ puts "#{prefix} #{theme.id}\t#{theme.title}"
71
+ end
72
+ end
73
+
74
+ def self.status
75
+ @insup.changes.each do |x|
76
+ case x.state
77
+ when Insup::TrackedFile::NEW
78
+ puts "New: #{x.path}".green
79
+ when Insup::TrackedFile::MODIFIED
80
+ puts "Modified: #{x.path}".yellow
81
+ when Insup::TrackedFile::DELETED
82
+ puts "Deleted: #{x.path}".red
83
+ end
84
+ end
85
+ end
86
+
87
+ def self.print_config
88
+ puts "Tracker: #{@settings.tracker['class']}"
89
+ puts "Uploader: #{@settings.uploader['class']}"
90
+ puts 'Tracked locations:'
91
+ puts @settings.tracked_locations.map{|loc| "\t#{loc}"}
92
+ puts 'Ignore patterns:'
93
+ puts @settings.ignore_patterns.map{|ip| "\t#{ip}"}
94
+ end
95
+
96
+ def self.listen
97
+ @insup.uploader.add_observer(Insup::Console::UploadObserver.new)
98
+ puts 'Listening...'
99
+ @insup.listen
100
+ exit_requested = false
101
+ Kernel.trap( "INT" ) { exit_requested = true }
102
+
103
+ while !exit_requested do
104
+ sleep 0.1
105
+ end
106
+
107
+ puts 'Stopping listener...'
108
+ @insup.stop_listening
109
+ puts 'Terminated by user'
110
+ end
111
+
112
+ def self.commit(args)
113
+ @insup.uploader.add_observer(Insup::Console::UploadObserver.new)
114
+ @insup.commit(args)
115
+ end
116
+
117
+ def self.process_error(exception)
118
+ if exception.is_a? Insup::Exceptions::UploaderError
119
+ $stderr.puts "UploaderError: #{exception.message}".red
120
+ else
121
+ $stderr.puts "Error: #{exception.message}".red
122
+ end
123
+
124
+ if @debug
125
+ $stderr.puts exception.backtrace
126
+ end
127
+
128
+ begin
129
+ @logger.error(exception) if @logger
130
+ rescue
131
+ $stderr.puts "Unable to log error because the logger is not properly configured"
132
+ end
133
+ end
134
+
135
+ end
136
+
137
+ require_relative 'console/upload_observer'
data/lib/insup/insales.rb CHANGED
@@ -1,30 +1,35 @@
1
- module Insup::Insales
1
+ class Insup::Insales
2
2
 
3
- def self.configure_api
4
- @config = Insup::Settings.instance.insales;
3
+ def initialize(settings)
4
+ @settings = settings
5
+ end
6
+
7
+ def self.logger=(val)
8
+ ActiveResource::Base.logger = val
9
+ end
5
10
 
6
- return false if @config.nil?
11
+ def self.logger
12
+ ActiveResource::Base.logger
13
+ end
7
14
 
15
+ def configure_api
8
16
  if !@has_api
9
- active_resource_logger = Logger.new('log/active_resource.log', 'daily')
10
- active_resource_logger.level = Logger::DEBUG
11
- ActiveResource::Base.logger = active_resource_logger
12
- @has_api = ::Insup::Insales::Base.configure(@config['api_key'], @config['subdomain'], @config['password'])
17
+ @has_api = ::Insup::Insales::Base.configure(config['api_key'], config['subdomain'], config['password'])
13
18
  end
14
19
  end
15
20
 
16
- def self.list_themes
21
+ def themes
17
22
  configure_api
18
- themes = Theme.all
19
- themes.each do |theme|
20
- puts "#{theme.id}\t#{theme.title}"
21
- end
23
+ Theme.all
24
+ end
25
+
26
+ def config
27
+ @settings.insales
22
28
  end
23
29
 
24
30
  def print_config
25
31
 
26
32
  end
27
-
28
33
  end
29
34
 
30
35
  require 'active_resource'
@@ -2,8 +2,9 @@ require 'listen'
2
2
 
3
3
  class Listener
4
4
 
5
- def initialize(base)
5
+ def initialize(base, settings)
6
6
  @base = base
7
+ @settings = settings
7
8
  end
8
9
 
9
10
  def listen(&block)
@@ -74,11 +75,11 @@ class Listener
74
75
  end
75
76
 
76
77
  def tracked_locations
77
- @track = ::Insup::Settings.instance.tracked_locations
78
+ @track = @settings.tracked_locations
78
79
  end
79
80
 
80
81
  def ignore_patterns
81
- @ignore_patterns ||= ::Insup::Settings.instance.ignore_patterns
82
+ @ignore_patterns = @settings.ignore_patterns
82
83
  end
83
84
 
84
85
  end
@@ -1,15 +1,16 @@
1
1
  require 'yaml'
2
+ require 'logger'
2
3
 
3
4
  class Insup::Settings
4
5
  attr_reader :settings
5
6
 
6
- def self.instance
7
- @instance ||= new()
8
- end
9
-
10
7
  def initialize(filename = '.insup')
11
- insupfile = IO.read(filename)
12
- @settings = YAML.load(insupfile)
8
+ if File.exist?(filename)
9
+ insupfile = IO.read(filename)
10
+ @settings = YAML.load(insupfile)
11
+ else
12
+ @settings = {}
13
+ end
13
14
  end
14
15
 
15
16
  def tracked_locations
@@ -17,23 +18,47 @@ class Insup::Settings
17
18
  end
18
19
 
19
20
  def uploader
20
- return settings['uploader']
21
+ return @settings['uploader']
21
22
  end
22
23
 
23
24
  def tracker
24
- return settings['tracker']
25
+ return @settings['tracker']
25
26
  end
26
27
 
27
28
  def ignore_patterns
28
- return settings['ignore'] || []
29
+ return @settings['ignore'] || []
29
30
  end
30
31
 
31
32
  def insales
32
- return settings['insales']
33
+ return @settings['insales']
33
34
  end
34
35
 
35
36
  def save(filename)
36
37
  File.write(filename, @settings.to_yaml)
37
38
  end
38
39
 
40
+ def log
41
+ @settings['log'] || {}
42
+ end
43
+
44
+ def log_level
45
+ level = log['level'] || 'info'
46
+ level = "Logger::#{level.upcase}"
47
+ Kernel.const_get(level)
48
+ end
49
+
50
+ def log_pattern
51
+ log['pattern'] || "%{message}\n"
52
+ end
53
+
54
+ def log_file
55
+ log['file']
56
+ end
57
+
58
+ def save(filename)
59
+ File.open(filename, 'w') do |f|
60
+ f.write(@settings.to_yaml)
61
+ end
62
+ end
63
+
39
64
  end
data/lib/insup/tracker.rb CHANGED
@@ -1,4 +1,4 @@
1
- require('match_files')
1
+ require 'match_files'
2
2
  class Insup::Tracker
3
3
 
4
4
  def self.tracker(tracker_alias)
@@ -10,12 +10,12 @@ class Insup::Tracker
10
10
  @@trackers[tracker_alias.to_sym]
11
11
  end
12
12
 
13
- def initialize(config = nil)
13
+ def initialize(base, config)
14
14
  @config = config
15
- @path = Dir.getwd
15
+ @path = base
16
16
  end
17
17
 
18
- # Lists ALL files in the tracked locations whether they are ignored or not
18
+ # Lists all files in the tracked locations whether they are ignored or not
19
19
  def all_files
20
20
  locations = tracked_locations
21
21
  locations.map do |loc|
@@ -25,12 +25,12 @@ class Insup::Tracker
25
25
  end.flatten
26
26
  end
27
27
 
28
- # Lists ALL tracked files in the tracked locations i. e. all files but ignored
28
+ # Lists all tracked files in the tracked locations i. e. all files but ignored
29
29
  def tracked_files
30
30
  all_files.reject{|f| ignore_matcher.matched?(f)}
31
31
  end
32
32
 
33
- # Lists ALL tracked files in the tracked locations i. e. all files but ignored
33
+ # Lists all tracked files in the tracked locations i. e. all files but ignored
34
34
  def ignored_files
35
35
  all_files.select{|f| ignore_matcher.matched?(f)}
36
36
  end
@@ -52,11 +52,11 @@ class Insup::Tracker
52
52
  end
53
53
 
54
54
  def tracked_locations
55
- @track = ::Insup::Settings.instance.tracked_locations
55
+ @track = @config.tracked_locations
56
56
  end
57
57
 
58
58
  def ignore_patterns
59
- @ignore_patterns ||= ::Insup::Settings.instance.ignore_patterns
59
+ @ignore_patterns ||= @config.ignore_patterns
60
60
  end
61
61
 
62
62
  end
@@ -7,18 +7,30 @@ class Insup::Uploader::DummyUploader < Insup::Uploader
7
7
  def upload_file(file)
8
8
  case file.state
9
9
  when Insup::TrackedFile::NEW
10
- puts "Creating file #{file.path}".green
10
+ changed
11
+ notify_observers(CREATING_FILE, file)
12
+ changed
13
+ notify_observers(CREATED_FILE, file)
11
14
  when Insup::TrackedFile::MODIFIED, Insup::TrackedFile::UNSURE
12
- puts "Uploading file #{file.path}".yellow
15
+ changed
16
+ notify_observers(MODIFYING_FILE, file)
17
+ changed
18
+ notify_observers(MODIFIED_FILE, file)
13
19
  end
14
20
  end
15
21
 
16
22
  def remove_file file
17
- puts "Deleting file #{file.path}".red
23
+ changed
24
+ notify_observers(DELETING_FILE, file)
25
+ changed
26
+ notify_observers(DELETED_FILE, file)
18
27
  end
19
28
 
20
29
  def batch_upload(files)
21
- puts "Batch uploading #{files.count} files"
30
+ changed
31
+ notify_observers(BATCH_UPLOADING_FILE, file)
32
+ changed
33
+ notify_observers(BATCH_UPLOADED_FILE, file)
22
34
  end
23
35
 
24
36
  end
@@ -7,9 +7,15 @@ class Insup::Uploader::InsalesUploader < Insup::Uploader
7
7
 
8
8
  InsalesUploaderError = Class.new(Insup::Exceptions::UploaderError)
9
9
 
10
- def initialize(config)
10
+ def initialize(settings)
11
11
  super
12
- Insup::Insales.configure_api
12
+ @insales = Insup::Insales.new(settings)
13
+ @insales.configure_api
14
+
15
+ if !theme
16
+ raise Insup::Exceptions::UploaderError, "Theme #{theme_id} is not found in the Insales shop"
17
+ end
18
+
13
19
  assets_list(true)
14
20
  end
15
21
 
@@ -32,23 +38,32 @@ class Insup::Uploader::InsalesUploader < Insup::Uploader
32
38
  return
33
39
  end
34
40
 
35
- puts "Creating #{file.path}".green
41
+ changed
42
+ notify_observers(CREATING_FILE, file)
36
43
  asset_type = get_asset_type(file.path)
37
44
 
38
- if(!asset_type)
45
+ if !asset_type
39
46
  raise InsalesUploaderError, "Cannot determine asset type for file #{file.path}"
40
47
  end
41
48
 
42
49
  file_contents = File.read(file.path)
43
50
 
44
- asset = ::Insup::Insales::Asset.create({
51
+ hash = {
45
52
  name: file.file_name,
46
- attachment: Base64.encode64(file_contents),
47
- theme_id: @config['theme_id'],
53
+ theme_id: @config.uploader['theme_id'],
48
54
  type: asset_type
49
- })
55
+ }
56
+
57
+ if ['Asset::Snippet', 'Asset::Template'].include?(asset_type)
58
+ hash[:content] = file_contents
59
+ else
60
+ hash[:attachment] = Base64.encode64(file_contents)
61
+ end
50
62
 
63
+ asset = ::Insup::Insales::Asset.new(hash)
51
64
  assets_list << asset
65
+ changed
66
+ notify_observers(CREATED_FILE, file)
52
67
  end
53
68
 
54
69
  def upload_modified_file(file)
@@ -56,18 +71,26 @@ class Insup::Uploader::InsalesUploader < Insup::Uploader
56
71
 
57
72
  if !asset
58
73
  upload_new_file(file)
74
+ return
59
75
  end
60
76
 
61
- puts "Updating #{file.path}".yellow
77
+ changed
78
+ notify_observers(MODIFYING_FILE, file)
62
79
 
63
80
  file_contents = File.read(file.path)
64
81
 
65
82
  if asset.content_type.start_with? 'text/'
66
- asset.update_attribute(:content, file_contents)
83
+ res = asset.update_attribute(:content, file_contents)
84
+ if !res
85
+ process_error(asset, file)
86
+ end
67
87
  else
68
88
  remove_file(file)
69
89
  upload_new_file(file)
70
90
  end
91
+
92
+ changed
93
+ notify_observers(MODIFIED_FILE, file)
71
94
  end
72
95
 
73
96
  def remove_file(file)
@@ -77,9 +100,15 @@ class Insup::Uploader::InsalesUploader < Insup::Uploader
77
100
  raise InsalesUploaderError, "Cannot find remote counterpart for file #{file.path}"
78
101
  end
79
102
 
80
- puts "Deleting #{file.path}".red
81
- asset.destroy
82
- assets_list.delete(asset)
103
+ changed
104
+ notify_observers(DELETING_FILE, file)
105
+
106
+ if pd=asset.destroy
107
+ assets_list.delete(asset)
108
+ end
109
+
110
+ changed
111
+ notify_observers(DELETED_FILE, file)
83
112
  end
84
113
 
85
114
  private
@@ -89,6 +118,14 @@ private
89
118
  'templates/' => 'Asset::Template'
90
119
  }.freeze
91
120
 
121
+ def process_error(entity, file)
122
+ changed
123
+ entity.errors.full_messages.each do |err|
124
+ Insup.logger.error(err)
125
+ notify_observers(ERROR, file, err)
126
+ end
127
+ end
128
+
92
129
  def get_asset_type path
93
130
  res = nil
94
131
 
@@ -103,7 +140,15 @@ private
103
140
  end
104
141
 
105
142
  def theme
106
- @theme ||= ::Insup::Insales::Theme.find(@config['theme_id'])
143
+ @theme ||= themes[theme_id]
144
+ end
145
+
146
+ def theme_id
147
+ @config.uploader['theme_id']
148
+ end
149
+
150
+ def themes
151
+ @themes ||= Hash[@insales.themes.map{|t| [t.id, t]}]
107
152
  end
108
153
 
109
154
  def find_asset file
@@ -1,4 +1,17 @@
1
+ require 'observer'
2
+
1
3
  class Insup::Uploader
4
+ include Observable
5
+
6
+ CREATING_FILE = 0
7
+ CREATED_FILE = 1
8
+ MODIFYING_FILE = 2
9
+ MODIFIED_FILE = 3
10
+ DELETING_FILE = 4
11
+ DELETED_FILE = 5
12
+ BATCH_UPLOADING_FILES = 6
13
+ BATCH_UPLOADED_FILES = 7
14
+ ERROR = 8
2
15
 
3
16
  def self.uploader(uploader_alias)
4
17
  @@uploaders ||= {}
@@ -23,4 +36,13 @@ class Insup::Uploader
23
36
  end
24
37
  end
25
38
 
39
+ def process_file(file)
40
+ case file.state
41
+ when Insup::TrackedFile::DELETED
42
+ remove_file(file)
43
+ else
44
+ upload_file(file)
45
+ end
46
+ end
47
+
26
48
  end
data/lib/insup/version.rb CHANGED
@@ -1,3 +1,3 @@
1
- module Insup
2
- VERSION = '0.1.2'
1
+ class Insup
2
+ VERSION = '0.2'
3
3
  end
data/lib/insup.rb CHANGED
@@ -1,21 +1,33 @@
1
- require 'colorize'
2
1
  require 'fileutils'
3
2
 
4
- module Insup
3
+ class Insup
4
+
5
+ def self.logger=(val)
6
+ @logger = val
7
+ Insup::Insales.logger = @logger
8
+ end
9
+
10
+ def self.logger
11
+ @logger
12
+ end
13
+
14
+ def initialize(base, settings)
15
+ @settings = settings
16
+ @base = base
17
+ end
5
18
 
6
19
  # Initializes a directory with a default .insup file
7
- def self.init(dir = nil)
20
+ def self.create_insup_file(dir = nil)
8
21
  dir ||= Dir.getwd
9
-
10
- template_file = File.join(File.dirname(File.expand_path(__FILE__)), '../.insup.template')
22
+ template_file = File.join(File.dirname(File.expand_path(__FILE__)), '../insup.template')
11
23
  FileUtils.cp(template_file, File.join(dir, '.insup'))
12
24
  end
13
25
 
14
- def self.list_locations
15
- puts Insup::Settings.instance.tracked_locations
26
+ def tracked_locations
27
+ @settings.tracked_locations
16
28
  end
17
29
 
18
- def self.list_files(options = {})
30
+ def files(options = {})
19
31
  files = case options[:mode]
20
32
  when nil
21
33
  tracker.tracked_files
@@ -24,85 +36,61 @@ module Insup
24
36
  when :ignored
25
37
  tracker.ignored_files
26
38
  end
27
-
28
- puts files
29
39
  end
30
40
 
31
- def self.uploader
32
- @uploader ||= if uploader_conf = Settings.instance.uploader
33
- klass = Insup::Uploader.find_uploader(uploader_conf['class']) || Object::const_get(uploader_conf['class'])
34
- klass.new(uploader_conf)
41
+ def commit(files = nil)
42
+ if files.nil? || files.empty?
43
+ list = changes
35
44
  else
36
- Uploader::Dummy.new({})
45
+ list = files.map do |f|
46
+ mode = File.exist?(f) ? TrackedFile::MODIFIED : TrackedFile::DELETED
47
+ TrackedFile.new(f, mode)
48
+ end
49
+ end
50
+
51
+ list.each do |file|
52
+ uploader.process_file(file)
37
53
  end
38
54
  end
39
55
 
40
- def self.tracker
41
- @tracker ||= if tracker_conf = Settings.instance.tracker
42
- klass = Insup::Tracker.find_tracker(tracker_conf['class']) || Object::const_get(tracker_conf['class'])
43
- klass.new(tracker_conf)
56
+ def uploader
57
+ @uploader ||= if uploader_conf = @settings.uploader
58
+ klass = Insup::Uploader.find_uploader(uploader_conf['class']) || Object::const_get(uploader_conf['class'])
59
+ klass.new(@settings)
44
60
  else
45
- Tracker::SimpleTracker.new({})
61
+ Uploader::Dummy.new(@settings)
46
62
  end
47
63
  end
48
64
 
49
- def self.commit(changed_files = nil)
50
- begin
51
- changed_files ||= get_changes
52
- uploader = get_uploader
53
- uploader.process_all changed_files
54
- rescue => ex
55
- puts ex
65
+ def tracker
66
+ @tracker ||= if tracker_conf = @settings.tracker
67
+ klass = Insup::Tracker.find_tracker(tracker_conf['class']) || Object::const_get(tracker_conf['class'])
68
+ klass.new(@base, @settings)
69
+ else
70
+ Tracker::SimpleTracker.new(@settings)
56
71
  end
57
72
  end
58
73
 
59
- def self.status
60
- tracker.changes.each do |x|
61
- case x.state
62
- when Insup::TrackedFile::NEW
63
- puts "New: #{x.path}".green
64
- when Insup::TrackedFile::MODIFIED
65
- puts "Modified: #{x.path}".yellow
66
- when Insup::TrackedFile::DELETED
67
- puts "Deleted: #{x.path}".red
68
- end
69
- end
74
+ def insales
75
+ @insales ||= Insales.new(@settings)
70
76
  end
71
77
 
72
- def self.print_config
73
- puts "Tracker: #{Insup::Settings.instance.tracker['class']}"
74
- puts "Uploader: #{Insup::Settings.instance.uploader['class']}"
75
- puts 'Tracked locations:'
76
- puts Settings.instance.tracked_locations.map{|loc| "\t#{loc}"}
77
- puts 'Ignore patterns:'
78
- puts Settings.instance.ignore_patterns.map{|ip| "\t#{ip}"}
78
+ def changes
79
+ tracker.changes
79
80
  end
80
81
 
81
- def self.listen
82
- puts 'Listening...'
83
- listener = Listener.new(Dir.getwd)
82
+ def listen
83
+ @listener = Listener.new(@base, @settings)
84
84
 
85
- listener.listen do |changes|
85
+ @listener.listen do |changes|
86
86
  changes.each do |change|
87
- case change.state
88
- when Insup::TrackedFile::DELETED
89
- uploader.remove_file(change)
90
- else
91
- uploader.upload_file(change)
92
- end
87
+ uploader.process_file(change)
93
88
  end
94
89
  end
90
+ end
95
91
 
96
- exit_requested = false
97
- Kernel.trap( "INT" ) { exit_requested = true }
98
-
99
- while !exit_requested do
100
- sleep 0.1
101
- end
102
-
103
- puts 'Stopping listener...'
104
- listener.stop
105
- puts 'Terminated by user'
92
+ def stop_listening
93
+ @listener.stop
106
94
  end
107
95
 
108
96
  end
@@ -0,0 +1,20 @@
1
+ require_relative '../../../spec_helper'
2
+
3
+ describe 'Insup::Console::UploadObserver' do
4
+
5
+ it 'should handle all types of events' do
6
+ @observer = Insup::Console::UploadObserver.new
7
+
8
+ [Insup::Uploader::CREATING_FILE,
9
+ Insup::Uploader::CREATED_FILE,
10
+ Insup::Uploader::MODIFYING_FILE,
11
+ Insup::Uploader::MODIFIED_FILE,
12
+ Insup::Uploader::DELETING_FILE,
13
+ Insup::Uploader::DELETED_FILE,
14
+ Insup::Uploader::BATCH_UPLOADING_FILES,
15
+ Insup::Uploader::BATCH_UPLOADED_FILES].each do |event|
16
+ expect {@observer.update(event, Insup::TrackedFile.new('path/to.file'))}.not_to raise_error
17
+ end
18
+ end
19
+
20
+ end
data/spec/spec_helper.rb CHANGED
@@ -3,3 +3,4 @@ require 'coveralls'
3
3
  Coveralls.wear!
4
4
 
5
5
  require_relative('../lib/insup')
6
+ require_relative('../lib/insup/console')
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: insup
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: '0.2'
5
5
  platform: ruby
6
6
  authors:
7
7
  - HttpLab
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-05-04 00:00:00.000000000 Z
12
+ date: 2014-06-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: colorize
@@ -26,19 +26,19 @@ dependencies:
26
26
  - !ruby/object:Gem::Version
27
27
  version: '0.7'
28
28
  - !ruby/object:Gem::Dependency
29
- name: trollop
29
+ name: gli
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
32
  - - "~>"
33
33
  - !ruby/object:Gem::Version
34
- version: '2.0'
34
+ version: '2.10'
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - "~>"
40
40
  - !ruby/object:Gem::Version
41
- version: '2.0'
41
+ version: '2.10'
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: listen
44
44
  requirement: !ruby/object:Gem::Requirement
@@ -59,14 +59,14 @@ dependencies:
59
59
  requirements:
60
60
  - - "~>"
61
61
  - !ruby/object:Gem::Version
62
- version: '0.1'
62
+ version: '0.2'
63
63
  type: :runtime
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
67
  - - "~>"
68
68
  - !ruby/object:Gem::Version
69
- version: '0.1'
69
+ version: '0.2'
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: activeresource
72
72
  requirement: !ruby/object:Gem::Requirement
@@ -89,16 +89,19 @@ extensions: []
89
89
  extra_rdoc_files: []
90
90
  files:
91
91
  - ".gitignore"
92
- - ".insup.template"
93
92
  - ".rspec"
94
93
  - ".ruby-version"
95
94
  - ".travis.yml"
96
95
  - Gemfile
97
96
  - Gemfile.lock
97
+ - LICENSE
98
98
  - README.md
99
99
  - bin/insup
100
100
  - insup.gemspec
101
+ - insup.template
101
102
  - lib/insup.rb
103
+ - lib/insup/console.rb
104
+ - lib/insup/console/upload_observer.rb
102
105
  - lib/insup/exceptions.rb
103
106
  - lib/insup/git.rb
104
107
  - lib/insup/insales.rb
@@ -115,6 +118,7 @@ files:
115
118
  - lib/insup/uploader/dummy_uploader.rb
116
119
  - lib/insup/uploader/insales_uploader.rb
117
120
  - lib/insup/version.rb
121
+ - spec/lib/insup/console/upload_observer_spec.rb
118
122
  - spec/lib/insup/git_spec.rb
119
123
  - spec/lib/insup/settings_spec.rb
120
124
  - spec/lib/insup/tracker_spec.rb
data/.insup.template DELETED
@@ -1,23 +0,0 @@
1
- track:
2
- - media
3
- - snippets
4
- - templates
5
-
6
- tracker:
7
- class: git
8
-
9
- insales:
10
- subdomain:
11
- api_key:
12
- password:
13
-
14
- uploader:
15
- class: insales
16
- theme_id:
17
-
18
- ignore:
19
- - '*.swp'
20
- - '*.swx'
21
- - '.*'
22
- - 'thumbs.db'
23
- - '.DS_Store'