woro 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +7 -0
- data/README.md +33 -23
- data/bin/woro +53 -29
- data/lib/capistrano/woro.rb +1 -0
- data/lib/woro.rb +3 -1
- data/lib/woro/adapters/gist.rb +82 -0
- data/lib/woro/configuration.rb +13 -3
- data/lib/woro/task.rb +8 -40
- data/lib/woro/task_helper.rb +39 -0
- data/lib/woro/tasks/capistrano.rake +28 -55
- data/lib/woro/tasks/mina.rake +9 -3
- data/lib/woro/version.rb +1 -1
- data/spec/fixtures/fresh_template.yml +6 -0
- data/spec/fixtures/gist.json +103 -0
- data/spec/lib/woro/adapters/gist_spec.rb +62 -0
- data/spec/lib/woro/configuration_spec.rb +103 -0
- data/spec/lib/woro/task_spec.rb +33 -0
- data/spec/spec_helper.rb +25 -0
- data/woro.gemspec +0 -2
- metadata +18 -32
- data/lib/woro/gister.rb +0 -45
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9280b0c23821f1b2f349fb0653519a738e12640b
|
4
|
+
data.tar.gz: 9a96cbb374926861269b29bfbc7536b966478a79
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bab818aa8921e7c73e0f7cd124550336fb35c25f8e725e21056e5cc197787da6d76e06225252a3e35798f8548f977c9f10dfcd3c8570106e859015fb831b74d0
|
7
|
+
data.tar.gz: f73111d88b02d1e23e25a588d718b2d42862e5bccc02493a8318c5d6a666ccd229c0b809972e92ba9893a801a97559b5183acf79734816f0de8bce886f6d5dfd
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
Write once, run once.
|
4
4
|
|
5
5
|
Manage one-time remote tasks in your Rails project.
|
6
|
-
Plugins with Mina to add support for rake tasks hosted in remote collection, such as Gist.
|
6
|
+
Plugins with Mina and Capistrano to add support for rake tasks hosted in remote collection, such as Gist.
|
7
7
|
|
8
8
|
Say you have a data migration to perform on a remote server. The procedure is too complex to just do it in the remote console and using database migrations would be evil. A rake task would be nice, but checking this in with the source code repository adds clutter, as you know you will only run this once.
|
9
9
|
Woro offers a quick way of pushing rake tasks onto the remote server, execute them and delete them instantly. Using Github's gist, you keep version control of the tasks and can share them with colleagues.
|
@@ -32,6 +32,17 @@ Or install it yourself as:
|
|
32
32
|
$ gem install woro
|
33
33
|
```
|
34
34
|
|
35
|
+
Then run:
|
36
|
+
|
37
|
+
```shell
|
38
|
+
$ woro init
|
39
|
+
```
|
40
|
+
|
41
|
+
This will create `lib/woro_tasks/` folder and `lib/tasks/woro.rake`.
|
42
|
+
Here the Woro task files are stored, edited locally and run using rake.
|
43
|
+
|
44
|
+
### for use with Mina
|
45
|
+
|
35
46
|
Require `mina/woro` in your `config/deploy.rb`:
|
36
47
|
|
37
48
|
```rb
|
@@ -41,33 +52,26 @@ require 'mina/git'
|
|
41
52
|
require 'mina/woro'
|
42
53
|
|
43
54
|
...
|
55
|
+
```
|
44
56
|
|
45
|
-
|
46
|
-
...
|
47
|
-
end
|
57
|
+
### for use with Capistrano
|
48
58
|
|
49
|
-
|
50
|
-
task deploy: :environment do
|
51
|
-
...
|
52
|
-
end
|
53
|
-
```
|
59
|
+
Require `capistrano/woro` in your `config/deploy.rb`:
|
54
60
|
|
55
|
-
|
61
|
+
```rb
|
62
|
+
require 'capistrano/rails'
|
63
|
+
require 'capistrano/woro'
|
56
64
|
|
57
|
-
|
58
|
-
$ woro init
|
65
|
+
...
|
59
66
|
```
|
60
67
|
|
61
|
-
This will create `lib/woro_tasks/` folder and `lib/tasks/woro.rake`.
|
62
|
-
Here the Woro task files are stored and edited locally.
|
63
|
-
|
64
68
|
## Usage
|
65
69
|
|
66
70
|
```shell
|
67
71
|
$ woro new cleanup_users
|
68
72
|
```
|
69
73
|
|
70
|
-
Can be used to create the template for a new task in `lib/
|
74
|
+
Can be used to create the template for a new task in `lib/woro_tasks/`.
|
71
75
|
|
72
76
|
The task itself is a regular rake-task in the woro-namespace. You can test it locally using rake:
|
73
77
|
|
@@ -76,33 +80,39 @@ $ rake woro:cleanup_users
|
|
76
80
|
```
|
77
81
|
|
78
82
|
Once you are done writing the task and you want to execute it on the remote system.
|
79
|
-
First you have to push them online.
|
83
|
+
First you have to push them online, in this case to Gist.
|
80
84
|
|
81
85
|
```shell
|
82
|
-
$ woro push cleanup_users
|
86
|
+
$ woro push gist:cleanup_users
|
83
87
|
```
|
84
88
|
|
85
89
|
_Attention, depending on whether you set up a Gist/Github login on
|
86
90
|
initialization. These tasks are online anonymous, but public, or
|
87
91
|
private under the specified Github account._
|
88
92
|
|
93
|
+
Now, to run a task remotely using Mina, specify the task:
|
94
|
+
|
95
|
+
```shell
|
96
|
+
$ mina woro:run task=gist:cleanup_users
|
97
|
+
```
|
89
98
|
|
90
|
-
|
99
|
+
Or to run it with Capistrano:
|
91
100
|
|
92
101
|
```shell
|
93
|
-
$
|
102
|
+
$ cap woro:run task=gist:cleanup_users
|
94
103
|
```
|
95
104
|
|
96
|
-
To show a list of all uploaded
|
105
|
+
To show a list of all tasks uploaded to any collection do:
|
97
106
|
|
98
107
|
```shell
|
99
108
|
$ woro list
|
109
|
+
$ woro ls
|
100
110
|
```
|
101
111
|
|
102
|
-
And finally you can download an existing task
|
112
|
+
And finally you can download an existing task to your local woro tasks directory.
|
103
113
|
|
104
114
|
```shell
|
105
|
-
$ woro pull cleanup_users
|
115
|
+
$ woro pull gist:cleanup_users
|
106
116
|
```
|
107
117
|
|
108
118
|
## Contributing
|
data/bin/woro
CHANGED
@@ -32,33 +32,32 @@ command :init do |c|
|
|
32
32
|
|
33
33
|
if agree 'Login to Gist/Github for private Woro tasks (Yes/No)? '
|
34
34
|
Gist.login!
|
35
|
-
#
|
36
|
-
#gen_access_token = agree "Secure gists via random access token?"
|
37
|
-
end
|
35
|
+
#elsif agree 'Login to AWS/S3 for private Woro tasks (Yes/No)? '
|
38
36
|
|
37
|
+
end
|
38
|
+
# if none of these, use gist, but public
|
39
39
|
|
40
40
|
# create Gist with welcome file
|
41
41
|
# additional tasks will be added to this first gist
|
42
42
|
app_name = ask 'Application name: '
|
43
|
-
result = Woro::
|
43
|
+
result = Woro::Adapters::Gist.create_initial_remote_task(app_name)
|
44
44
|
|
45
45
|
# configure adapters
|
46
46
|
gist_adapter = {
|
47
47
|
gist_id: result['id'],
|
48
48
|
public: false
|
49
49
|
}
|
50
|
-
# TODO generate access token
|
51
|
-
#gist_adapter[:access_token] = 'access_token' if gen_access_token
|
52
|
-
adapters = { gist: gist_adapter }
|
53
50
|
|
54
51
|
unless File.exists? File.dirname(Woro::Configuration.config_file)
|
55
52
|
FileUtils.mkdir_p File.dirname(Woro::Configuration.config_file)
|
56
53
|
end
|
57
|
-
config = Woro::Configuration.save(adapters: adapters)
|
58
54
|
say 'Initialized at `./config/woro.yml`'
|
59
55
|
|
56
|
+
options.default(adapters: { gist: gist_adapter } )
|
57
|
+
config = Woro::Configuration.save(options.__hash__)
|
58
|
+
|
60
59
|
unless File.exists? config.woro_task_dir
|
61
|
-
FileUtils.mkdir_p
|
60
|
+
FileUtils.mkdir_p config.woro_task_dir
|
62
61
|
say "Create #{config.woro_task_dir}"
|
63
62
|
end
|
64
63
|
|
@@ -76,10 +75,10 @@ command :new do |c|
|
|
76
75
|
c.example 'Creates tasks called "cleanup", "fix1" and "fix2"', 'woro new cleanup fix1 fix2'
|
77
76
|
c.option '--[no-]force', 'force overwrite of existing task file'
|
78
77
|
c.action do |args, options|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
78
|
+
config = Woro::Configuration.load
|
79
|
+
force_overwrite = options.force
|
80
|
+
args.each do |task_name|
|
81
|
+
task = Woro::Task.new(task_name)
|
83
82
|
if !task.exists? || force_overwrite || agree("Overwrite existing #{task.file_path}?")
|
84
83
|
task.create_from_task_template
|
85
84
|
say "Created #{task.file_path}"
|
@@ -94,12 +93,18 @@ command :push do |c|
|
|
94
93
|
c.description = 'Pushes one or more local tasks to the remote collection. Existing tasks by this name in the remote connection will be updated.'
|
95
94
|
c.example 'Pushes the task "cleanup" to the remote collection', 'woro push cleanup'
|
96
95
|
c.action do |args, options|
|
96
|
+
config = Woro::Configuration.load
|
97
97
|
args.each do |arg|
|
98
|
-
|
98
|
+
unless arg.include?(':')
|
99
|
+
say_error "Does not specify upload target"
|
100
|
+
next
|
101
|
+
end
|
102
|
+
adapter_name, task_name = arg.split(':')
|
103
|
+
adapter = config.adapter adapter_name
|
99
104
|
# Pushes a new woro task by given name to gist, this can be done multiple time.
|
100
|
-
task = Woro::Task.new(
|
105
|
+
task = Woro::Task.new(task_name)
|
101
106
|
if task.exists?
|
102
|
-
result =
|
107
|
+
result = adapter.push(task)
|
103
108
|
say "Uploaded #{task.file_path} to #{result['url']}"
|
104
109
|
else
|
105
110
|
say "Task #{task.task_name} not found at #{task.file_path}"
|
@@ -112,16 +117,23 @@ command :pull do |c|
|
|
112
117
|
c.syntax = 'woro pull <task> [options]'
|
113
118
|
c.summary = 'Pull Woro task from remote repository'
|
114
119
|
c.description = 'Pulls one task from the remote collection. Existing local tasks can be overwritten.'
|
115
|
-
c.example 'Pulls the task "cleanup" from the remote collection', 'woro pull cleanup'
|
120
|
+
c.example 'Pulls the task "cleanup" from the remote collection', 'woro pull gist:cleanup'
|
116
121
|
c.option '--[no-]force', 'force overwrite of existing task file'
|
117
122
|
c.action do |args, options|
|
118
123
|
config = Woro::Configuration.load
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
124
|
+
args.each do |arg|
|
125
|
+
unless arg.include?(':')
|
126
|
+
say_error "Does not specify download target"
|
127
|
+
next
|
128
|
+
end
|
129
|
+
adapter_name, task_name = arg.split(':')
|
130
|
+
adapter = config.adapter adapter_name
|
131
|
+
task = Woro::Task.new(task_name)
|
132
|
+
force_overwrite = options.force
|
133
|
+
if !task.exists? || force_overwrite || agree("Overwrite existing #{task.file_path}?")
|
134
|
+
system "cd '#{config.woro_task_dir}' && curl -O -# #{adapter.raw_url(task.file_name)}"
|
135
|
+
say "Downloaded #{task.task_name} to #{task.file_path}"
|
136
|
+
end
|
125
137
|
end
|
126
138
|
end
|
127
139
|
end
|
@@ -135,13 +147,25 @@ command :list do |c|
|
|
135
147
|
c.action do |args, options|
|
136
148
|
abort "invalid command. See 'woro help' for more information" unless args.empty?
|
137
149
|
config = Woro::Configuration.load
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
150
|
+
config.adapters.each do |adapter_config|
|
151
|
+
puts "#{adapter_config[0]} ---"
|
152
|
+
adapter = config.adapter(adapter_config[0])
|
153
|
+
files = adapter.list_keys || {}
|
154
|
+
tasks = files.map do |file_name, data|
|
155
|
+
if file_name.include? '.rake'
|
156
|
+
OpenStruct.new(name_with_args: file_name.split('.rake').first,
|
157
|
+
comment: adapter.extract_description(data))
|
158
|
+
end
|
159
|
+
end
|
160
|
+
tasks.compact!
|
161
|
+
Woro::TaskHelper.print_task_list(tasks)
|
162
|
+
end
|
163
|
+
puts "local ---"
|
164
|
+
tasks = Woro::TaskHelper.woro_task_files(config.woro_task_dir) do |file_name, data|
|
165
|
+
OpenStruct.new(name_with_args: file_name.split('.rake').first,
|
166
|
+
comment: Woro::TaskHelper.extract_description(data))
|
144
167
|
end
|
168
|
+
Woro::TaskHelper.print_task_list(tasks)
|
145
169
|
end
|
146
170
|
end
|
147
171
|
alias_command :ls, :list
|
@@ -0,0 +1 @@
|
|
1
|
+
load File.expand_path("../../woro/tasks/capistrano.rake", __FILE__)
|
data/lib/woro.rb
CHANGED
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'gist'
|
2
|
+
|
3
|
+
module Woro
|
4
|
+
module Adapters
|
5
|
+
class Gist
|
6
|
+
|
7
|
+
attr_reader :gist_id
|
8
|
+
|
9
|
+
# Create a new gist collection adapter
|
10
|
+
# @param gist_id [String] gist to which the adapter connects
|
11
|
+
def initialize(gist_id)
|
12
|
+
@gist_id = gist_id
|
13
|
+
end
|
14
|
+
|
15
|
+
# Returns the list of files included in the Gist
|
16
|
+
# @return [Hash] List of files in the format { filename: { data }}
|
17
|
+
def list_keys
|
18
|
+
gist['files']
|
19
|
+
end
|
20
|
+
|
21
|
+
# Push this task's file content to the Gist collection on the server.
|
22
|
+
# Existing contents by the same #file_name will be overriden, but
|
23
|
+
# can be accessed via Github or Gist's API.
|
24
|
+
def push(task)
|
25
|
+
::Gist.multi_gist({ task.file_name => task.read_task_file },
|
26
|
+
public: false,
|
27
|
+
update: gist_id,
|
28
|
+
output: :all)
|
29
|
+
end
|
30
|
+
|
31
|
+
# The Gist contains a collection of files.
|
32
|
+
# These are stored and accessed on Github.
|
33
|
+
# @return [Hash] parsed JSON hash of the gist's metadata
|
34
|
+
def gist
|
35
|
+
@gist ||= retrieve_gist(gist_id)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Retrieves metadata of the specified gist
|
39
|
+
# @param gist_id [String] id of the gist
|
40
|
+
# @return [Hash] parsed JSON hash
|
41
|
+
def retrieve_gist(gist_id)
|
42
|
+
service_url = "https://api.github.com/gists/#{gist_id}"
|
43
|
+
response = Net::HTTP.get_response(URI.parse(service_url))
|
44
|
+
JSON.parse(response.body || '')
|
45
|
+
end
|
46
|
+
|
47
|
+
# Retrieves the data hash included in the gist under the #file_name.
|
48
|
+
# @param file_name [String] name of the file to retrieve the download url
|
49
|
+
# @return [Hash] parsed JSON hash
|
50
|
+
def retrieve_file_data(file_name)
|
51
|
+
gist['files'][file_name]
|
52
|
+
end
|
53
|
+
|
54
|
+
# The raw url is a permalink for downloading the content rake task within
|
55
|
+
# the Gist as a file.
|
56
|
+
# @param file_name [String] name of the file to retrieve the download url
|
57
|
+
# @return [String] HTTP-URL of addressed file within the gist collection
|
58
|
+
def raw_url(file_name)
|
59
|
+
retrieve_file_data(file_name)['raw_url']
|
60
|
+
end
|
61
|
+
|
62
|
+
# Creates an initial welcome gist on project setup
|
63
|
+
# @param app_name [String] Name of the app is displayed in the initial welcome message
|
64
|
+
def self.create_initial_remote_task(app_name, access_token=nil)
|
65
|
+
::Gist.gist("Welcome to the Woro Task Repository for #{app_name}", filename: app_name, access_token: access_token)
|
66
|
+
end
|
67
|
+
|
68
|
+
# Extract description from gist's data content string.
|
69
|
+
# @param data [Hash] gist data hash
|
70
|
+
# [String] description string
|
71
|
+
def extract_description(data)
|
72
|
+
Woro::TaskHelper.extract_description(data['content'])
|
73
|
+
end
|
74
|
+
|
75
|
+
# Read the rake task template
|
76
|
+
# @return [String]
|
77
|
+
def read_template_file
|
78
|
+
File.read(File.join(File.dirname(__FILE__), 'templates','task.rake') )
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
data/lib/woro/configuration.rb
CHANGED
@@ -4,12 +4,13 @@ include Commander::UI
|
|
4
4
|
|
5
5
|
module Woro
|
6
6
|
class Configuration
|
7
|
-
attr_reader :adapters, :woro_task_dir
|
7
|
+
attr_reader :adapters, :woro_task_dir, :app_name
|
8
8
|
|
9
9
|
# Initialize configuration.
|
10
10
|
def initialize(options = {})
|
11
11
|
@woro_task_dir = Configuration.woro_task_dir
|
12
12
|
@adapters = options[:adapters]
|
13
|
+
@app_name = options[:app_name]
|
13
14
|
end
|
14
15
|
|
15
16
|
# Load configuration file or default_options. Passed options take precedence.
|
@@ -17,7 +18,7 @@ module Woro
|
|
17
18
|
user_options = options.reject{|k,v| ![:adapters, :app_name].include? k}
|
18
19
|
|
19
20
|
if !(File.exists? config_file)
|
20
|
-
File.open(config_file, 'w') { |file| YAML
|
21
|
+
File.open(config_file, 'w') { |file| YAML.dump(default_options, file) }
|
21
22
|
say "Initialized default config file in #{config_file}. See 'woro help init' for options."
|
22
23
|
end
|
23
24
|
|
@@ -31,7 +32,7 @@ module Woro
|
|
31
32
|
force_save = options.delete :force
|
32
33
|
|
33
34
|
if !(File.exists? config_file) || force_save
|
34
|
-
File.open(config_file, 'w') { |file| YAML
|
35
|
+
File.open(config_file, 'w') { |file| YAML.dump(default_options.merge(user_options), file) }
|
35
36
|
say "Initialized config file in #{config_file}"
|
36
37
|
else
|
37
38
|
say_error "Not overwriting existing config file #{config_file}, use --force to override. See 'woro help init'."
|
@@ -39,6 +40,15 @@ module Woro
|
|
39
40
|
self
|
40
41
|
end
|
41
42
|
|
43
|
+
def adapter(name)
|
44
|
+
options = adapters[name.to_sym]
|
45
|
+
|
46
|
+
case name.to_sym
|
47
|
+
when :gist
|
48
|
+
@gist_adapter ||= Woro::Adapters::Gist.new(options[:gist_id])
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
42
52
|
# Helpers
|
43
53
|
|
44
54
|
def self.config_file
|
data/lib/woro/task.rb
CHANGED
@@ -4,25 +4,22 @@ require 'erb'
|
|
4
4
|
module Woro
|
5
5
|
# Task object, helps in the creation and management of gists.
|
6
6
|
class Task
|
7
|
-
attr_reader :task_name, :
|
7
|
+
attr_reader :task_name, :gist
|
8
8
|
|
9
|
-
def initialize(
|
9
|
+
def initialize(task_name)
|
10
10
|
@task_name = Woro::Task.sanitize_task_name task_name
|
11
|
-
@gist_id = gist_id
|
12
11
|
end
|
13
12
|
|
14
|
-
# Create a new task based on a template rake-task.
|
15
|
-
# @param gist_id [String] gist to which the task is added
|
16
13
|
# @param task_name [String] sanitized name of the task, used throughout the further processing
|
17
14
|
# @return [Task] the created task
|
18
|
-
def self.create(
|
19
|
-
task = Woro::Task.new(
|
15
|
+
def self.create(task_name)
|
16
|
+
task = Woro::Task.new(task_name)
|
20
17
|
task.create_from_task_template
|
21
18
|
task
|
22
19
|
end
|
23
20
|
|
24
21
|
def self.sanitize_task_name(task_name)
|
25
|
-
task_name.strip.split(' ').first
|
22
|
+
task_name.strip.split(' ').first # not nice
|
26
23
|
end
|
27
24
|
|
28
25
|
# File name based on the task's name.
|
@@ -34,18 +31,18 @@ module Woro
|
|
34
31
|
# File name based on the task's filename (see #file_name).
|
35
32
|
# @return [String]
|
36
33
|
def file_path
|
37
|
-
File.join
|
34
|
+
File.join 'lib', 'woro_tasks', file_name
|
38
35
|
end
|
39
36
|
|
40
37
|
# Returns true if a task of this name exists locally
|
41
38
|
def exists?
|
42
|
-
File.
|
39
|
+
File.exist? file_path
|
43
40
|
end
|
44
41
|
|
45
42
|
# Creates a new rake task file at the file path (see #file_path).
|
46
43
|
def create_from_task_template
|
47
44
|
b = binding
|
48
|
-
template = ERB.new(
|
45
|
+
template = ERB.new(Woro::TaskHelper.read_template_file).result(b)
|
49
46
|
File.open(file_path, 'w') do |f|
|
50
47
|
f.puts template
|
51
48
|
end
|
@@ -63,34 +60,5 @@ module Woro
|
|
63
60
|
def read_task_file
|
64
61
|
File.read(file_path)
|
65
62
|
end
|
66
|
-
|
67
|
-
# Push this task's file content to the Gist collection on the server.
|
68
|
-
# Existing contents by the same #file_name will be overriden, but
|
69
|
-
# can be accessed via Github or Gist's API.
|
70
|
-
def push
|
71
|
-
Gist.multi_gist({ file_name => read_task_file },
|
72
|
-
public: false,
|
73
|
-
update: gist_id,
|
74
|
-
output: :all)
|
75
|
-
end
|
76
|
-
|
77
|
-
# The Gist contains a collection of files.
|
78
|
-
# These are stored and accessed on Github.
|
79
|
-
# @return [Hash] parsed JSON hash of the gist's metadata
|
80
|
-
def gist
|
81
|
-
@gist ||= Gister.retrieve_gist(gist_id)
|
82
|
-
end
|
83
|
-
|
84
|
-
# Retrieves the data hash included in the gist under the #file_name.
|
85
|
-
# @return [Hash] parsed JSON hash
|
86
|
-
def retrieve_file_data
|
87
|
-
gist['files'][file_name]
|
88
|
-
end
|
89
|
-
|
90
|
-
# The raw url is a permalink for downloading the content rake task within
|
91
|
-
# the Gist as a file.
|
92
|
-
def raw_url
|
93
|
-
retrieve_file_data['raw_url']
|
94
|
-
end
|
95
63
|
end
|
96
64
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Woro
|
2
|
+
class TaskHelper
|
3
|
+
|
4
|
+
class << self
|
5
|
+
|
6
|
+
def print_task_list(tasks)
|
7
|
+
width ||= tasks.map { |t| t.name_with_args.length }.max || 10
|
8
|
+
tasks.each do |t|
|
9
|
+
puts " %-#{width}s # %s" % [ t.name_with_args, t.comment ]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# Perform an action over all files within the woro task directory
|
14
|
+
def woro_task_files(directory, &block)
|
15
|
+
tasks = []
|
16
|
+
Dir.foreach(directory) do |file_name|
|
17
|
+
if file_name.include? '.rake'
|
18
|
+
data = File.read(File.join(directory, file_name))
|
19
|
+
tasks << yield(file_name, data)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
tasks
|
23
|
+
end
|
24
|
+
|
25
|
+
# Extract description from gist's data content string.
|
26
|
+
# @param data [Hash] gist data hash
|
27
|
+
# [String] description string
|
28
|
+
def extract_description(task_content)
|
29
|
+
task_content.match(/desc ['"]([a-zA-Z0-9\s]*)['"]/)[1]
|
30
|
+
end
|
31
|
+
|
32
|
+
# Read the rake task template
|
33
|
+
# @return [String]
|
34
|
+
def read_template_file
|
35
|
+
File.read(File.join(File.dirname(__FILE__), 'templates','task.rake') )
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -1,58 +1,31 @@
|
|
1
|
-
require '
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
#
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
end
|
30
|
-
|
31
|
-
def args
|
32
|
-
fetch(:delayed_job_args, '')
|
33
|
-
end
|
34
|
-
|
35
|
-
def roles
|
36
|
-
fetch(:delayed_job_server_role, :app)
|
37
|
-
end
|
38
|
-
|
39
|
-
def delayed_job_command
|
40
|
-
fetch(:delayed_job_command, 'script/delayed_job')
|
41
|
-
end
|
42
|
-
|
43
|
-
desc 'Stop the delayed_job process'
|
44
|
-
task :stop, :roles => lambda { roles } do
|
45
|
-
run "cd #{current_path} && #{rails_env} #{delayed_job_command} stop #{args}"
|
46
|
-
end
|
47
|
-
|
48
|
-
desc 'Start the delayed_job process'
|
49
|
-
task :start, :roles => lambda { roles } do
|
50
|
-
run "cd #{current_path} && #{rails_env} #{delayed_job_command} start #{args}"
|
51
|
-
end
|
52
|
-
|
53
|
-
desc 'Restart the delayed_job process'
|
54
|
-
task :restart, :roles => lambda { roles } do
|
55
|
-
run "cd #{current_path} && #{rails_env} #{delayed_job_command} restart #{args}"
|
1
|
+
require 'woro'
|
2
|
+
|
3
|
+
# Capistrano recipees for managing woro tasks
|
4
|
+
namespace :woro do
|
5
|
+
desc 'Run Woro task remotely'
|
6
|
+
task run: 'deploy:set_rails_env' do
|
7
|
+
|
8
|
+
on roles(:app), in: :sequence, wait: 5 do
|
9
|
+
unless ENV['task'].include?(':')
|
10
|
+
error "Does not specify upload target"
|
11
|
+
else
|
12
|
+
config = Woro::Configuration.load
|
13
|
+
|
14
|
+
adapter_name, task_name = ENV['task'].split(':')
|
15
|
+
adapter = config.adapter(adapter_name)
|
16
|
+
task = Woro::Task.new(task_name)
|
17
|
+
|
18
|
+
info "Execute #{task.task_name} remotely"
|
19
|
+
within File.join(release_path, 'lib', 'tasks') do
|
20
|
+
execute :curl, "#{adapter.raw_url(task.file_name)}", '-o' "woro_#{task.file_name}"
|
21
|
+
end
|
22
|
+
within release_path do
|
23
|
+
with rails_env: fetch(:rails_env) do
|
24
|
+
execute :rake, "woro:#{task.task_name}"
|
25
|
+
execute :rm, "lib/tasks/woro_#{task.file_name}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
56
29
|
end
|
57
30
|
end
|
58
31
|
end
|
data/lib/woro/tasks/mina.rake
CHANGED
@@ -6,12 +6,18 @@ namespace :woro do
|
|
6
6
|
desc 'Run Woro task remotely'
|
7
7
|
task run: :environment do
|
8
8
|
config = Woro::Configuration.load
|
9
|
-
|
9
|
+
unless ENV['task'].include?(':')
|
10
|
+
print_error "Does not specify upload target"
|
11
|
+
return
|
12
|
+
end
|
13
|
+
adapter_name, task_name = ENV['task'].split(':')
|
14
|
+
adapter = config.adapter(adapter_name)
|
15
|
+
task = Woro::Task.new(task_name)
|
10
16
|
print_status "Execute #{task.task_name} remotely"
|
11
17
|
in_directory "#{app_path}" do
|
12
|
-
queue! "cd 'lib/tasks' && curl -
|
18
|
+
queue! "cd 'lib/tasks' && curl #{adapter.raw_url(task.file_name)} -o woro_#{task.file_name}"
|
13
19
|
queue! "#{bundle_prefix} rake woro:#{task.task_name}"
|
14
|
-
queue! "rm lib/tasks
|
20
|
+
queue! "rm lib/tasks/woro_#{task.file_name}"
|
15
21
|
end
|
16
22
|
end
|
17
23
|
end
|
data/lib/woro/version.rb
CHANGED
@@ -0,0 +1,103 @@
|
|
1
|
+
{
|
2
|
+
"url": "https://api.github.com/gists/aa5a315d61ae9438b18d",
|
3
|
+
"forks_url": "https://api.github.com/gists/aa5a315d61ae9438b18d/forks",
|
4
|
+
"commits_url": "https://api.github.com/gists/aa5a315d61ae9438b18d/commits",
|
5
|
+
"id": "aa5a315d61ae9438b18d",
|
6
|
+
"description": "description of gist",
|
7
|
+
"public": true,
|
8
|
+
"owner": {
|
9
|
+
"login": "octocat",
|
10
|
+
"id": 1,
|
11
|
+
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
|
12
|
+
"gravatar_id": "",
|
13
|
+
"url": "https://api.github.com/users/octocat",
|
14
|
+
"html_url": "https://github.com/octocat",
|
15
|
+
"followers_url": "https://api.github.com/users/octocat/followers",
|
16
|
+
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
|
17
|
+
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
|
18
|
+
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
|
19
|
+
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
|
20
|
+
"organizations_url": "https://api.github.com/users/octocat/orgs",
|
21
|
+
"repos_url": "https://api.github.com/users/octocat/repos",
|
22
|
+
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
|
23
|
+
"received_events_url": "https://api.github.com/users/octocat/received_events",
|
24
|
+
"type": "User",
|
25
|
+
"site_admin": false
|
26
|
+
},
|
27
|
+
"user": null,
|
28
|
+
"files": {
|
29
|
+
"create_user.rake": {
|
30
|
+
"size": 932,
|
31
|
+
"raw_url": "https://gist.githubusercontent.com/raw/365370/8c4d2d43d178df44f4c03a7f2ac0ff512853564e/ring.erl",
|
32
|
+
"type": "text/plain",
|
33
|
+
"language": "Ruby",
|
34
|
+
"truncated": false,
|
35
|
+
"content": "namespace :woro do\n desc 'Create User'\n task create_user: :environment do\n # Code\n end\nend\n"
|
36
|
+
}
|
37
|
+
},
|
38
|
+
"comments": 0,
|
39
|
+
"comments_url": "https://api.github.com/gists/aa5a315d61ae9438b18d/comments/",
|
40
|
+
"html_url": "https://gist.github.com/aa5a315d61ae9438b18d",
|
41
|
+
"git_pull_url": "https://gist.github.com/aa5a315d61ae9438b18d.git",
|
42
|
+
"git_push_url": "https://gist.github.com/aa5a315d61ae9438b18d.git",
|
43
|
+
"created_at": "2010-04-14T02:15:15Z",
|
44
|
+
"updated_at": "2011-06-20T11:34:15Z",
|
45
|
+
"forks": [
|
46
|
+
{
|
47
|
+
"user": {
|
48
|
+
"login": "octocat",
|
49
|
+
"id": 1,
|
50
|
+
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
|
51
|
+
"gravatar_id": "",
|
52
|
+
"url": "https://api.github.com/users/octocat",
|
53
|
+
"html_url": "https://github.com/octocat",
|
54
|
+
"followers_url": "https://api.github.com/users/octocat/followers",
|
55
|
+
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
|
56
|
+
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
|
57
|
+
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
|
58
|
+
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
|
59
|
+
"organizations_url": "https://api.github.com/users/octocat/orgs",
|
60
|
+
"repos_url": "https://api.github.com/users/octocat/repos",
|
61
|
+
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
|
62
|
+
"received_events_url": "https://api.github.com/users/octocat/received_events",
|
63
|
+
"type": "User",
|
64
|
+
"site_admin": false
|
65
|
+
},
|
66
|
+
"url": "https://api.github.com/gists/dee9c42e4998ce2ea439",
|
67
|
+
"id": "dee9c42e4998ce2ea439",
|
68
|
+
"created_at": "2011-04-14T16:00:49Z",
|
69
|
+
"updated_at": "2011-04-14T16:00:49Z"
|
70
|
+
}
|
71
|
+
],
|
72
|
+
"history": [
|
73
|
+
{
|
74
|
+
"url": "https://api.github.com/gists/aa5a315d61ae9438b18d/57a7f021a713b1c5a6a199b54cc514735d2d462f",
|
75
|
+
"version": "57a7f021a713b1c5a6a199b54cc514735d2d462f",
|
76
|
+
"user": {
|
77
|
+
"login": "octocat",
|
78
|
+
"id": 1,
|
79
|
+
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
|
80
|
+
"gravatar_id": "",
|
81
|
+
"url": "https://api.github.com/users/octocat",
|
82
|
+
"html_url": "https://github.com/octocat",
|
83
|
+
"followers_url": "https://api.github.com/users/octocat/followers",
|
84
|
+
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
|
85
|
+
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
|
86
|
+
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
|
87
|
+
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
|
88
|
+
"organizations_url": "https://api.github.com/users/octocat/orgs",
|
89
|
+
"repos_url": "https://api.github.com/users/octocat/repos",
|
90
|
+
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
|
91
|
+
"received_events_url": "https://api.github.com/users/octocat/received_events",
|
92
|
+
"type": "User",
|
93
|
+
"site_admin": false
|
94
|
+
},
|
95
|
+
"change_status": {
|
96
|
+
"deletions": 0,
|
97
|
+
"additions": 180,
|
98
|
+
"total": 180
|
99
|
+
},
|
100
|
+
"committed_at": "2010-04-14T02:15:15Z"
|
101
|
+
}
|
102
|
+
]
|
103
|
+
}
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
describe Woro::Adapters::Gist do
|
5
|
+
|
6
|
+
let!(:gist_id) { rand(999)}
|
7
|
+
let(:task) { Woro::Task.new('create_user') }
|
8
|
+
subject { Woro::Adapters::Gist.new(gist_id) }
|
9
|
+
let(:gist_hash) do
|
10
|
+
FakeFS.deactivate!
|
11
|
+
body = File.read(File.join('spec', 'fixtures', 'gist.json'))
|
12
|
+
FakeFS.activate!
|
13
|
+
JSON.parse(body)
|
14
|
+
end
|
15
|
+
|
16
|
+
before do
|
17
|
+
allow(subject).to receive(:gist).once.and_return gist_hash
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#list_keys' do
|
21
|
+
it 'returns list' do
|
22
|
+
expected_list = {
|
23
|
+
"create_user.rake" => {
|
24
|
+
"size"=>932, "raw_url"=>"https://gist.githubusercontent.com/raw/365370/8c4d2d43d178df44f4c03a7f2ac0ff512853564e/ring.erl", "type"=>"text/plain", "language"=>"Ruby", "truncated"=>false, "content"=>"namespace :woro do\n desc 'Create User'\n task create_user: :environment do\n # Code\n end\nend\n"
|
25
|
+
}
|
26
|
+
}
|
27
|
+
expect(subject.list_keys).to eq expected_list
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '#push' do
|
32
|
+
it 'calls gist services with correct params' do
|
33
|
+
File.open(task.file_path, 'w') do |f|
|
34
|
+
f.puts 'hey'
|
35
|
+
end
|
36
|
+
expected_files_hash = { task.file_name => task.read_task_file }
|
37
|
+
expected_params_hash = { public: false,
|
38
|
+
update: gist_id,
|
39
|
+
output: :all
|
40
|
+
}
|
41
|
+
expect(Gist).to receive(:multi_gist).with(expected_files_hash, expected_params_hash).and_return gist_hash
|
42
|
+
subject.push(task)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
describe '#retrieve_file_data' do
|
48
|
+
it 'returns data hash from file' do
|
49
|
+
expected_hash = {
|
50
|
+
"size"=>932, "raw_url"=>"https://gist.githubusercontent.com/raw/365370/8c4d2d43d178df44f4c03a7f2ac0ff512853564e/ring.erl", "type"=>"text/plain", "language"=>"Ruby", "truncated"=>false, "content"=>"namespace :woro do\n desc 'Create User'\n task create_user: :environment do\n # Code\n end\nend\n"
|
51
|
+
}
|
52
|
+
expect(subject.retrieve_file_data('create_user.rake')).to eq expected_hash
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe '#raw_url' do
|
57
|
+
it 'returns raw_url of file' do
|
58
|
+
expected_url = "https://gist.githubusercontent.com/raw/365370/8c4d2d43d178df44f4c03a7f2ac0ff512853564e/ring.erl"
|
59
|
+
expect(subject.raw_url('create_user.rake')).to eq expected_url
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Woro::Configuration do
|
4
|
+
|
5
|
+
describe '#initialize' do
|
6
|
+
it 'instantiates object' do
|
7
|
+
options = {
|
8
|
+
adapters: %(foo baz),
|
9
|
+
app_name: 'bar'
|
10
|
+
}
|
11
|
+
config = Woro::Configuration.new(options)
|
12
|
+
expect(config.adapters).to eq %(foo baz)
|
13
|
+
expect(config.app_name).to eq 'bar'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '.load' do
|
18
|
+
context 'not given a configuration file' do
|
19
|
+
it 'returns Configuration object with default options' do
|
20
|
+
config = Woro::Configuration.load
|
21
|
+
expect(config.adapters).to be_falsy
|
22
|
+
expect(config.app_name).to be_falsy
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'writes a configuration file with default options' do
|
26
|
+
Woro::Configuration.load
|
27
|
+
expect(File.read(Woro::Configuration.config_file)).to eq \
|
28
|
+
YAML.dump(Woro::Configuration.default_options)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'given a configuration file' do
|
33
|
+
before(:each) do
|
34
|
+
opts = {
|
35
|
+
adapters: %w(foo baz),
|
36
|
+
app_name: 'bar'
|
37
|
+
}
|
38
|
+
File.open(Woro::Configuration.config_file, 'w') do |file|
|
39
|
+
YAML.dump(opts, file)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'returns Configuration object with options in file' do
|
44
|
+
config = Woro::Configuration.load
|
45
|
+
expect(config.adapters).to eq %w(foo baz)
|
46
|
+
expect(config.app_name).to eq 'bar'
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'given options' do
|
50
|
+
it 'overrides options in configuration file' do
|
51
|
+
options = {
|
52
|
+
adapters: %w(goo grr),
|
53
|
+
app_name: 'car'
|
54
|
+
}
|
55
|
+
config = Woro::Configuration.load(options)
|
56
|
+
expect(config.adapters).to eq %w(goo grr)
|
57
|
+
expect(config.app_name).to eq 'car'
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe '.save' do
|
64
|
+
let(:options) do
|
65
|
+
{
|
66
|
+
adapters: ['foo', 'baz'],
|
67
|
+
app_name: 'bar'
|
68
|
+
}
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'not given a configuration file' do
|
72
|
+
it 'writes a configuration file with options' do
|
73
|
+
Woro::Configuration.save(options)
|
74
|
+
expect(File.read(Woro::Configuration.config_file)).to eq \
|
75
|
+
YAML.dump(options)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context 'given a configuration file' do
|
80
|
+
before(:each) do
|
81
|
+
opts = {
|
82
|
+
adapters: ['goo', 'grr'],
|
83
|
+
app_name: 'car'
|
84
|
+
}
|
85
|
+
File.open(Woro::Configuration.config_file, 'w') do |file|
|
86
|
+
YAML.dump(opts, file)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'does not overwrite' do
|
91
|
+
Woro::Configuration.save(options)
|
92
|
+
expect(File.read(Woro::Configuration.config_file)).to_not eq \
|
93
|
+
YAML.dump(options)
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'does overwrite if passed `force` option' do
|
97
|
+
Woro::Configuration.save(options.merge(:force => true))
|
98
|
+
expect(File.read(Woro::Configuration.config_file)).to eq \
|
99
|
+
YAML.dump(options)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Woro::Task do
|
4
|
+
|
5
|
+
subject { Woro::Task.new('cleanup_task') }
|
6
|
+
|
7
|
+
describe '#create_from_task_template' do
|
8
|
+
it 'creates new file' do
|
9
|
+
FakeFS.deactivate!
|
10
|
+
example_path = File.join('spec', 'fixtures','fresh_template.yml')
|
11
|
+
fresh_template_body = File.read example_path
|
12
|
+
FakeFS.activate!
|
13
|
+
subject.create_from_task_template
|
14
|
+
expect(File.read(Woro::Task.file_path)).to eq fresh_template_body
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#file_name' do
|
19
|
+
context 'taskname is cleanup_task' do
|
20
|
+
it 'returns cleanup_task.rake' do
|
21
|
+
expect(subject.file_name).to eq 'cleanup_task.rake'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#file_path' do
|
27
|
+
context 'task path is lib/woro_tasks/cleanup_task' do
|
28
|
+
it 'returns lib/woro_tasks/cleanup_task.rake' do
|
29
|
+
expect(subject.file_path).to eq 'lib/woro_tasks/cleanup_task.rake'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'pry'
|
2
|
+
require 'woro'
|
3
|
+
require 'fakefs/safe'
|
4
|
+
require 'aws-sdk-v1'
|
5
|
+
|
6
|
+
Dir[('./spec/support/**/*.rb')].each {|f| require f}
|
7
|
+
|
8
|
+
RSpec.configure do |config|
|
9
|
+
config.color = true
|
10
|
+
config.order = 'random'
|
11
|
+
|
12
|
+
config.before(:each) do
|
13
|
+
FakeFS.activate!
|
14
|
+
FileUtils.mkdir_p 'config'
|
15
|
+
FileUtils.mkdir_p 'lib/woro_tasks'
|
16
|
+
FileUtils.mkdir_p 'lib/tasks'
|
17
|
+
end
|
18
|
+
|
19
|
+
config.after(:each) do
|
20
|
+
FakeFS.deactivate!
|
21
|
+
FakeFS::FileSystem.clear
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
data/woro.gemspec
CHANGED
@@ -23,8 +23,6 @@ Gem::Specification.new do |spec|
|
|
23
23
|
|
24
24
|
spec.add_development_dependency "bundler", "~> 1.7"
|
25
25
|
spec.add_development_dependency "rake", "~> 10.0"
|
26
|
-
spec.add_development_dependency "rspec"
|
27
|
-
spec.add_development_dependency "rspec-nc"
|
28
26
|
spec.add_development_dependency "guard"
|
29
27
|
spec.add_development_dependency "guard-rspec"
|
30
28
|
spec.add_development_dependency "pry"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: woro
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Senff
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-06-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: gist
|
@@ -66,34 +66,6 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '10.0'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: rspec
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - ">="
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '0'
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - ">="
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '0'
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: rspec-nc
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - ">="
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '0'
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - ">="
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '0'
|
97
69
|
- !ruby/object:Gem::Dependency
|
98
70
|
name: guard
|
99
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -192,16 +164,24 @@ files:
|
|
192
164
|
- README.md
|
193
165
|
- Rakefile
|
194
166
|
- bin/woro
|
167
|
+
- lib/capistrano/woro.rb
|
195
168
|
- lib/mina/woro.rb
|
196
169
|
- lib/woro.rb
|
170
|
+
- lib/woro/adapters/gist.rb
|
197
171
|
- lib/woro/configuration.rb
|
198
|
-
- lib/woro/gister.rb
|
199
172
|
- lib/woro/task.rb
|
173
|
+
- lib/woro/task_helper.rb
|
200
174
|
- lib/woro/tasks/capistrano.rake
|
201
175
|
- lib/woro/tasks/mina.rake
|
202
176
|
- lib/woro/templates/task.rake
|
203
177
|
- lib/woro/templates/woro.rake
|
204
178
|
- lib/woro/version.rb
|
179
|
+
- spec/fixtures/fresh_template.yml
|
180
|
+
- spec/fixtures/gist.json
|
181
|
+
- spec/lib/woro/adapters/gist_spec.rb
|
182
|
+
- spec/lib/woro/configuration_spec.rb
|
183
|
+
- spec/lib/woro/task_spec.rb
|
184
|
+
- spec/spec_helper.rb
|
205
185
|
- woro.gemspec
|
206
186
|
homepage: http://github.com/Dahie/woro
|
207
187
|
licenses:
|
@@ -228,4 +208,10 @@ signing_key:
|
|
228
208
|
specification_version: 4
|
229
209
|
summary: Write once, run once. One-time migration task management on remote servers
|
230
210
|
through mina.
|
231
|
-
test_files:
|
211
|
+
test_files:
|
212
|
+
- spec/fixtures/fresh_template.yml
|
213
|
+
- spec/fixtures/gist.json
|
214
|
+
- spec/lib/woro/adapters/gist_spec.rb
|
215
|
+
- spec/lib/woro/configuration_spec.rb
|
216
|
+
- spec/lib/woro/task_spec.rb
|
217
|
+
- spec/spec_helper.rb
|
data/lib/woro/gister.rb
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
require 'gist'
|
2
|
-
require 'net/https'
|
3
|
-
|
4
|
-
# All classes and modules specific to Woro.
|
5
|
-
module Woro
|
6
|
-
# Various shared static helpers
|
7
|
-
class Gister
|
8
|
-
class << self
|
9
|
-
# Creates an initial welcome gist on project setup
|
10
|
-
# @param app_name [String] Name of the app is displayed in the initial welcome message
|
11
|
-
def create_initial_gist(app_name, access_token=nil)
|
12
|
-
Gist.gist("Welcome to the Woro Task Repository for #{app_name}", filename: app_name, access_token: access_token)
|
13
|
-
end
|
14
|
-
|
15
|
-
# Retrieves metadata of the specified gist
|
16
|
-
# @param gist_id [String] id of the gist
|
17
|
-
# @return [Hash] parsed JSON hash
|
18
|
-
def retrieve_gist(gist_id)
|
19
|
-
service_url = "https://api.github.com/gists/#{gist_id}"
|
20
|
-
response = Net::HTTP.get_response(URI.parse(service_url))
|
21
|
-
JSON.parse(response.body)
|
22
|
-
end
|
23
|
-
|
24
|
-
# Extract description from gist's data content string.
|
25
|
-
# @param data [Hash] gist data hash
|
26
|
-
# [String] description string
|
27
|
-
def extract_description(data)
|
28
|
-
data['content'].match(/desc ['"]([a-zA-Z0-9\s]*)['"]/)[1]
|
29
|
-
end
|
30
|
-
|
31
|
-
# Returns the list of files included in the specified gist
|
32
|
-
# @param gist_id [String] id of the gist
|
33
|
-
# @return [Hash] List of files in the format { filename: { data }}
|
34
|
-
def get_list_of_files(gist_id)
|
35
|
-
retrieve_gist(gist_id)['files']
|
36
|
-
end
|
37
|
-
|
38
|
-
# Read the rake task template
|
39
|
-
# @return [String]
|
40
|
-
def read_template_file
|
41
|
-
File.read(File.dirname(__FILE__) + '/templates/task.rake')
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|