fanforce-cli 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +19 -0
- data/.rbenv-gemsets +1 -0
- data/.rbenv-version +1 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +91 -0
- data/LICENSE.txt +22 -0
- data/README.md +144 -0
- data/Rakefile +1 -0
- data/bin/fanforce +20 -0
- data/bin/fanforce-supercharge +7 -0
- data/fanforce-cli.gemspec +31 -0
- data/lib/fanforce/cli/_base.rb +264 -0
- data/lib/fanforce/cli/app.rb +57 -0
- data/lib/fanforce/cli/apps.rb +41 -0
- data/lib/fanforce/cli/commands.rb +506 -0
- data/lib/fanforce/cli/commands_support.rb +210 -0
- data/lib/fanforce/cli/env.rb +41 -0
- data/lib/fanforce/cli/files.rb +266 -0
- data/lib/fanforce/cli/help.rb +93 -0
- data/lib/fanforce/cli/run.rb +51 -0
- data/lib/fanforce/cli/utils.rb +51 -0
- data/lib/fanforce/cli/version.rb +5 -0
- data/lib/fanforce/cli.rb +12 -0
- metadata +194 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2c93a7d41d24ba4fffa283343bf5b1cec0923efb
|
4
|
+
data.tar.gz: 6a267ce03515d30b0b2893adffc43a9df2bb24c6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 173946476976342ebf6777d1095f1ac1fd7c8d3f32135865d0beefe106d058bb5a39341ae21855188a7623a2bf49d7403727837f49bb9c524ac173cadcd49eb3
|
7
|
+
data.tar.gz: 830fde0a3d785a7c4fcfc54911490d23551cc984eb3e0d1fbf06e011dd50aa6c23a9e8d87df15ca05c0770ac3ba9a3266a305c22c959d20271676be74627502e
|
data/.gitignore
ADDED
data/.rbenv-gemsets
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
fanforce-cli
|
data/.rbenv-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.0.0-p247
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
fanforce-cli (1.0.0)
|
5
|
+
activesupport
|
6
|
+
bitbucket_rest_api
|
7
|
+
fanforce-api
|
8
|
+
heroku-api (= 0.3.8)
|
9
|
+
iron_worker_ng
|
10
|
+
multi_json
|
11
|
+
redis
|
12
|
+
rest-client
|
13
|
+
|
14
|
+
GEM
|
15
|
+
remote: https://rubygems.org/
|
16
|
+
specs:
|
17
|
+
activesupport (4.1.4)
|
18
|
+
i18n (~> 0.6, >= 0.6.9)
|
19
|
+
json (~> 1.7, >= 1.7.7)
|
20
|
+
minitest (~> 5.1)
|
21
|
+
thread_safe (~> 0.1)
|
22
|
+
tzinfo (~> 1.1)
|
23
|
+
activesupport-inflector (0.1.0)
|
24
|
+
bitbucket_rest_api (0.1.5)
|
25
|
+
faraday (~> 0.8.1)
|
26
|
+
faraday_middleware (~> 0.9.0)
|
27
|
+
hashie (~> 2.0.5)
|
28
|
+
multi_json (~> 1.3)
|
29
|
+
nokogiri (>= 1.5.2)
|
30
|
+
simple_oauth
|
31
|
+
excon (0.16.10)
|
32
|
+
fanforce (0.19.0)
|
33
|
+
multi_json (>= 1.7.2)
|
34
|
+
rack
|
35
|
+
fanforce-api (0.23.0)
|
36
|
+
fanforce-exceptions (~> 0.5)
|
37
|
+
fanforce-validations (~> 0.7)
|
38
|
+
rest-client (~> 1.6.7)
|
39
|
+
fanforce-exceptions (0.5.1)
|
40
|
+
fanforce (~> 0.15)
|
41
|
+
fanforce-validations (0.7.1)
|
42
|
+
activesupport-inflector (~> 0.1)
|
43
|
+
fanforce (~> 0.15)
|
44
|
+
fanforce-exceptions (~> 0.5)
|
45
|
+
faraday (0.8.9)
|
46
|
+
multipart-post (~> 1.2.0)
|
47
|
+
faraday_middleware (0.9.1)
|
48
|
+
faraday (>= 0.7.4, < 0.10)
|
49
|
+
hashie (2.0.5)
|
50
|
+
heroku-api (0.3.8)
|
51
|
+
excon (~> 0.16.10)
|
52
|
+
i18n (0.6.11)
|
53
|
+
iron_core (1.0.5)
|
54
|
+
rest (>= 2.6.4)
|
55
|
+
iron_worker_ng (1.5.0)
|
56
|
+
bundler
|
57
|
+
iron_core (>= 1.0.0)
|
58
|
+
rubyzip (= 0.9.9)
|
59
|
+
json (1.8.1)
|
60
|
+
mime-types (1.25.1)
|
61
|
+
mini_portile (0.6.0)
|
62
|
+
minitest (5.4.0)
|
63
|
+
multi_json (1.10.1)
|
64
|
+
multipart-post (1.2.0)
|
65
|
+
net-http-persistent (2.9.4)
|
66
|
+
netrc (0.7.7)
|
67
|
+
nokogiri (1.6.3.1)
|
68
|
+
mini_portile (= 0.6.0)
|
69
|
+
rack (1.5.2)
|
70
|
+
rdoc (4.1.1)
|
71
|
+
json (~> 1.4)
|
72
|
+
redis (3.1.0)
|
73
|
+
rest (2.7.2)
|
74
|
+
net-http-persistent (>= 2.9.1)
|
75
|
+
rest_client (>= 1.7.1)
|
76
|
+
rest-client (1.6.8)
|
77
|
+
mime-types (~> 1.16)
|
78
|
+
rdoc (>= 2.4.2)
|
79
|
+
rest_client (1.7.3)
|
80
|
+
netrc (~> 0.7.7)
|
81
|
+
rubyzip (0.9.9)
|
82
|
+
simple_oauth (0.2.0)
|
83
|
+
thread_safe (0.3.4)
|
84
|
+
tzinfo (1.2.2)
|
85
|
+
thread_safe (~> 0.1)
|
86
|
+
|
87
|
+
PLATFORMS
|
88
|
+
ruby
|
89
|
+
|
90
|
+
DEPENDENCIES
|
91
|
+
fanforce-cli!
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Caleb Clark
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
# fanforce-cli
|
2
|
+
The simplest way to create and manage a folder of Fanforce apps. This gem provides
|
3
|
+
bulk commands that you can run against your entire list.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Run this command from your command line:
|
8
|
+
|
9
|
+
gem install fanforce-cli
|
10
|
+
|
11
|
+
## Usage
|
12
|
+
|
13
|
+
Run this command to view usage instructions
|
14
|
+
|
15
|
+
$ fanforce
|
16
|
+
|
17
|
+
|
18
|
+
## Customizing Your Fanforce CLI Setup with .fanforce-cli
|
19
|
+
You can add a .fanforce-cli to any fanforce folder you've setup for your apps. It accepts any valid YAML markup.
|
20
|
+
Below is a example file that sets a custom local path for the fanforce-app-factory gem, plus a version:
|
21
|
+
|
22
|
+
```yaml
|
23
|
+
app_factory_gem:
|
24
|
+
path: '../../fanforce-app-factory'
|
25
|
+
version: '~> 0.1.3'
|
26
|
+
```
|
27
|
+
For more options see BitBucket and Heroku below.
|
28
|
+
|
29
|
+
|
30
|
+
## Run Fanforce CLI Inside of an App
|
31
|
+
|
32
|
+
Sometimes you'll want to use cli commands inside a specific app. You can as long as the folder contains a config.ru
|
33
|
+
file, and the app is a subdirectory of a fanforce folder containing a .fanforce-cli file.
|
34
|
+
|
35
|
+
|
36
|
+
## Supercharge Your Fanforce CLI
|
37
|
+
|
38
|
+
Fanforce-cli comes with a special application when you're running commands on a long list of apps and
|
39
|
+
each command is taking a long time to run. It forks each command and runs them in parallel. Only a subset of the full
|
40
|
+
cli commands are available with fanforce-supercharge. Run the following from your terminal to see your available
|
41
|
+
options:
|
42
|
+
|
43
|
+
```
|
44
|
+
fanforce-supercharge
|
45
|
+
```
|
46
|
+
|
47
|
+
## BitBucket: Creating Repositories and Pushing
|
48
|
+
A BitBucket repository will be automatically setup for each new app if a bitbucket object is defined in your .fanforce-cli file:
|
49
|
+
|
50
|
+
```yaml
|
51
|
+
bitbucket:
|
52
|
+
user: apps-by-me
|
53
|
+
password: password
|
54
|
+
```
|
55
|
+
|
56
|
+
## Heroku Apps: Creating and Updating
|
57
|
+
A heroku app will be automatically setup for each new app if a heroku object is defined in your .fanforce-cli file. You'll need
|
58
|
+
one for each environment (staging|production) you want apps setup for.
|
59
|
+
|
60
|
+
```yaml
|
61
|
+
heroku:
|
62
|
+
production:
|
63
|
+
user: technical@fanforce.com
|
64
|
+
git_ssh_domain: heroku_fanforce
|
65
|
+
password: password
|
66
|
+
app_domain: ffapp.io
|
67
|
+
short_domain: fanforce.io
|
68
|
+
```
|
69
|
+
The git_ssh_domain variable listed above is needed if you're pushing to multiple Heroku accounts as you'll need to specify
|
70
|
+
the SSH key that must be used (each Heroku account requires a unique ssh key). For example, the above git_ssh_domain variable
|
71
|
+
references the following lines in ~/.ssh/config:
|
72
|
+
|
73
|
+
```
|
74
|
+
Host heroku_fanforce
|
75
|
+
HostName heroku.com
|
76
|
+
User technical@fanforce.com
|
77
|
+
IdentityFile ~/.ssh/heroku_fanforce
|
78
|
+
```
|
79
|
+
|
80
|
+
See http://www.springloops.com/blog/git-config-for-mutiply-ssh-keys/ for more info.
|
81
|
+
|
82
|
+
## Environment Variables
|
83
|
+
Fanforce CLI allows you to setup a list of env variables that can be loaded by your app it's running in your local
|
84
|
+
development environment, pushed to Heroku, or tasks setup on IronWorker.
|
85
|
+
|
86
|
+
First, you need to setup a folder called ".env" in your fanforce folder with a series of YAML files inside. The only required
|
87
|
+
file is _bind.yaml:
|
88
|
+
|
89
|
+
```yaml
|
90
|
+
constantcontact:
|
91
|
+
- app-constantcontact
|
92
|
+
- plugin-constantcontact-subscribers
|
93
|
+
|
94
|
+
facebook:
|
95
|
+
- app-facebook
|
96
|
+
- plugin-facebook-friends
|
97
|
+
- plugin-facebook-posts
|
98
|
+
|
99
|
+
iron: ALL
|
100
|
+
```
|
101
|
+
|
102
|
+
Each key is the filename (minus .yaml) of the YAML file holding a list of ENV variables. The array underneath is the folder names of apps
|
103
|
+
that these ENV variables will be loaded into. Alternatively, you can specify the keyword ALL if those ENV variables should
|
104
|
+
be loaded into all apps.
|
105
|
+
|
106
|
+
Second, you'll need to setup the filenames references in _bind.yaml. Each file contains a hash of ENV key/values organized
|
107
|
+
by RACK_ENV. Here's is an example of facebook.yaml (of course, you'll need to provide legit facebook api_keys and api_secrets):
|
108
|
+
|
109
|
+
```yaml
|
110
|
+
development:
|
111
|
+
api_key: 175620799120142
|
112
|
+
api_secret: b4e86cbf9db2ch5777609396b1d0a52f
|
113
|
+
|
114
|
+
staging:
|
115
|
+
api_key: 362017347478160
|
116
|
+
api_secret: cf3605c0cnda02c95ddd1bb983a59e7a
|
117
|
+
```
|
118
|
+
|
119
|
+
## Using IronWorker
|
120
|
+
|
121
|
+
Fanforce CLI comes with built in support for using IronWorker in your apps:
|
122
|
+
|
123
|
+
```
|
124
|
+
fanforce iron upload:development
|
125
|
+
```
|
126
|
+
|
127
|
+
There are a couple things you'll want to setup first:
|
128
|
+
|
129
|
+
#### 1. Env Variables
|
130
|
+
|
131
|
+
- IRON_TOKEN
|
132
|
+
- IRON_PROJECT_ID
|
133
|
+
|
134
|
+
#### 2.
|
135
|
+
|
136
|
+
|
137
|
+
|
138
|
+
## Contributing
|
139
|
+
|
140
|
+
1. Fork it
|
141
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
142
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
143
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
144
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/fanforce
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'fanforce/cli'
|
3
|
+
|
4
|
+
fanforce = Fanforce::CLI.new('fanforce')
|
5
|
+
|
6
|
+
if File.exists?("#{$HomeDir}/config.ru") and File.exists?("#{$HomeDir}/../.fanforce-cli")
|
7
|
+
ARGV.unshift(":#{File.basename($HomeDir)}")
|
8
|
+
$HomeDir = File.expand_path('..', $HomeDir)
|
9
|
+
fanforce.start(
|
10
|
+
:runtype => :single,
|
11
|
+
:allowed => [:update, :push, :restart, :bundle, :git, :iron, :version, :config, :cleanorgs, :upgrade],
|
12
|
+
)
|
13
|
+
elsif File.exists?("#{$HomeDir}/.fanforce-cli")
|
14
|
+
fanforce.start(
|
15
|
+
:runtype => :multiple,
|
16
|
+
:allowed => [:list, :create, :update, :delete, :push, :restart, :count, :bundle, :git, :iron, :version, :config, :cleanorgs, :upgrade],
|
17
|
+
)
|
18
|
+
else
|
19
|
+
puts 'NOT A VALID DIRECTORY'
|
20
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'fanforce/cli/version'
|
5
|
+
require 'rubygems'
|
6
|
+
|
7
|
+
Gem::Specification.new do |gem|
|
8
|
+
gem.name = 'fanforce-cli'
|
9
|
+
gem.version = Fanforce::CLI::VERSION
|
10
|
+
gem.authors = ['Caleb Clark']
|
11
|
+
gem.email = ['cclark@mobilizationlabs.com']
|
12
|
+
gem.description = %q{CLI for managing a folder of Fanforce apps}
|
13
|
+
gem.summary = %q{Manage a folder of Fanforce apps}
|
14
|
+
gem.homepage = ''
|
15
|
+
|
16
|
+
gem.files = `git ls-files`.split($/)
|
17
|
+
gem.executables = ['fanforce','fanforce-supercharge']
|
18
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
19
|
+
gem.require_paths = ['lib']
|
20
|
+
|
21
|
+
gem.add_dependency 'redis'
|
22
|
+
gem.add_dependency 'rest-client'
|
23
|
+
gem.add_dependency 'iron_worker_ng'
|
24
|
+
gem.add_dependency 'activesupport'
|
25
|
+
gem.add_dependency 'heroku-api', '0.3.8'
|
26
|
+
gem.add_dependency 'multi_json'
|
27
|
+
gem.add_dependency 'bitbucket_rest_api'
|
28
|
+
gem.add_dependency 'fanforce'
|
29
|
+
gem.add_dependency 'fanforce-api'
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,264 @@
|
|
1
|
+
require 'iron_worker_ng'
|
2
|
+
require 'fanforce/cli'
|
3
|
+
|
4
|
+
class Fanforce::CLI
|
5
|
+
require 'fanforce/cli/utils'
|
6
|
+
require 'fanforce/cli/files'
|
7
|
+
require 'fanforce/cli/app'
|
8
|
+
require 'fanforce/cli/apps'
|
9
|
+
require 'fanforce/cli/run'
|
10
|
+
require 'fanforce/cli/env'
|
11
|
+
require 'fanforce/cli/help'
|
12
|
+
require 'fanforce/cli/commands'
|
13
|
+
include Fanforce::CLI::Utils
|
14
|
+
|
15
|
+
def initialize(executable)
|
16
|
+
@executable = executable
|
17
|
+
$HomeDir = Shell.new.pwd
|
18
|
+
end
|
19
|
+
|
20
|
+
def start(options)
|
21
|
+
@runtype = options[:runtype]
|
22
|
+
@allowed_commands = options[:allowed]
|
23
|
+
setup_config
|
24
|
+
init_counter(Process.pid) if @runtype == :forked
|
25
|
+
parse_app_filter
|
26
|
+
parse_command
|
27
|
+
destroy_counter(Process.pid) if @runtype == :forked
|
28
|
+
end
|
29
|
+
|
30
|
+
def setup_config
|
31
|
+
puts 'ERROR: Fanforce CLI could not find the required config file.'.format(:red) if !File.exists?("#{$HomeDir}/.fanforce-cli")
|
32
|
+
$Config = format_config(YAML.load_file("#{$HomeDir}/.fanforce-cli"))
|
33
|
+
end
|
34
|
+
|
35
|
+
def parse_app_filter
|
36
|
+
if ARGV[0] =~ /^:((app)-(.+))$/
|
37
|
+
$Filter = {dir_name: $1}
|
38
|
+
ARGV.shift
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
#################################################################################
|
43
|
+
|
44
|
+
def parse_command
|
45
|
+
|
46
|
+
#################################################################
|
47
|
+
|
48
|
+
if ARGV.length == 0 or !@allowed_commands.include?(ARGV[0].to_sym)
|
49
|
+
puts Fanforce::CLI::Help.intro(@executable, @runtype)
|
50
|
+
puts Fanforce::CLI::Help.commands(@allowed_commands)
|
51
|
+
|
52
|
+
#################################################################
|
53
|
+
|
54
|
+
elsif ARGV[0] == 'list'
|
55
|
+
list_apps
|
56
|
+
|
57
|
+
#################################################################
|
58
|
+
|
59
|
+
elsif ARGV[0] == 'create'
|
60
|
+
ARGV[1] =~ /^app-([a-z0-9-]+)$/i || error('You supplied an invalid create command.', :create)
|
61
|
+
create_app($1)
|
62
|
+
|
63
|
+
#################################################################
|
64
|
+
|
65
|
+
elsif ARGV[0] == 'update'
|
66
|
+
ARGV[1] =~ /^(all|app-([a-z0-9-]+))$/ || error('You supplied an invalid update command.', :update) if ARGV[1]
|
67
|
+
($2 && $2 != 'all') ? update_app($2) : run(:update)
|
68
|
+
|
69
|
+
#################################################################
|
70
|
+
|
71
|
+
elsif ARGV[0] == 'delete'
|
72
|
+
ARGV[1] =~ /^app-([a-z0-9-]+)$/ || error('You supplied an invalid delete command.', :delete)
|
73
|
+
confirm("Are you sure you want to delete all files, repositories, and other items for #{ARGV[1]}?")
|
74
|
+
delete_app($1)
|
75
|
+
|
76
|
+
#################################################################
|
77
|
+
|
78
|
+
elsif ARGV[0] == 'push'
|
79
|
+
ARGV[1] =~ /^(all|development|staging|production)$/ || error('You supplied an invalid push command.', :push)
|
80
|
+
environment = $1.to_sym
|
81
|
+
command = (ARGV[2] =~ /(:all|:heroku|:iron|bitbucket)$/) ? $1.to_sym : :all
|
82
|
+
|
83
|
+
confirm('Are you sure you want to push to all environments, including production?') if environment == :all
|
84
|
+
confirm('Are you sure you want to push to production?') if environment == :production
|
85
|
+
confirm("Are you sure you want to push to all services on #{environment}?") if command == :all
|
86
|
+
|
87
|
+
run(:push, environment, command)
|
88
|
+
|
89
|
+
#################################################################
|
90
|
+
|
91
|
+
elsif ARGV[0] == 'restart'
|
92
|
+
if ARGV[1].present?
|
93
|
+
ARGV[1] =~ /^(development|staging|production|all)?$/ || error('You supplied an invalid restart command.', :restart)
|
94
|
+
environment = $1.to_sym
|
95
|
+
else
|
96
|
+
environment = :development
|
97
|
+
end
|
98
|
+
|
99
|
+
confirm('Are you sure you want to restart all environments?') if environment == :all
|
100
|
+
run(:restart, environment)
|
101
|
+
|
102
|
+
#################################################################
|
103
|
+
|
104
|
+
elsif ARGV[0] == 'count'
|
105
|
+
count
|
106
|
+
|
107
|
+
#################################################################
|
108
|
+
|
109
|
+
elsif ARGV[0] == 'bundle'
|
110
|
+
ARGV[1] =~ /^(install|update)$/ || error('You supplied an invalid bundle command.', :bundle)
|
111
|
+
|
112
|
+
run(:bundle, $1.to_sym, ARGV[3..-1] || [])
|
113
|
+
|
114
|
+
#################################################################
|
115
|
+
|
116
|
+
elsif ARGV[0] == 'git' and ARGV[1] == 'status:overview'
|
117
|
+
run(:git_overview)
|
118
|
+
|
119
|
+
elsif ARGV[0] == 'git'
|
120
|
+
run(:git, ARGV[1..-1] || [])
|
121
|
+
|
122
|
+
#################################################################
|
123
|
+
|
124
|
+
elsif ARGV[0] == 'iron'
|
125
|
+
ARGV[1] =~ /^(upload|reset|delete)$/ || error('You supplied an invalid iron command.', :iron)
|
126
|
+
command = $1.to_sym
|
127
|
+
|
128
|
+
if ARGV[2].blank? or ARGV[2] =~ /^(all|development|staging|production)$/
|
129
|
+
environment = ($1.present?) ? $1.to_sym : :all
|
130
|
+
confirm("Are you sure you want to #{command} workers in all environments?") if environment == :all
|
131
|
+
else
|
132
|
+
error('You supplied an invalid iron environment.', :iron)
|
133
|
+
end
|
134
|
+
|
135
|
+
if command == :delete
|
136
|
+
delete_all_iron_workers(environment)
|
137
|
+
else
|
138
|
+
run(:iron, command, environment)
|
139
|
+
end
|
140
|
+
|
141
|
+
#################################################################
|
142
|
+
|
143
|
+
elsif ARGV[0] == 'cleanorgs'
|
144
|
+
ARGV[1] =~ /^(development|staging|production)$/ || error('You supplied an invalid cleanorgs command.', :cleanorgs)
|
145
|
+
environment = $1.to_sym
|
146
|
+
|
147
|
+
supercore_api_key = ARGV[2] || error('You supplied an invalid cleanorgs command.', :cleanorgs)
|
148
|
+
|
149
|
+
run(:cleanorgs, environment, supercore_api_key)
|
150
|
+
|
151
|
+
#################################################################
|
152
|
+
|
153
|
+
elsif ARGV[0] == 'version'
|
154
|
+
puts '---------------------------------------------------------------------------------------------------------------'
|
155
|
+
puts "You are using version #{Fanforce::CLI::VERSION} of Fanforce CLI"
|
156
|
+
puts '---------------------------------------------------------------------------------------------------------------'
|
157
|
+
|
158
|
+
elsif ARGV[0] == 'config'
|
159
|
+
puts '---------------------------------------------------------------------------------------------------------------'
|
160
|
+
if !File.exists?("#{$HomeDir}/.fanforce-cli")
|
161
|
+
puts 'Oops'.format(:red,:bold) + '... no ".fanforce-cli" file was found in this directory.'.format(:red)
|
162
|
+
else
|
163
|
+
puts $Config
|
164
|
+
end
|
165
|
+
puts '---------------------------------------------------------------------------------------------------------------'
|
166
|
+
|
167
|
+
elsif ARGV[0] == 'upgrade'
|
168
|
+
run(:upgrade)
|
169
|
+
|
170
|
+
end
|
171
|
+
|
172
|
+
end
|
173
|
+
|
174
|
+
#################################################################################
|
175
|
+
|
176
|
+
def run(method, *args)
|
177
|
+
(@runtype == :forked) ? run_forked(method, *args) : run_multiple(method, *args)
|
178
|
+
end
|
179
|
+
|
180
|
+
def run_multiple(method, *args)
|
181
|
+
if (dirs = Apps.dirs).size == 0
|
182
|
+
puts "\n---------------------------------------------------------------------------------------------------------------"
|
183
|
+
puts "#{'Oops'.format(:bold)}... no fanforce apps were found in this directory."
|
184
|
+
puts "---------------------------------------------------------------------------------------------------------------\n"
|
185
|
+
return
|
186
|
+
end
|
187
|
+
|
188
|
+
if self.respond_to?(:"preprocess_#{method}")
|
189
|
+
args << self.method(:"preprocess_#{method}").call
|
190
|
+
end
|
191
|
+
Apps.each do |app, processed_count, total_count|
|
192
|
+
self.method(:"run_#{method}").call(app.dir, processed_count, total_count, *args)
|
193
|
+
end
|
194
|
+
if self.respond_to?(:"postprocess_#{method}")
|
195
|
+
self.method(:"postprocess_#{method}").call
|
196
|
+
else
|
197
|
+
puts "\n---------------------------------------------------------------------------------------------------------------"
|
198
|
+
puts 'DONE!'
|
199
|
+
puts '---------------------------------------------------------------------------------------------------------------'
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
def run_forked(method, *args)
|
204
|
+
counter_id = Process.pid
|
205
|
+
processes = []
|
206
|
+
dirs = Apps.dirs
|
207
|
+
puts "\n---------------------------------------------------------------------------------------------------------------"
|
208
|
+
dirs.each_with_index do |app_dir, i|
|
209
|
+
puts "#{'Forking'.format(:white,:bold)} #{app_dir}"
|
210
|
+
end
|
211
|
+
dirs.each_with_index do |app_dir, i|
|
212
|
+
processes << fork do
|
213
|
+
response = capture_stdout do
|
214
|
+
self.method(:"run_#{method}").call(app_dir, 'PROCESSED_APPS_COUNT', dirs.size, *args)
|
215
|
+
end
|
216
|
+
puts response.gsub('PROCESSED_APPS_COUNT', incr_counter(counter_id).to_s)
|
217
|
+
end
|
218
|
+
sleep(0.25)
|
219
|
+
end
|
220
|
+
|
221
|
+
processes.each { |pid| Process.waitpid(pid) }
|
222
|
+
puts "\n---------------------------------------------------------------------------------------------------------------"
|
223
|
+
puts 'DONE!'
|
224
|
+
puts '---------------------------------------------------------------------------------------------------------------'
|
225
|
+
end
|
226
|
+
|
227
|
+
require 'stringio'
|
228
|
+
def capture_stdout
|
229
|
+
previous_stdout, previous_stderr = $stdout, $stderr
|
230
|
+
io = StringIO.new
|
231
|
+
$stdout = io
|
232
|
+
$stderr = io
|
233
|
+
IronCore::Logger.logger = ::Logger.new(io)
|
234
|
+
IronCore::Logger.logger.level = ::Logger::INFO
|
235
|
+
yield
|
236
|
+
io.string
|
237
|
+
ensure
|
238
|
+
$stdout = previous_stdout
|
239
|
+
$stderr = previous_stderr
|
240
|
+
end
|
241
|
+
|
242
|
+
def init_counter(counter_id)
|
243
|
+
File.open("#{$HomeDir}/.forked-counter-#{counter_id}", 'w') {|f| f.write('0') }
|
244
|
+
end
|
245
|
+
|
246
|
+
def incr_counter(counter_id)
|
247
|
+
new_count = nil
|
248
|
+
File.open("#{$HomeDir}/.forked-counter-#{counter_id}", File::RDWR|File::CREAT, 0644) do |f|
|
249
|
+
f.flock(File::LOCK_EX)
|
250
|
+
new_count = f.read.to_i + 1
|
251
|
+
f.rewind
|
252
|
+
f.write("#{new_count}\n")
|
253
|
+
f.flush
|
254
|
+
f.truncate(f.pos)
|
255
|
+
end
|
256
|
+
new_count
|
257
|
+
end
|
258
|
+
|
259
|
+
def destroy_counter(counter_id)
|
260
|
+
File.delete("#{$HomeDir}/.forked-counter-#{counter_id}")
|
261
|
+
end
|
262
|
+
|
263
|
+
end
|
264
|
+
|
@@ -0,0 +1,57 @@
|
|
1
|
+
class Fanforce::CLI::App
|
2
|
+
attr_reader :_id, :dir, :dir_name, :dir_root, :root_domain
|
3
|
+
|
4
|
+
def self.parse_dir_name(dir_name)
|
5
|
+
return if dir_name !~ /^(app-([a-z0-9-]+))\/?$/
|
6
|
+
{_id: $2, dir_name: $1}
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.load(dir)
|
10
|
+
self.new(dir)
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(dir)
|
14
|
+
raise "This is an invalid directory name for a fanforce addon: #{dir}" if dir !~ /^(.*)\/(app-([a-z0-9-]+))\/?$/
|
15
|
+
@_id = $3
|
16
|
+
@dir = "#{$1}/#{$2}"
|
17
|
+
@dir_root = $1
|
18
|
+
@dir_name = $2
|
19
|
+
@root_domain = Fanforce.apps_base_domain
|
20
|
+
end
|
21
|
+
|
22
|
+
def create_files(*filenames)
|
23
|
+
filenames.each do |filename|
|
24
|
+
Fanforce::CLI::Files.method(:"create_#{filename}").call(self)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
alias create_file create_files
|
28
|
+
|
29
|
+
def update_files(*filenames)
|
30
|
+
filenames.each do |filename|
|
31
|
+
Fanforce::CLI::Files.method(:"update_#{filename}").call(self)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
alias update_file update_files
|
35
|
+
|
36
|
+
def to_hash
|
37
|
+
{
|
38
|
+
_id: @_id,
|
39
|
+
dir_name: @dir_name,
|
40
|
+
dir_root: @dir_root,
|
41
|
+
dir: @dir,
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
def to_json
|
46
|
+
to_hash.to_json
|
47
|
+
end
|
48
|
+
|
49
|
+
def start_print
|
50
|
+
print "- #{@dir_name}... "
|
51
|
+
end
|
52
|
+
|
53
|
+
def end_print
|
54
|
+
puts 'DONE'
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|