insup 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.insup.template +23 -0
- data/.rspec +3 -0
- data/.ruby-version +1 -0
- data/.travis.yml +10 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +91 -0
- data/README.md +90 -0
- data/bin/insup +67 -0
- data/insup.gemspec +29 -0
- data/lib/insup/exceptions.rb +5 -0
- data/lib/insup/git.rb +113 -0
- data/lib/insup/insales/asset.rb +5 -0
- data/lib/insup/insales/base.rb +17 -0
- data/lib/insup/insales/theme.rb +5 -0
- data/lib/insup/insales.rb +33 -0
- data/lib/insup/listener.rb +84 -0
- data/lib/insup/settings.rb +39 -0
- data/lib/insup/tracked_file.rb +12 -0
- data/lib/insup/tracker/git_tracker.rb +35 -0
- data/lib/insup/tracker/simple_tracker.rb +12 -0
- data/lib/insup/tracker.rb +62 -0
- data/lib/insup/uploader/dummy_uploader.rb +24 -0
- data/lib/insup/uploader/insales_uploader.rb +135 -0
- data/lib/insup/uploader.rb +26 -0
- data/lib/insup/version.rb +3 -0
- data/lib/insup.rb +119 -0
- data/spec/lib/insup/git_spec.rb +7 -0
- data/spec/lib/insup/settings_spec.rb +24 -0
- data/spec/lib/insup/tracker_spec.rb +9 -0
- data/spec/lib/insup/uploader/insales_uploader_spec.rb +5 -0
- data/spec/lib/insup_spec.rb +5 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/support/.insup +18 -0
- metadata +149 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 865c49f6dd236ccef3027dc04084c735b87f525a
|
4
|
+
data.tar.gz: 97b3f43e5fa341d031b8f05e8fabfa26bd51f862
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e601f6a59cd8c163c34bc9e1448417c35db3abab1ae781f1753f40120161348a339d6299b8c736f63321c9b5e457a847ad75f6276ef1a5d76a86546d4fbf7382
|
7
|
+
data.tar.gz: 3e7e51c70057e53e8d62d6f5b0b6e9d286d1f94105ca07b7a69e4f568dc15f67958a51f1b38b97db2225cfae8dc646331a8524aa92670ca4db771f3e7fe6ba0d
|
data/.gitignore
ADDED
data/.insup.template
ADDED
@@ -0,0 +1,23 @@
|
|
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'
|
data/.rspec
ADDED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.1.1
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
insup (0.1.2)
|
5
|
+
activeresource (~> 4.0)
|
6
|
+
colorize (~> 0.7)
|
7
|
+
listen (~> 2.7)
|
8
|
+
match_files (~> 0.1)
|
9
|
+
trollop (~> 2.0)
|
10
|
+
|
11
|
+
GEM
|
12
|
+
remote: https://rubygems.org/
|
13
|
+
specs:
|
14
|
+
activemodel (4.1.0)
|
15
|
+
activesupport (= 4.1.0)
|
16
|
+
builder (~> 3.1)
|
17
|
+
activeresource (4.0.0)
|
18
|
+
activemodel (~> 4.0)
|
19
|
+
activesupport (~> 4.0)
|
20
|
+
rails-observers (~> 0.1.1)
|
21
|
+
activesupport (4.1.0)
|
22
|
+
i18n (~> 0.6, >= 0.6.9)
|
23
|
+
json (~> 1.7, >= 1.7.7)
|
24
|
+
minitest (~> 5.1)
|
25
|
+
thread_safe (~> 0.1)
|
26
|
+
tzinfo (~> 1.1)
|
27
|
+
builder (3.2.2)
|
28
|
+
celluloid (0.15.2)
|
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)
|
34
|
+
coveralls (0.7.0)
|
35
|
+
multi_json (~> 1.3)
|
36
|
+
rest-client
|
37
|
+
simplecov (>= 0.7)
|
38
|
+
term-ansicolor
|
39
|
+
thor
|
40
|
+
diff-lcs (1.2.5)
|
41
|
+
docile (1.1.3)
|
42
|
+
ffi (1.9.3)
|
43
|
+
i18n (0.6.9)
|
44
|
+
json (1.8.1)
|
45
|
+
listen (2.7.2)
|
46
|
+
celluloid (>= 0.15.2)
|
47
|
+
celluloid-io (>= 0.15.0)
|
48
|
+
rb-fsevent (>= 0.9.3)
|
49
|
+
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)
|
55
|
+
rails-observers (0.1.2)
|
56
|
+
activemodel (~> 4.0)
|
57
|
+
rb-fsevent (0.9.4)
|
58
|
+
rb-inotify (0.9.4)
|
59
|
+
ffi (>= 0.5.0)
|
60
|
+
rest-client (1.6.7)
|
61
|
+
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)
|
70
|
+
simplecov (0.8.2)
|
71
|
+
docile (~> 1.1.0)
|
72
|
+
multi_json
|
73
|
+
simplecov-html (~> 0.8.0)
|
74
|
+
simplecov-html (0.8.0)
|
75
|
+
term-ansicolor (1.3.0)
|
76
|
+
tins (~> 1.0)
|
77
|
+
thor (0.19.1)
|
78
|
+
thread_safe (0.3.3)
|
79
|
+
timers (1.1.0)
|
80
|
+
tins (1.1.0)
|
81
|
+
trollop (2.0)
|
82
|
+
tzinfo (1.1.0)
|
83
|
+
thread_safe (~> 0.1)
|
84
|
+
|
85
|
+
PLATFORMS
|
86
|
+
ruby
|
87
|
+
|
88
|
+
DEPENDENCIES
|
89
|
+
coveralls
|
90
|
+
insup!
|
91
|
+
rspec
|
data/README.md
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
# Insup
|
2
|
+
|
3
|
+
[![Build Status](https://travis-ci.org/httplab/insup.svg?branch=master)](https://travis-ci.org/httplab/insup)
|
4
|
+
[![Gem Version](https://badge.fury.io/rb/insup.svg)](http://badge.fury.io/rb/insup)
|
5
|
+
[![Coverage Status](https://coveralls.io/repos/httplab/insup/badge.png)](https://coveralls.io/r/httplab/insup)
|
6
|
+
[![Code Climate](https://codeclimate.com/github/httplab/insup.png)](https://codeclimate.com/github/httplab/insup)
|
7
|
+
[![Dependency Status](https://gemnasium.com/httplab/insup.svg)](https://gemnasiurm.com/httplab/insup)
|
8
|
+
|
9
|
+
## Description
|
10
|
+
|
11
|
+
Insup Insales theme uploader.
|
12
|
+
|
13
|
+
## Installation
|
14
|
+
|
15
|
+
```bash
|
16
|
+
gem install insup
|
17
|
+
```
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
### Preparing
|
22
|
+
|
23
|
+
Enter the directory you want to sync with the remote service. Then type `insup init` to initialize your working directory with **.insup** file that holds all neccessary Insup configuration.
|
24
|
+
|
25
|
+
Open **.insup** file with your favourite text editor and modify the configuration according to your needs.
|
26
|
+
|
27
|
+
### Configuration
|
28
|
+
**.insup** file is a YAML file. Here's a list of the configuration options.
|
29
|
+
|
30
|
+
* **track** section is an array of directories which you want to track for changes. Specify locations relative to the working directory
|
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.
|
34
|
+
* **insales** secion holds information for connecting to Insales shop. To use insales features you should specify `subdomain`, `api_key` and `password` parameters.
|
35
|
+
|
36
|
+
#### Trackers
|
37
|
+
|
38
|
+
Currently there are two trackers available:
|
39
|
+
|
40
|
+
* **Git tracker** finds changes in the working directory using Git index. This tracker will operate only if the working dir is a Git repository. Select this tracker by specifying `Insup::Tracker::GitTracker` or `git` in the `class` section of the tracker configuration.
|
41
|
+
* **Simple tracker** will always consider all files in the working directory modified (except the ignored ones). Specify `Insup::Tracker::SimpleTracker` or `simple` ins the `class` section.
|
42
|
+
|
43
|
+
#### Uploaders
|
44
|
+
|
45
|
+
Currently there are two uploaders available:
|
46
|
+
|
47
|
+
* **Insales uploader** will upload files to the specified Insales theme. Specify `Insup::Uploader::Insales` or `insales` in the `class` section of the uploader configuration. Insales uploader also requires `theme_id` to be specified. Working directory should include 3 subfolders *media*, *snippets* and *templates*. The same 3 folders should be specified in the `track` sectio of .insup file.
|
48
|
+
|
49
|
+
* **Dummy uploader** will only print its operations to the console without actually uploading anything. It can be used for testing the configuration. Use by specifying `dummy` or `Insup::Uploader::Dummy` in the `class` section.
|
50
|
+
|
51
|
+
### Operation modes
|
52
|
+
|
53
|
+
#### Listen mode
|
54
|
+
|
55
|
+
In this mode Insup will continuously listen to the changes in tracked locations and upload the changes immidiately. It will use the specified uploader, but the tracker is ignored. Listen mode will only watch files that do not match ignore patterns.
|
56
|
+
|
57
|
+
Activate listen mode by typing
|
58
|
+
```bash
|
59
|
+
insup listen
|
60
|
+
```
|
61
|
+
in your working directory.
|
62
|
+
|
63
|
+
|
64
|
+
#### Track mode
|
65
|
+
|
66
|
+
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
|
+
|
68
|
+
Print working directory status accroding to the selected tracker
|
69
|
+
```bash
|
70
|
+
insup status
|
71
|
+
```
|
72
|
+
|
73
|
+
Upload changes
|
74
|
+
```bash
|
75
|
+
insup commit [file1 [file2 [file3 [...]]]]
|
76
|
+
```
|
77
|
+
Call `commit` command with the file list to upload only files specified.
|
78
|
+
|
79
|
+
### Other commands
|
80
|
+
|
81
|
+
List all themes in the Insales shop if `insales` section is given in the .insup file:
|
82
|
+
```bash
|
83
|
+
insup insales list-themes
|
84
|
+
```
|
85
|
+
|
86
|
+
List files under tracked locations:
|
87
|
+
```bash
|
88
|
+
insup list-files [--all|--ignored]
|
89
|
+
```
|
90
|
+
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.
|
data/bin/insup
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'trollop'
|
4
|
+
|
5
|
+
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
|
24
|
+
end
|
25
|
+
|
26
|
+
cmd = ARGV.shift
|
27
|
+
|
28
|
+
if cmd.nil?
|
29
|
+
raise Trollop::HelpNeeded
|
30
|
+
end
|
31
|
+
|
32
|
+
if(!SUB_COMMANDS.include? cmd)
|
33
|
+
Trollop::die "unknown subcommand #{cmd.inspect}"
|
34
|
+
end
|
35
|
+
|
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)
|
49
|
+
else
|
50
|
+
Insup.list_files
|
51
|
+
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
|
63
|
+
end
|
64
|
+
end
|
65
|
+
rescue => ex
|
66
|
+
puts ex.message
|
67
|
+
end
|
data/insup.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require File.expand_path("../lib/insup/version", __FILE__)
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = 'insup'
|
5
|
+
s.version = Insup::VERSION
|
6
|
+
s.platform = Gem::Platform::RUBY
|
7
|
+
s.date = Date.today.to_s
|
8
|
+
|
9
|
+
s.summary = 'InSales theme uploader.'
|
10
|
+
s.description = 'Utility for automatic upload of InSales theme files.'
|
11
|
+
s.authors = ['HttpLab', 'Nu-hin']
|
12
|
+
s.email = 'nuinuhin@gmail.com'
|
13
|
+
s.homepage = 'https://github.com/httplab/insup'
|
14
|
+
s.license = 'MIT'
|
15
|
+
|
16
|
+
s.add_dependency 'colorize', '~> 0.7'
|
17
|
+
s.add_dependency 'trollop', '~> 2.0'
|
18
|
+
s.add_dependency 'listen', '~> 2.7'
|
19
|
+
s.add_dependency 'match_files', '~> 0.1'
|
20
|
+
s.add_dependency 'activeresource', '~> 4.0'
|
21
|
+
|
22
|
+
s.files = `git ls-files`.split("\n")
|
23
|
+
s.bindir = 'bin'
|
24
|
+
s.test_files = `git ls-files -- {spec}/*`.split("\n")
|
25
|
+
s.require_paths = ["lib"]
|
26
|
+
s.executables << 'insup'
|
27
|
+
|
28
|
+
s.post_install_message = "type 'insup help' for help"
|
29
|
+
end
|
data/lib/insup/git.rb
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
class Insup::Git
|
2
|
+
|
3
|
+
def initialize(base)
|
4
|
+
Dir.chdir(base) do
|
5
|
+
`git status 2>&1`
|
6
|
+
|
7
|
+
if $?.exitstatus == 128
|
8
|
+
raise Insup::Exceptions::NotAGitRepositoryError, 'Not a GIT repository'
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
@base = base
|
13
|
+
end
|
14
|
+
|
15
|
+
def status
|
16
|
+
files = ls_files
|
17
|
+
ignore = ignored_files
|
18
|
+
|
19
|
+
Dir.chdir(@base) do
|
20
|
+
Dir.glob('**/*', File::FNM_DOTMATCH) do |file|
|
21
|
+
next if files[file] || File.directory?(file) || ignore.include?(file) || file =~ /^.git\/.+/
|
22
|
+
files[file] = {:path => file, :untracked => true}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
diff_files.each do |path, data|
|
27
|
+
files[path] ? files[path].merge!(data) : files[path] = data
|
28
|
+
end
|
29
|
+
|
30
|
+
diff_index('HEAD').each do |path, data|
|
31
|
+
files[path] ? files[path].merge!(data) : files[path] = data
|
32
|
+
end
|
33
|
+
|
34
|
+
files.each do |k, file_hash|
|
35
|
+
file_hash
|
36
|
+
end
|
37
|
+
|
38
|
+
files
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def ignored_files
|
44
|
+
command_lines('ls-files', ['--others', '-i', '--exclude-standard'])
|
45
|
+
end
|
46
|
+
|
47
|
+
def ls_files
|
48
|
+
hsh = {}
|
49
|
+
command_lines('ls-files', ['--stage']).each do |line|
|
50
|
+
(info, file) = line.split("\t")
|
51
|
+
(mode, sha, stage) = info.split
|
52
|
+
file = eval(file) if file =~ /^\".*\"$/
|
53
|
+
hsh[file] = {:path => file, :stage => stage}
|
54
|
+
end
|
55
|
+
hsh
|
56
|
+
end
|
57
|
+
|
58
|
+
def command_lines(cmd, opts = [])
|
59
|
+
command(cmd, opts).split("\n")
|
60
|
+
end
|
61
|
+
|
62
|
+
def command(cmd, opts = [])
|
63
|
+
opts = [opts].flatten.map {|s| escape(s) }.join(' ')
|
64
|
+
git_cmd = "git #{cmd} #{opts} 2>&1"
|
65
|
+
out = nil
|
66
|
+
|
67
|
+
if Dir.getwd != @base
|
68
|
+
Dir.chdir(@base) { out = `#{git_cmd}` }
|
69
|
+
else
|
70
|
+
out = `#{git_cmd}`
|
71
|
+
end
|
72
|
+
|
73
|
+
if $?.exitstatus > 0
|
74
|
+
if $?.exitstatus == 1 && out == ''
|
75
|
+
return ''
|
76
|
+
end
|
77
|
+
|
78
|
+
raise 'git error'
|
79
|
+
end
|
80
|
+
out
|
81
|
+
end
|
82
|
+
|
83
|
+
def diff_files
|
84
|
+
diff_as_hash('diff-files')
|
85
|
+
end
|
86
|
+
|
87
|
+
def diff_index(treeish)
|
88
|
+
diff_as_hash('diff-index', treeish)
|
89
|
+
end
|
90
|
+
|
91
|
+
def diff_as_hash(diff_command, opts=[])
|
92
|
+
command_lines(diff_command, opts).inject({}) do |memo, line|
|
93
|
+
info, file = line.split("\t")
|
94
|
+
mode_src, mode_dest, sha_src, sha_dest, type = info.split
|
95
|
+
|
96
|
+
memo[file] = {
|
97
|
+
# :mode_index => mode_dest,
|
98
|
+
# :mode_repo => mode_src.to_s[1, 7],
|
99
|
+
:path => file,
|
100
|
+
# :sha_repo => sha_src,
|
101
|
+
# :sha_index => sha_dest,
|
102
|
+
:type => type
|
103
|
+
}
|
104
|
+
|
105
|
+
memo
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def escape(s)
|
110
|
+
"'#{s && s.to_s.gsub('\'','\'"\'"\'')}'"
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class Insup::Insales::Base < ActiveResource::Base
|
2
|
+
self.headers['User-Agent'] = %W(
|
3
|
+
insup/#{Insup::VERSION}
|
4
|
+
ActiveResource/#{ActiveResource::VERSION::STRING}
|
5
|
+
Ruby/#{RUBY_VERSION}
|
6
|
+
).join(' ')
|
7
|
+
|
8
|
+
self.format = :xml
|
9
|
+
self.prefix = '/admin/'
|
10
|
+
|
11
|
+
def self.configure(api_key, domain, password)
|
12
|
+
self.user = api_key
|
13
|
+
self.site = "http://#{domain}"
|
14
|
+
self.password = password
|
15
|
+
self
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Insup::Insales
|
2
|
+
|
3
|
+
def self.configure_api
|
4
|
+
@config = Insup::Settings.instance.insales;
|
5
|
+
|
6
|
+
return false if @config.nil?
|
7
|
+
|
8
|
+
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'])
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.list_themes
|
17
|
+
configure_api
|
18
|
+
themes = Theme.all
|
19
|
+
themes.each do |theme|
|
20
|
+
puts "#{theme.id}\t#{theme.title}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def print_config
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
require 'active_resource'
|
31
|
+
require_relative 'insales/base'
|
32
|
+
require_relative 'insales/theme'
|
33
|
+
require_relative 'insales/asset'
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'listen'
|
2
|
+
|
3
|
+
class Listener
|
4
|
+
|
5
|
+
def initialize(base)
|
6
|
+
@base = base
|
7
|
+
end
|
8
|
+
|
9
|
+
def listen(&block)
|
10
|
+
return if @listener
|
11
|
+
|
12
|
+
@listener = Listen.to(tracked_locations) do |modified, added, removed|
|
13
|
+
flags = {}
|
14
|
+
|
15
|
+
added.each do |file|
|
16
|
+
flags[file] = flags[file] ? flags[file] | 4 : 4
|
17
|
+
end
|
18
|
+
|
19
|
+
modified.each do |file|
|
20
|
+
flags[file] = flags[file] ? flags[file] | 2 : 2
|
21
|
+
end
|
22
|
+
|
23
|
+
removed.each do |file|
|
24
|
+
flags[file] = flags[file] ? flags[file] | 1 : 1
|
25
|
+
end
|
26
|
+
|
27
|
+
res = []
|
28
|
+
|
29
|
+
flags.each do |f, flags|
|
30
|
+
pn = Pathname.new(f)
|
31
|
+
basepn = Pathname.new(@base)
|
32
|
+
file = pn.relative_path_from(basepn).to_s
|
33
|
+
|
34
|
+
next if ignore_matcher.matched?(file)
|
35
|
+
|
36
|
+
case flags
|
37
|
+
when 1
|
38
|
+
res << Insup::TrackedFile.new(file, Insup::TrackedFile::DELETED)
|
39
|
+
when 2
|
40
|
+
res << Insup::TrackedFile.new(file, Insup::TrackedFile::MODIFIED)
|
41
|
+
when 3
|
42
|
+
res << Insup::TrackedFile.new(file, Insup::TrackedFile::DELETED)
|
43
|
+
when 4
|
44
|
+
res << Insup::TrackedFile.new(file, Insup::TrackedFile::NEW)
|
45
|
+
when 5
|
46
|
+
if File.exist?(file)
|
47
|
+
res << Insup::TrackedFile.new(file, Insup::TrackedFile::UNSURE)
|
48
|
+
end
|
49
|
+
when 6
|
50
|
+
res << Insup::TrackedFile.new(file, Insup::TrackedFile::NEW)
|
51
|
+
when 7
|
52
|
+
if File.exist?(file)
|
53
|
+
res << Insup::TrackedFile.new(file, Insup::TrackedFile::UNSURE)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
yield res
|
59
|
+
end
|
60
|
+
|
61
|
+
@listener.start
|
62
|
+
end
|
63
|
+
|
64
|
+
def stop
|
65
|
+
if @listener
|
66
|
+
@listener.stop
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
protected
|
71
|
+
|
72
|
+
def ignore_matcher
|
73
|
+
@ignore_matcher ||= ::MatchFiles.git(@base, ignore_patterns)
|
74
|
+
end
|
75
|
+
|
76
|
+
def tracked_locations
|
77
|
+
@track = ::Insup::Settings.instance.tracked_locations
|
78
|
+
end
|
79
|
+
|
80
|
+
def ignore_patterns
|
81
|
+
@ignore_patterns ||= ::Insup::Settings.instance.ignore_patterns
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
class Insup::Settings
|
4
|
+
attr_reader :settings
|
5
|
+
|
6
|
+
def self.instance
|
7
|
+
@instance ||= new()
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(filename = '.insup')
|
11
|
+
insupfile = IO.read(filename)
|
12
|
+
@settings = YAML.load(insupfile)
|
13
|
+
end
|
14
|
+
|
15
|
+
def tracked_locations
|
16
|
+
return settings['track'] || []
|
17
|
+
end
|
18
|
+
|
19
|
+
def uploader
|
20
|
+
return settings['uploader']
|
21
|
+
end
|
22
|
+
|
23
|
+
def tracker
|
24
|
+
return settings['tracker']
|
25
|
+
end
|
26
|
+
|
27
|
+
def ignore_patterns
|
28
|
+
return settings['ignore'] || []
|
29
|
+
end
|
30
|
+
|
31
|
+
def insales
|
32
|
+
return settings['insales']
|
33
|
+
end
|
34
|
+
|
35
|
+
def save(filename)
|
36
|
+
File.write(filename, @settings.to_yaml)
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require_relative('../git')
|
2
|
+
|
3
|
+
# Git tracker: tracks files by evaluating changes in Git repo
|
4
|
+
class Insup::Tracker::GitTracker < Insup::Tracker
|
5
|
+
|
6
|
+
tracker :git
|
7
|
+
|
8
|
+
def initialize config = nil
|
9
|
+
super
|
10
|
+
@git = ::Insup::Git.new(@path)
|
11
|
+
end
|
12
|
+
|
13
|
+
protected
|
14
|
+
|
15
|
+
STATUS_MAP = {
|
16
|
+
'A' => Insup::TrackedFile::NEW,
|
17
|
+
'M' => Insup::TrackedFile::MODIFIED,
|
18
|
+
'D' => Insup::TrackedFile::DELETED
|
19
|
+
}
|
20
|
+
|
21
|
+
def raw_changes
|
22
|
+
changed = @git.status.select do |x,v|
|
23
|
+
v[:untracked] || (['A','M','D'].include? v[:type])
|
24
|
+
end
|
25
|
+
|
26
|
+
changed.map do |x, v|
|
27
|
+
if v[:untracked]
|
28
|
+
Insup::TrackedFile.new v[:path], Insup::TrackedFile::NEW
|
29
|
+
else
|
30
|
+
Insup::TrackedFile.new v[:path], STATUS_MAP[v[:type]]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# Simple tracker: will list all tracked files as changed
|
2
|
+
class Insup::Tracker::SimpleTracker < Insup::Tracker
|
3
|
+
|
4
|
+
tracker :simple
|
5
|
+
|
6
|
+
def raw_changes
|
7
|
+
tracked_files.map do |p|
|
8
|
+
Insup::TrackedFile.new(p, Insup::TrackedFile::MODIFIED)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require('match_files')
|
2
|
+
class Insup::Tracker
|
3
|
+
|
4
|
+
def self.tracker(tracker_alias)
|
5
|
+
@@trackers ||= {}
|
6
|
+
@@trackers[tracker_alias] = self
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.find_tracker(tracker_alias)
|
10
|
+
@@trackers[tracker_alias.to_sym]
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(config = nil)
|
14
|
+
@config = config
|
15
|
+
@path = Dir.getwd
|
16
|
+
end
|
17
|
+
|
18
|
+
# Lists ALL files in the tracked locations whether they are ignored or not
|
19
|
+
def all_files
|
20
|
+
locations = tracked_locations
|
21
|
+
locations.map do |loc|
|
22
|
+
loc_pat = File.join(loc, '**/*')
|
23
|
+
Dir.glob(loc_pat, File::FNM_DOTMATCH)
|
24
|
+
.select{|e| File.file?(e)}
|
25
|
+
end.flatten
|
26
|
+
end
|
27
|
+
|
28
|
+
# Lists ALL tracked files in the tracked locations i. e. all files but ignored
|
29
|
+
def tracked_files
|
30
|
+
all_files.reject{|f| ignore_matcher.matched?(f)}
|
31
|
+
end
|
32
|
+
|
33
|
+
# Lists ALL tracked files in the tracked locations i. e. all files but ignored
|
34
|
+
def ignored_files
|
35
|
+
all_files.select{|f| ignore_matcher.matched?(f)}
|
36
|
+
end
|
37
|
+
|
38
|
+
def changes
|
39
|
+
res = raw_changes.select do |x|
|
40
|
+
tracked_locations.any? do |loc|
|
41
|
+
!ignore_matcher.matched?(x.path) && File.fnmatch(File.join(loc,'/*'), x.path)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
protected
|
47
|
+
|
48
|
+
def raw_changes; end;
|
49
|
+
|
50
|
+
def ignore_matcher
|
51
|
+
@ignore_matcher ||= ::MatchFiles.git(@path, ignore_patterns)
|
52
|
+
end
|
53
|
+
|
54
|
+
def tracked_locations
|
55
|
+
@track = ::Insup::Settings.instance.tracked_locations
|
56
|
+
end
|
57
|
+
|
58
|
+
def ignore_patterns
|
59
|
+
@ignore_patterns ||= ::Insup::Settings.instance.ignore_patterns
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'colorize'
|
2
|
+
|
3
|
+
class Insup::Uploader::DummyUploader < Insup::Uploader
|
4
|
+
|
5
|
+
uploader :dummy
|
6
|
+
|
7
|
+
def upload_file(file)
|
8
|
+
case file.state
|
9
|
+
when Insup::TrackedFile::NEW
|
10
|
+
puts "Creating file #{file.path}".green
|
11
|
+
when Insup::TrackedFile::MODIFIED, Insup::TrackedFile::UNSURE
|
12
|
+
puts "Uploading file #{file.path}".yellow
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def remove_file file
|
17
|
+
puts "Deleting file #{file.path}".red
|
18
|
+
end
|
19
|
+
|
20
|
+
def batch_upload(files)
|
21
|
+
puts "Batch uploading #{files.count} files"
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
require 'base64'
|
2
|
+
require_relative '../insales'
|
3
|
+
|
4
|
+
class Insup::Uploader::InsalesUploader < Insup::Uploader
|
5
|
+
|
6
|
+
uploader :insales
|
7
|
+
|
8
|
+
InsalesUploaderError = Class.new(Insup::Exceptions::UploaderError)
|
9
|
+
|
10
|
+
def initialize(config)
|
11
|
+
super
|
12
|
+
Insup::Insales.configure_api
|
13
|
+
assets_list(true)
|
14
|
+
end
|
15
|
+
|
16
|
+
def upload_file(file)
|
17
|
+
case file.state
|
18
|
+
when Insup::TrackedFile::NEW
|
19
|
+
upload_new_file(file)
|
20
|
+
when Insup::TrackedFile::MODIFIED
|
21
|
+
upload_modified_file(file)
|
22
|
+
when Insup::TrackedFile::UNSURE
|
23
|
+
upload_modified_file(file)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def upload_new_file(file)
|
28
|
+
asset = find_asset(file)
|
29
|
+
|
30
|
+
if !asset.nil?
|
31
|
+
upload_modified_file(file)
|
32
|
+
return
|
33
|
+
end
|
34
|
+
|
35
|
+
puts "Creating #{file.path}".green
|
36
|
+
asset_type = get_asset_type(file.path)
|
37
|
+
|
38
|
+
if(!asset_type)
|
39
|
+
raise InsalesUploaderError, "Cannot determine asset type for file #{file.path}"
|
40
|
+
end
|
41
|
+
|
42
|
+
file_contents = File.read(file.path)
|
43
|
+
|
44
|
+
asset = ::Insup::Insales::Asset.create({
|
45
|
+
name: file.file_name,
|
46
|
+
attachment: Base64.encode64(file_contents),
|
47
|
+
theme_id: @config['theme_id'],
|
48
|
+
type: asset_type
|
49
|
+
})
|
50
|
+
|
51
|
+
assets_list << asset
|
52
|
+
end
|
53
|
+
|
54
|
+
def upload_modified_file(file)
|
55
|
+
asset = find_asset(file)
|
56
|
+
|
57
|
+
if !asset
|
58
|
+
upload_new_file(file)
|
59
|
+
end
|
60
|
+
|
61
|
+
puts "Updating #{file.path}".yellow
|
62
|
+
|
63
|
+
file_contents = File.read(file.path)
|
64
|
+
|
65
|
+
if asset.content_type.start_with? 'text/'
|
66
|
+
asset.update_attribute(:content, file_contents)
|
67
|
+
else
|
68
|
+
remove_file(file)
|
69
|
+
upload_new_file(file)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def remove_file(file)
|
74
|
+
asset = find_asset(file)
|
75
|
+
|
76
|
+
if !asset
|
77
|
+
raise InsalesUploaderError, "Cannot find remote counterpart for file #{file.path}"
|
78
|
+
end
|
79
|
+
|
80
|
+
puts "Deleting #{file.path}".red
|
81
|
+
asset.destroy
|
82
|
+
assets_list.delete(asset)
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
ASSET_TYPE_MAP = {
|
87
|
+
'media/' => 'Asset::Media',
|
88
|
+
'snippets/' => 'Asset::Snippet',
|
89
|
+
'templates/' => 'Asset::Template'
|
90
|
+
}.freeze
|
91
|
+
|
92
|
+
def get_asset_type path
|
93
|
+
res = nil
|
94
|
+
|
95
|
+
ASSET_TYPE_MAP.each do |k,v|
|
96
|
+
if path.start_with? k
|
97
|
+
res = v
|
98
|
+
break
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
res
|
103
|
+
end
|
104
|
+
|
105
|
+
def theme
|
106
|
+
@theme ||= ::Insup::Insales::Theme.find(@config['theme_id'])
|
107
|
+
end
|
108
|
+
|
109
|
+
def find_asset file
|
110
|
+
asset_type = get_asset_type(file.path)
|
111
|
+
|
112
|
+
if(!asset_type)
|
113
|
+
raise InsalesUploaderError, "Cannot determine asset type for file #{file.path}"
|
114
|
+
end
|
115
|
+
|
116
|
+
files = assets_list.select do |el|
|
117
|
+
el.type == asset_type && (el.human_readable_name == file.file_name || el.name == file.file_name)
|
118
|
+
end
|
119
|
+
|
120
|
+
if files && !files.empty?
|
121
|
+
return files.first
|
122
|
+
else
|
123
|
+
return nil
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def assets_list(reload = false)
|
128
|
+
if !@assets_list || reload
|
129
|
+
@assets_list ||= theme.assets.to_a
|
130
|
+
else
|
131
|
+
@assets_list
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class Insup::Uploader
|
2
|
+
|
3
|
+
def self.uploader(uploader_alias)
|
4
|
+
@@uploaders ||= {}
|
5
|
+
@@uploaders[uploader_alias] = self
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.find_uploader(uploader_alias)
|
9
|
+
@@uploaders[uploader_alias.to_sym]
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize config = nil
|
13
|
+
@config = config
|
14
|
+
end
|
15
|
+
|
16
|
+
def upload_file(file); end
|
17
|
+
|
18
|
+
def delete_file(file); end
|
19
|
+
|
20
|
+
def batch_upload(files)
|
21
|
+
files.each do |file|
|
22
|
+
upload_file(file)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
data/lib/insup.rb
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'colorize'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
module Insup
|
5
|
+
|
6
|
+
# Initializes a directory with a default .insup file
|
7
|
+
def self.init(dir = nil)
|
8
|
+
dir ||= Dir.getwd
|
9
|
+
|
10
|
+
template_file = File.join(File.dirname(File.expand_path(__FILE__)), '../.insup.template')
|
11
|
+
FileUtils.cp(template_file, File.join(dir, '.insup'))
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.list_locations
|
15
|
+
puts Insup::Settings.instance.tracked_locations
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.list_files(options = {})
|
19
|
+
files = case options[:mode]
|
20
|
+
when nil
|
21
|
+
tracker.tracked_files
|
22
|
+
when :all
|
23
|
+
tracker.all_files
|
24
|
+
when :ignored
|
25
|
+
tracker.ignored_files
|
26
|
+
end
|
27
|
+
|
28
|
+
puts files
|
29
|
+
end
|
30
|
+
|
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)
|
35
|
+
else
|
36
|
+
Uploader::Dummy.new({})
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
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)
|
44
|
+
else
|
45
|
+
Tracker::SimpleTracker.new({})
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
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
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
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
|
70
|
+
end
|
71
|
+
|
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}"}
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.listen
|
82
|
+
puts 'Listening...'
|
83
|
+
listener = Listener.new(Dir.getwd)
|
84
|
+
|
85
|
+
listener.listen do |changes|
|
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
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
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'
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
require_relative 'insup/exceptions.rb'
|
111
|
+
require_relative 'insup/settings.rb'
|
112
|
+
require_relative 'insup/tracked_file.rb'
|
113
|
+
require_relative 'insup/tracker.rb'
|
114
|
+
require_relative 'insup/tracker/git_tracker.rb'
|
115
|
+
require_relative 'insup/tracker/simple_tracker.rb'
|
116
|
+
require_relative 'insup/listener.rb'
|
117
|
+
require_relative 'insup/uploader.rb'
|
118
|
+
require_relative 'insup/uploader/dummy_uploader.rb'
|
119
|
+
require_relative 'insup/uploader/insales_uploader.rb'
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require_relative '../../spec_helper'
|
2
|
+
|
3
|
+
describe 'Insup::Settings' do
|
4
|
+
before(:each) do
|
5
|
+
@settings = Insup::Settings.new('spec/support/.insup')
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'should have correct tracked locations' do
|
9
|
+
expect(['media', 'templates', 'snippets'] - @settings.tracked_locations).to be_empty
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'should have correct tracker' do
|
13
|
+
expect(@settings.tracker['class']).to eq ('Insup::Tracker::GitTracker')
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should have correct uploader' do
|
17
|
+
expect(@settings.uploader['class']).to eq ('Insup::Uploader::InsalesUploader')
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should have correct ignore paths' do
|
21
|
+
expect(@settings.ignore_patterns).to include('*.swp')
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
data/spec/spec_helper.rb
ADDED
data/spec/support/.insup
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
track:
|
2
|
+
- media
|
3
|
+
- snippets
|
4
|
+
- templates
|
5
|
+
|
6
|
+
tracker:
|
7
|
+
class: Insup::Tracker::GitTracker
|
8
|
+
|
9
|
+
uploader:
|
10
|
+
class: Insup::Uploader::InsalesUploader
|
11
|
+
subdomain: subdomain.myinsales.ru
|
12
|
+
password: password
|
13
|
+
api_key: apikey
|
14
|
+
|
15
|
+
ignore:
|
16
|
+
- '*.swp'
|
17
|
+
- '*.swx'
|
18
|
+
- '.*'
|
metadata
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: insup
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- HttpLab
|
8
|
+
- Nu-hin
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2014-05-04 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: colorize
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '0.7'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '0.7'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: trollop
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '2.0'
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '2.0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: listen
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - "~>"
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '2.7'
|
49
|
+
type: :runtime
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - "~>"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '2.7'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: match_files
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - "~>"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0.1'
|
63
|
+
type: :runtime
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0.1'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: activeresource
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - "~>"
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '4.0'
|
77
|
+
type: :runtime
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - "~>"
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '4.0'
|
84
|
+
description: Utility for automatic upload of InSales theme files.
|
85
|
+
email: nuinuhin@gmail.com
|
86
|
+
executables:
|
87
|
+
- insup
|
88
|
+
extensions: []
|
89
|
+
extra_rdoc_files: []
|
90
|
+
files:
|
91
|
+
- ".gitignore"
|
92
|
+
- ".insup.template"
|
93
|
+
- ".rspec"
|
94
|
+
- ".ruby-version"
|
95
|
+
- ".travis.yml"
|
96
|
+
- Gemfile
|
97
|
+
- Gemfile.lock
|
98
|
+
- README.md
|
99
|
+
- bin/insup
|
100
|
+
- insup.gemspec
|
101
|
+
- lib/insup.rb
|
102
|
+
- lib/insup/exceptions.rb
|
103
|
+
- lib/insup/git.rb
|
104
|
+
- lib/insup/insales.rb
|
105
|
+
- lib/insup/insales/asset.rb
|
106
|
+
- lib/insup/insales/base.rb
|
107
|
+
- lib/insup/insales/theme.rb
|
108
|
+
- lib/insup/listener.rb
|
109
|
+
- lib/insup/settings.rb
|
110
|
+
- lib/insup/tracked_file.rb
|
111
|
+
- lib/insup/tracker.rb
|
112
|
+
- lib/insup/tracker/git_tracker.rb
|
113
|
+
- lib/insup/tracker/simple_tracker.rb
|
114
|
+
- lib/insup/uploader.rb
|
115
|
+
- lib/insup/uploader/dummy_uploader.rb
|
116
|
+
- lib/insup/uploader/insales_uploader.rb
|
117
|
+
- lib/insup/version.rb
|
118
|
+
- spec/lib/insup/git_spec.rb
|
119
|
+
- spec/lib/insup/settings_spec.rb
|
120
|
+
- spec/lib/insup/tracker_spec.rb
|
121
|
+
- spec/lib/insup/uploader/insales_uploader_spec.rb
|
122
|
+
- spec/lib/insup_spec.rb
|
123
|
+
- spec/spec_helper.rb
|
124
|
+
- spec/support/.insup
|
125
|
+
homepage: https://github.com/httplab/insup
|
126
|
+
licenses:
|
127
|
+
- MIT
|
128
|
+
metadata: {}
|
129
|
+
post_install_message: type 'insup help' for help
|
130
|
+
rdoc_options: []
|
131
|
+
require_paths:
|
132
|
+
- lib
|
133
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
134
|
+
requirements:
|
135
|
+
- - ">="
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '0'
|
138
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
139
|
+
requirements:
|
140
|
+
- - ">="
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: '0'
|
143
|
+
requirements: []
|
144
|
+
rubyforge_project:
|
145
|
+
rubygems_version: 2.2.2
|
146
|
+
signing_key:
|
147
|
+
specification_version: 4
|
148
|
+
summary: InSales theme uploader.
|
149
|
+
test_files: []
|