woro 0.2.2 → 0.3.0

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: b95b362f677b55672cbf3f6fd70ee7b1d66551af
4
- data.tar.gz: 2be0c9ad7365d1c755d1d2b24dbfab13c2b88f50
3
+ metadata.gz: 1fc039fcb30ca0249690a9faa835fe36b0a791b3
4
+ data.tar.gz: 9049c6ace163fa2570cb74f27e09024c86c940b3
5
5
  SHA512:
6
- metadata.gz: db55fd8f7bbee3528608990b764da0d6747492087bc94fae475bd5f8cd4d5634913bd73658fc8a44289ad20d920bb6ea561de61e26a5fb33a231095b2cb4118e
7
- data.tar.gz: 4aed67765b981c0f2ff6da55a2c06f8f2aadd33f8c935ac236920244ec605280e80ab749a9523b0d3f2668c9647c1f385d0a15403e5d106be09e4cce9e029773
6
+ metadata.gz: 16c86c137ee7bbc88d1db72b1adb66d659382c4235caad2c2e7d302ab2835fd9788e33db4f2890702e2c85999bc77e1f3108c917903e81a6ab1b79208578f0d7
7
+ data.tar.gz: 02f0df2c3afd3dffed2de0833f6bb64ced14dd2bdca2898fe97eabbd5795f94c456c3cca194f2f2fe08048cb8301d5e96180abb7e5d7c0a2f448b1b9693e37b7
data/README.md CHANGED
@@ -6,12 +6,19 @@ Manage one-time remote tasks in your Rails project.
6
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
- 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.
9
+ Woro offers a quick way of pushing rake tasks onto the remote server, execute them and delete them instantly.
10
10
 
11
11
  Woro helps you create rake tasks, that you can develop and run locally.
12
- Once you are ready, woro let's you push them online to a remote collection like Gist.
12
+ Once you are ready, woro let's you push them online to a remote storage like FTP or other adapters like Gist or S3.
13
13
  Using a mina deployment setup, these tasks are downloaded on the remote system, executed by rake and cleaned up afterwards.
14
14
 
15
+ ### Adapters
16
+
17
+ By default Woro comes with support for FTP, but additional adapters are available:
18
+
19
+ * [woro-gist](https://github.com/github/woro-gist)
20
+ * [woro-s3](https://github.com/github/woro-s3)
21
+
15
22
  ## Installation
16
23
 
17
24
  Add this line to your application's Gemfile:
@@ -87,7 +94,7 @@ Once you are done writing the task and you want to execute it on the remote syst
87
94
  First you have to push them online, in this case to Gist.
88
95
 
89
96
  ```shell
90
- $ woro push gist:cleanup_users
97
+ $ woro push ftp:cleanup_users
91
98
  ```
92
99
 
93
100
  _Attention, depending on whether you set up a Gist/Github login on
@@ -97,13 +104,13 @@ private under the specified Github account._
97
104
  Now, to run a task remotely using Mina, specify the task:
98
105
 
99
106
  ```shell
100
- $ mina woro:run task=gist:cleanup_users
107
+ $ mina woro:run task=ftp:cleanup_users
101
108
  ```
102
109
 
103
110
  Or to run it with Capistrano:
104
111
 
105
112
  ```shell
106
- $ cap woro:run task=gist:cleanup_users
113
+ $ cap woro:run task=ftp:cleanup_users
107
114
  ```
108
115
 
109
116
  To show a list of all tasks uploaded to any collection do:
@@ -116,7 +123,7 @@ $ woro ls
116
123
  And finally you can download an existing task to your local woro tasks directory.
117
124
 
118
125
  ```shell
119
- $ woro pull gist:cleanup_users
126
+ $ woro pull ftp:cleanup_users
120
127
  ```
121
128
 
122
129
  ## Testing
data/bin/woro CHANGED
@@ -14,8 +14,7 @@ to just do it in the remote console and using database migrations would be evil.
14
14
  A rake task would be nice, but checking this in with the source code repository
15
15
  adds clutter, as you know you will only run this once.
16
16
  Woro offers a quick way of pushing rake tasks onto the remote server, execute them
17
- and delete them instantly. Using Github\'s gist, you keep version control of the tasks
18
- and can share them with colleagues.
17
+ and delete them instantly.
19
18
 
20
19
  Woro helps you create rake tasks, that you can develop and run locally.
21
20
  Once you are ready, woro let\'s you push them online to a remote collection like Gist.
@@ -27,18 +26,19 @@ default_command :list
27
26
  def create_directory_unless_existing(directory)
28
27
  unless File.exists? directory
29
28
  FileUtils.mkdir_p directory
30
- say "Created #{directory}"
29
+ say "Created `#{directory}`"
31
30
  end
32
31
  end
33
32
 
34
33
  def create_required_files
35
34
  create_directory_unless_existing Woro::Configuration.woro_task_dir
36
35
  create_directory_unless_existing Woro::Configuration.rake_task_dir
36
+ create_directory_unless_existing File.dirname(Woro::Configuration.config_file)
37
37
 
38
38
  unless File.exists? File.join(Woro::Configuration.rake_task_dir, 'woro.rake')
39
39
  FileUtils.cp(File.dirname(__FILE__) + '/../lib/woro/templates/woro.rake',
40
40
  Woro::Configuration.rake_task_dir)
41
- say "Created woro.rake in #{Woro::Configuration.rake_task_dir}"
41
+ say "Created `woro.rake` in `#{Woro::Configuration.rake_task_dir}`"
42
42
  end
43
43
  end
44
44
 
@@ -49,42 +49,36 @@ def woro_environment_setup?
49
49
  File.exists?(File.join(Woro::Configuration.rake_task_dir, 'woro.rake'))
50
50
  end
51
51
 
52
+ def select_choice(choices)
53
+ choose do |menu|
54
+ menu.prompt = 'Please choose a service to use with Woro:'
55
+ menu.choices(*choices) do |choice|
56
+ return choice.to_s.strip
57
+ end
58
+ end
59
+ end
60
+
61
+ def choose_and_build_adapter_config(available_adapters)
62
+ adapter_name = select_choice available_adapters
63
+ adapter = Object.const_get "Woro::Adapters::#{adapter_name}"
64
+ { adapter_name => adapter.setup }
65
+ end
66
+
52
67
  command :init do |c|
53
68
  c.syntax = 'woro init [options]'
54
69
  c.description = 'Initialize Woro in the current Rails directory and setup Gist collection'
55
70
  c.option '--[no-]force', 'force overwrite of existing config file'
56
71
  c.action do |args, options|
57
-
58
- if agree 'Login to Gist/Github for private Woro tasks (Yes/No)? '
59
- Gist.login!
60
- #elsif agree 'Login to AWS/S3 for private Woro tasks (Yes/No)? '
61
-
62
- end
63
- # if none of these, use gist, but public
64
-
65
- # create Gist with welcome file
66
- # additional tasks will be added to this first gist
72
+ available_adapters = Woro::Adapters.constants.reject { |name| name == :Base }
73
+ adapters = {}
67
74
  begin
68
- require File.join(Dir.pwd, 'config', 'application.rb')
69
- app_name = Rails.application.class.parent_name
70
- rescue LoadError
71
- app_name = ask('Application name: ')
72
- end
73
- result = Woro::Adapters::Gist.create_initial_remote_task(app_name)
74
-
75
- # configure adapters
76
- gist_adapter = {
77
- gist_id: result['id'],
78
- public: false
79
- }
75
+ adapters.merge! choose_and_build_adapter_config(available_adapters)
76
+ end while agree('Do you want to configure another service?')
77
+ options.default(adapters: adapters )
80
78
 
81
- unless File.exists? File.dirname(Woro::Configuration.config_file)
82
- FileUtils.mkdir_p File.dirname(Woro::Configuration.config_file)
83
- end
79
+ create_required_files
84
80
 
85
- options.default(adapters: { gist: gist_adapter } )
86
81
  config = Woro::Configuration.save(options.__hash__)
87
- create_required_files
88
82
  end
89
83
  end
90
84
 
@@ -114,25 +108,25 @@ command :push do |c|
114
108
  c.syntax = 'woro push <task> [options]'
115
109
  c.summary = 'Push tasks to remote collection, updates existing tasks'
116
110
  c.description = 'Pushes one or more local tasks to the remote collection. Existing tasks by this name in the remote connection will be updated.'
117
- c.example 'Pushes the task "cleanup" to the remote collection', 'woro push cleanup'
111
+ c.example 'Pushes the task "cleanup" to the remote collection', 'woro push ftp:cleanup'
118
112
  c.action do |args, options|
119
113
  abort 'Woro environment is not set up. Call `woro init` to do so.' unless woro_environment_setup?
120
114
 
121
115
  config = Woro::Configuration.load
122
116
  args.each do |arg|
123
117
  unless arg.include?(':')
124
- say_error "Does not specify upload target"
118
+ say_error "Does not specify upload service, eg `woro push ftp:#{arg}`"
125
119
  next
126
120
  end
127
121
  adapter_name, task_name = arg.split(':')
128
- adapter = config.adapter adapter_name
129
- # Pushes a new woro task by given name to gist, this can be done multiple time.
122
+ # Pushes a new woro task by given name to storage, this can be done multiple time.
130
123
  task = Woro::Task.new(task_name)
131
124
  if task.exists?
125
+ adapter = config.adapter adapter_name
132
126
  result = adapter.push(task)
133
- say "Uploaded #{task.file_path} to #{result['url']}"
127
+ say "Uploaded `#{task.file_path} to #{result['url']}"
134
128
  else
135
- say "Task #{task.task_name} not found at #{task.file_path}"
129
+ say "Task `#{task.task_name}` not found at `#{task.file_path}`"
136
130
  end
137
131
  end
138
132
  end
@@ -142,7 +136,7 @@ command :pull do |c|
142
136
  c.syntax = 'woro pull <task> [options]'
143
137
  c.summary = 'Pull Woro task from remote repository'
144
138
  c.description = 'Pulls one task from the remote collection. Existing local tasks can be overwritten.'
145
- c.example 'Pulls the task "cleanup" from the remote collection', 'woro pull gist:cleanup'
139
+ c.example 'Pulls the task "cleanup" from the remote collection', 'woro pull ftp:cleanup'
146
140
  c.option '--[no-]force', 'force overwrite of existing task file'
147
141
  c.action do |args, options|
148
142
  abort 'Woro environment is not set up. Call `woro init` to do so.' unless woro_environment_setup?
@@ -150,7 +144,7 @@ command :pull do |c|
150
144
  config = Woro::Configuration.load
151
145
  args.each do |arg|
152
146
  unless arg.include?(':')
153
- say_error "Does not specify download target"
147
+ say_error "Does not specify download service, eg `woro pull ftp:#{arg}`"
154
148
  next
155
149
  end
156
150
  adapter_name, task_name = arg.split(':')
@@ -169,26 +163,26 @@ command :list do |c|
169
163
  c.syntax = 'woro [list|ls] [options]'
170
164
  c.description = 'List tasks'
171
165
  c.example 'List remote tasks', 'woro list'
172
- c.example 'List all tasks', 'woro list --all'
173
- c.option '-a', '--all', 'List all tasks'
166
+ #c.example 'List all tasks', 'woro list --all'
167
+ #c.option '-a', '--all', 'List all tasks'
174
168
  c.action do |args, options|
175
169
  abort 'Woro environment is not set up. Call `woro init` to do so.' unless woro_environment_setup?
176
170
  abort "invalid command. See 'woro help' for more information" unless args.empty?
177
171
  config = Woro::Configuration.load
178
- config.adapters.each do |adapter_config|
179
- puts "#{adapter_config[0]} ---"
180
- adapter = config.adapter(adapter_config[0])
181
- files = adapter.list_keys || {}
172
+ config.adapter_settings.each do |adapter_setting|
173
+ say "#{adapter_setting[0]} ---"
174
+ adapter = config.adapter(adapter_setting[0])
175
+ files = adapter.list_contents || {}
182
176
  tasks = files.map do |file_name, data|
183
177
  if file_name.include? '.rake'
184
178
  OpenStruct.new(name_with_args: file_name.split('.rake').first,
185
- comment: adapter.extract_description(data))
179
+ comment: adapter.extract_description(data[:data]))
186
180
  end
187
181
  end
188
182
  tasks.compact!
189
183
  Woro::TaskHelper.print_task_list(tasks)
190
184
  end
191
- puts "local ---"
185
+ say "local ---"
192
186
  tasks = Woro::TaskHelper.woro_task_files(config.woro_task_dir) do |file_name, data|
193
187
  OpenStruct.new(name_with_args: file_name.split('.rake').first,
194
188
  comment: Woro::TaskHelper.extract_description(data))
@@ -8,11 +8,29 @@ Feature: Configure woro
8
8
 
9
9
  Scenario: Initialize configuration without Rails environment
10
10
  When I run `woro init` interactively
11
- And I type "n\n"
12
- And I type "Rails-project\n"
13
- Then the output should contain "Initialized config file in `config/woro.yml`"
11
+ And I type "Ftp"
12
+ And I type "localhost"
13
+ And I type "Username"
14
+ And I type "Password"
15
+ And I type "/"
16
+ And I type "n"
17
+ Then the output should contain exactly:
18
+ """
19
+ 1. Ftp
20
+ Please choose a service to use with Woro:
21
+ FTP Host: FTP User: FTP Passwod: FTP Folder: |/| Do you want to configure another service?
22
+ Created `lib/woro_tasks`
23
+ Created `lib/tasks`
24
+ Created `config`
25
+ Created `woro.rake` in `lib/tasks`
26
+ Initialized config file in `config/woro.yml`
27
+
28
+ """
29
+ And the following directories should exist:
30
+ | lib/woro_tasks |
31
+ | lib/tasks |
14
32
  And the following files should exist:
15
- | config/woro.yml |
33
+ | lib/tasks/woro.rake |
16
34
 
17
35
  Scenario: Initialize configuration (no clobber)
18
36
  Given a file named "config/woro.yml" with:
@@ -20,8 +38,12 @@ Feature: Configure woro
20
38
  hello world
21
39
  """
22
40
  When I run `woro init` interactively
23
- And I type "n\n"
24
- And I type "Rails-project\n"
41
+ And I type "Ftp"
42
+ And I type "localhost"
43
+ And I type "Username"
44
+ And I type "Password"
45
+ And I type "/"
46
+ And I type "n"
25
47
  Then the output should contain "Not overwriting existing config file"
26
48
 
27
49
  Scenario: Force initialize configuration (clobber)
@@ -30,6 +52,10 @@ Feature: Configure woro
30
52
  hello world
31
53
  """
32
54
  When I run `woro init --force` interactively
33
- And I type "n\n"
34
- And I type "Rails-project\n"
55
+ And I type "Ftp"
56
+ And I type "localhost"
57
+ And I type "Username"
58
+ And I type "Password"
59
+ And I type "/"
60
+ And I type "n"
35
61
  Then the file "config/woro.yml" should not contain "hello world"
@@ -16,7 +16,6 @@ Feature: Manage Woro task
16
16
 
17
17
  """
18
18
 
19
-
20
19
  Scenario: List tasks without environment setup
21
20
  Given I run `woro list`
22
21
  Then the output should contain "Woro environment is not set up. Call `woro init` to do so."
@@ -48,6 +47,22 @@ Feature: Manage Woro task
48
47
  When I run `woro push stub:cleanup`
49
48
  Then the output should contain "Woro environment is not set up. Call `woro init` to do so."
50
49
 
50
+ Scenario: Push local task to remote without adapter name
51
+ Given the Woro environment is set up
52
+ When I run `woro push cleanup`
53
+ Then the output should contain "Does not specify upload service, eg `woro push ftp:cleanup`"
54
+
55
+ Scenario: Push unknown local task
56
+ Given the Woro environment is set up
57
+ When I run `woro push ftp:cleanup_all --trace`
58
+ Then the output should contain "Task `cleanup_all` not found at `lib/woro_tasks/cleanup_all.rake`"
59
+
51
60
  Scenario: Pull local task to remote without environment
52
61
  When I run `woro pull stub:cleanup`
53
62
  Then the output should contain "Woro environment is not set up. Call `woro init` to do so."
63
+
64
+ Scenario: Pull local task to remote without adapter name
65
+ Given the Woro environment is set up
66
+ When I run `woro pull cleanup`
67
+ Then the output should contain "Does not specify download service, eg `woro pull ftp:cleanup`"
68
+
@@ -2,7 +2,6 @@ require "aruba/cucumber"
2
2
  require 'cucumber/rspec/doubles'
3
3
 
4
4
  Before do
5
- allow(Gist).to receive(:multi_gist).and_return({ 'id' => '1234'})
6
5
  end
7
6
 
8
7
  After do
@@ -1,5 +1,14 @@
1
1
  require 'woro/version'
2
2
  require 'woro/task_helper'
3
3
  require 'woro/task'
4
- require 'woro/adapters/gist'
4
+ require 'woro/adapters/base'
5
+ require 'woro/adapters/ftp'
5
6
  require 'woro/configuration'
7
+
8
+ # require any gem with the prefix "woro" found in the gemset
9
+ [].tap do |woro_specs|
10
+ Gem::Specification::each do |spec|
11
+ woro_specs << spec.name if spec.name.start_with?('woro') && spec.name != 'woro'
12
+ end
13
+ woro_specs.uniq.each { |spec| require spec }
14
+ end
@@ -0,0 +1,49 @@
1
+ require 'commander'
2
+ module Woro
3
+ module Adapters
4
+ class Base
5
+ include ::Commander::UI
6
+
7
+ # Extract description from file content string.
8
+ # @param content [String] content of task file
9
+ # [String] description string
10
+ def extract_description(content)
11
+ Woro::TaskHelper.extract_description content
12
+ end
13
+
14
+ # Returns the list of files included in the Gist
15
+ # @return [Array] List of file names
16
+ def list_files
17
+ fail('Requires implementation')
18
+ end
19
+
20
+ # Returns the list of files included in the Gist
21
+ # @return [Hash] List of files in the format { filename: { data }}
22
+ def list_contents
23
+ fail('Requires implementation')
24
+ end
25
+
26
+ # Push this task's file content to the Gist collection on the server.
27
+ # Existing contents by the same #file_name will be overriden, but
28
+ # can be accessed via Github or Gist's API.
29
+ def push(task)
30
+ fail('Requires implementation')
31
+ end
32
+
33
+ # Creates an initial welcome gist on project setup
34
+ # @param app_name [String] Name of the app is displayed in the
35
+ # initial welcome message
36
+ def self.create_initial_remote_task(app_name, access_token = nil)
37
+ # not implemented
38
+ end
39
+
40
+ # The raw url is a permalink for downloading the content rake task within
41
+ # the Gist as a file.
42
+ # @param file_name [String] name of the file to retrieve the download url
43
+ # @return [String] HTTP-URL of addressed file within the gist collection
44
+ def raw_url(file_name)
45
+ fail('Requires implementation')
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,87 @@
1
+ require 'net/ftp'
2
+ module Woro
3
+ module Adapters
4
+ class Ftp < Base
5
+ attr_accessor :host, :user, :password, :folder
6
+
7
+ # Setup configuration for adapter
8
+ # Highline CLI helpers can be used for interactivity.
9
+ # @return [Hash] Configuration options
10
+ def self.setup
11
+ {
12
+ 'host' => ask('FTP Host: '),
13
+ 'user' => ask('FTP User: '),
14
+ 'password' => ask('FTP Passwod: '),
15
+ 'folder' => ask('FTP Folder: ') { |q| q.default = '/' }
16
+ }
17
+ end
18
+
19
+ def initialize(options = [])
20
+ self.host = options['host']
21
+ self.user = options['user']
22
+ self.password = options['password']
23
+ self.folder = options['folder'] || '/'
24
+ end
25
+
26
+ # Returns the list of rake files included in the remote collection.
27
+ # @return [Array] List of files
28
+ def list_files
29
+ [].tap do |files|
30
+ remote_files do |file|
31
+ files << file
32
+ end
33
+ end
34
+ end
35
+
36
+ # Returns the list of rake files included in the remote collection
37
+ # with their contents.
38
+ # @return [Hash] List of files with their contents
39
+ def list_contents
40
+ {}.tap do |files|
41
+ remote_files do |file|
42
+ ftp.gettextfile(file) do |line, newline|
43
+ content.concat newline ? line + "\n" : line
44
+ end # temporarly downloads the file
45
+ FileUtils.rm file
46
+ files[file] = { data: content }
47
+ end
48
+ end
49
+ end
50
+
51
+ # Push this task's file content to ftp server.
52
+ # Existing contents by the same #file_name will be overriden.
53
+ def push(task)
54
+ client do |ftp|
55
+ ftp.chdir(folder)
56
+ ftp.put(task.file_path, task.file_name)
57
+ end
58
+ end
59
+
60
+ # The raw url is for downloading the rake task content via ftp.
61
+ # @param file_name [String] name of the file to retrieve the download url
62
+ # @return [String] HTTP-URL of addressed file within the gist collection
63
+ def raw_url(file_name)
64
+ "ftp://#{user}@#{host}#{folder}#{file_name}"
65
+ end
66
+
67
+ protected
68
+
69
+ def remote_files
70
+ client do |ftp|
71
+ ftp.chdir(folder)
72
+ ftp.nlst.each do |file|
73
+ yield file if file.include?('.rake')
74
+ end
75
+ end
76
+ end
77
+
78
+ def client
79
+ Net::FTP.open(host, user, password) do |ftp|
80
+ yield(ftp)
81
+ end
82
+ rescue => e
83
+ say_error "Error connecting to ftp://#{host}: #{e.message}"
84
+ end
85
+ end
86
+ end
87
+ end
@@ -4,20 +4,20 @@ include Commander::UI
4
4
 
5
5
  module Woro
6
6
  class Configuration
7
- attr_reader :adapters, :woro_task_dir, :app_name
7
+ attr_reader :adapter_settings, :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
- @adapters = options[:adapters] || {}
13
- @app_name = options[:app_name]
12
+ @adapter_settings = options['adapters'] || {}
13
+ @app_name = options['app_name']
14
14
  end
15
15
 
16
16
  # Load configuration file or default_options. Passed options take precedence.
17
17
  def self.load(options = {})
18
- user_options = options.reject{|k,v| ![:adapters, :app_name].include? k}
18
+ user_options = options.reject { |k, v| !['adapters', 'app_name'].include? k }
19
19
 
20
- if !(File.exists? config_file)
20
+ unless File.exist? config_file
21
21
  File.open(config_file, 'w') { |file| YAML.dump(default_options, file) }
22
22
  say "Initialized default config file in `#{config_file}`. See 'woro help init' for options."
23
23
  end
@@ -28,10 +28,10 @@ module Woro
28
28
 
29
29
  # Save configuration. Passed options take precendence over default_options.
30
30
  def self.save(options = {})
31
- user_options = options.reject{|k,v| ![:adapters, :app_name].include? k}
31
+ user_options = options.reject { |k, v| !['adapters', 'app_name'].include? k }
32
32
  force_save = options.delete :force
33
33
 
34
- if !(File.exists? config_file) || force_save
34
+ if !File.exist?(config_file) || force_save
35
35
  File.open(config_file, 'w') do |file|
36
36
  YAML.dump(default_options.merge(user_options), file)
37
37
  end
@@ -42,13 +42,9 @@ module Woro
42
42
  self
43
43
  end
44
44
 
45
- def adapter(name)
46
- options = adapters[name.to_sym]
47
-
48
- case name.to_sym
49
- when :gist
50
- @gist_adapter ||= Woro::Adapters::Gist.new(options[:gist_id])
51
- end
45
+ def adapter(adapter_name)
46
+ clazz = Object.const_get("Woro::Adapters::#{adapter_name.capitalize}")
47
+ clazz.new adapter_settings[adapter_name.downcase]
52
48
  end
53
49
 
54
50
  # Helpers
@@ -10,7 +10,8 @@ module Woro
10
10
  @task_name = Woro::Task.sanitize_task_name task_name
11
11
  end
12
12
 
13
- # @param task_name [String] sanitized name of the task, used throughout the further processing
13
+ # @param task_name [String] sanitized name of the task, used
14
+ # throughout the further processing
14
15
  # @return [Task] the created task
15
16
  def self.create(task_name)
16
17
  task = Woro::Task.new(task_name)
@@ -52,6 +53,7 @@ module Woro
52
53
  end
53
54
 
54
55
  # Read the content of the local rake task file on #file_path.
56
+ # @return [String] file content
55
57
  def read_task_file
56
58
  File.read(file_path)
57
59
  end
@@ -1,8 +1,6 @@
1
1
  module Woro
2
2
  class TaskHelper
3
-
4
3
  class << self
5
-
6
4
  def print_task_list(tasks)
7
5
  width ||= tasks.map { |t| t.name_with_args.length }.max || 10
8
6
  tasks.each do |t|
@@ -15,7 +15,7 @@ namespace :woro do
15
15
  task = Woro::Task.new(task_name)
16
16
  print_status "Execute #{task.task_name} remotely"
17
17
  in_directory "#{app_path}" do
18
- queue! "cd 'lib/tasks' && curl #{adapter.raw_url(task.file_name)} -o woro_#{task.file_name}"
18
+ queue! "curl '#{adapter.raw_url(task.file_name)}' -o lib/tasks/woro_#{task.file_name}"
19
19
  queue! "#{bundle_prefix} rake woro:#{task.task_name}"
20
20
  queue! "rm lib/tasks/woro_#{task.file_name}"
21
21
  end
@@ -1,4 +1,4 @@
1
1
  module Woro
2
2
  # Look shiny!
3
- VERSION = "0.2.2"
3
+ VERSION = "0.3.0"
4
4
  end
@@ -5,11 +5,11 @@ describe Woro::Configuration do
5
5
  describe '#initialize' do
6
6
  it 'instantiates object' do
7
7
  options = {
8
- adapters: %(foo baz),
9
- app_name: 'bar'
8
+ 'adapters' => %(foo baz),
9
+ 'app_name' => 'bar'
10
10
  }
11
11
  config = Woro::Configuration.new(options)
12
- expect(config.adapters).to eq %(foo baz)
12
+ expect(config.adapter_settings).to eq %(foo baz)
13
13
  expect(config.app_name).to eq 'bar'
14
14
  end
15
15
  end
@@ -18,7 +18,7 @@ describe Woro::Configuration do
18
18
  context 'not given a configuration file' do
19
19
  it 'returns Configuration object with default options' do
20
20
  config = Woro::Configuration.load
21
- expect(config.adapters).to eq({})
21
+ expect(config.adapter_settings).to eq({})
22
22
  expect(config.app_name).to be_falsy
23
23
  end
24
24
 
@@ -32,8 +32,8 @@ describe Woro::Configuration do
32
32
  context 'given a configuration file' do
33
33
  before(:each) do
34
34
  opts = {
35
- adapters: %w(foo baz),
36
- app_name: 'bar'
35
+ 'adapters' => %w(foo baz),
36
+ 'app_name' => 'bar'
37
37
  }
38
38
  File.open(Woro::Configuration.config_file, 'w') do |file|
39
39
  YAML.dump(opts, file)
@@ -42,18 +42,18 @@ describe Woro::Configuration do
42
42
 
43
43
  it 'returns Configuration object with options in file' do
44
44
  config = Woro::Configuration.load
45
- expect(config.adapters).to eq %w(foo baz)
45
+ expect(config.adapter_settings).to eq %w(foo baz)
46
46
  expect(config.app_name).to eq 'bar'
47
47
  end
48
48
 
49
49
  context 'given options' do
50
50
  it 'overrides options in configuration file' do
51
51
  options = {
52
- adapters: %w(goo grr),
53
- app_name: 'car'
52
+ 'adapters' => %w(goo grr),
53
+ 'app_name' => 'car'
54
54
  }
55
55
  config = Woro::Configuration.load(options)
56
- expect(config.adapters).to eq %w(goo grr)
56
+ expect(config.adapter_settings).to eq %w(goo grr)
57
57
  expect(config.app_name).to eq 'car'
58
58
  end
59
59
  end
@@ -63,8 +63,8 @@ describe Woro::Configuration do
63
63
  describe '.save' do
64
64
  let(:options) do
65
65
  {
66
- adapters: ['foo', 'baz'],
67
- app_name: 'bar'
66
+ 'adapters' => ['foo', 'baz'],
67
+ 'app_name' => 'bar'
68
68
  }
69
69
  end
70
70
 
@@ -79,8 +79,8 @@ describe Woro::Configuration do
79
79
  context 'given a configuration file' do
80
80
  before(:each) do
81
81
  opts = {
82
- adapters: ['goo', 'grr'],
83
- app_name: 'car'
82
+ 'adapters' => ['goo', 'grr'],
83
+ 'app_name' => 'car'
84
84
  }
85
85
  File.open(Woro::Configuration.config_file, 'w') do |file|
86
86
  YAML.dump(opts, file)
@@ -18,7 +18,6 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.add_dependency "gist"
22
21
  spec.add_dependency "commander"
23
22
 
24
23
  spec.add_development_dependency "bundler", "~> 1.7"
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: woro
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.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-06-27 00:00:00.000000000 Z
11
+ date: 2015-07-01 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: gist
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: '0'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: commander
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -171,7 +157,8 @@ files:
171
157
  - lib/capistrano/woro.rb
172
158
  - lib/mina/woro.rb
173
159
  - lib/woro.rb
174
- - lib/woro/adapters/gist.rb
160
+ - lib/woro/adapters/base.rb
161
+ - lib/woro/adapters/ftp.rb
175
162
  - lib/woro/configuration.rb
176
163
  - lib/woro/task.rb
177
164
  - lib/woro/task_helper.rb
@@ -181,8 +168,6 @@ files:
181
168
  - lib/woro/templates/woro.rake
182
169
  - lib/woro/version.rb
183
170
  - spec/fixtures/cleanup.rake
184
- - spec/fixtures/gist.json
185
- - spec/lib/woro/adapters/gist_spec.rb
186
171
  - spec/lib/woro/configuration_spec.rb
187
172
  - spec/lib/woro/task_spec.rb
188
173
  - spec/spec_helper.rb
@@ -218,8 +203,6 @@ test_files:
218
203
  - features/step_definitions/woro_steps.rb
219
204
  - features/support/env.rb
220
205
  - spec/fixtures/cleanup.rake
221
- - spec/fixtures/gist.json
222
- - spec/lib/woro/adapters/gist_spec.rb
223
206
  - spec/lib/woro/configuration_spec.rb
224
207
  - spec/lib/woro/task_spec.rb
225
208
  - spec/spec_helper.rb
@@ -1,82 +0,0 @@
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
@@ -1,103 +0,0 @@
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
- }
@@ -1,62 +0,0 @@
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