jdc 0.2.1 → 0.2.2.pre
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.
- data/LICENSE +1277 -24
- data/Rakefile +13 -0
- data/bin/jdc +12 -2
- data/lib/admin/README.md +15 -0
- data/lib/admin/curl.rb +60 -0
- data/lib/admin/guid.rb +89 -0
- data/lib/admin/plugin.rb +6 -0
- data/lib/admin/service_auth_token.rb +94 -0
- data/lib/admin/service_broker/add.rb +47 -0
- data/lib/admin/service_broker/service_brokers.rb +24 -0
- data/lib/admin/set_quota.rb +44 -0
- data/lib/console/README.md +8 -0
- data/lib/console/console.rb +187 -0
- data/lib/console/plugin.rb +33 -0
- data/lib/jdc.rb +15 -2
- data/lib/jdc/cli.rb +556 -0
- data/lib/jdc/cli/app/app.rb +43 -0
- data/lib/jdc/cli/app/apps.rb +87 -0
- data/lib/jdc/cli/app/base.rb +72 -0
- data/lib/jdc/cli/app/delete.rb +95 -0
- data/lib/jdc/cli/app/deprecated.rb +11 -0
- data/lib/jdc/cli/app/env.rb +78 -0
- data/lib/jdc/cli/app/events.rb +45 -0
- data/lib/jdc/cli/app/files.rb +137 -0
- data/lib/jdc/cli/app/health.rb +26 -0
- data/lib/jdc/cli/app/instances.rb +53 -0
- data/lib/jdc/cli/app/logs.rb +76 -0
- data/lib/jdc/cli/app/push.rb +103 -0
- data/lib/jdc/cli/app/push/create.rb +108 -0
- data/lib/jdc/cli/app/push/interactions.rb +86 -0
- data/lib/jdc/cli/app/push/sync.rb +57 -0
- data/lib/jdc/cli/app/rename.rb +35 -0
- data/lib/jdc/cli/app/restart.rb +31 -0
- data/lib/jdc/cli/app/scale.rb +63 -0
- data/lib/jdc/cli/app/start.rb +161 -0
- data/lib/jdc/cli/app/stats.rb +67 -0
- data/lib/jdc/cli/app/stop.rb +27 -0
- data/lib/jdc/cli/domain/base.rb +9 -0
- data/lib/jdc/cli/domain/domains.rb +40 -0
- data/lib/jdc/cli/domain/map.rb +55 -0
- data/lib/jdc/cli/domain/unmap.rb +56 -0
- data/lib/jdc/cli/help.rb +15 -0
- data/lib/jdc/cli/interactive.rb +105 -0
- data/lib/jdc/cli/login_requirements.rb +15 -0
- data/lib/jdc/cli/organization/base.rb +14 -0
- data/lib/jdc/cli/organization/create.rb +37 -0
- data/lib/jdc/cli/organization/delete.rb +63 -0
- data/lib/jdc/cli/organization/org.rb +45 -0
- data/lib/jdc/cli/organization/orgs.rb +30 -0
- data/lib/jdc/cli/organization/rename.rb +37 -0
- data/lib/jdc/cli/populators/base.rb +16 -0
- data/lib/jdc/cli/populators/organization.rb +32 -0
- data/lib/jdc/cli/populators/populator_methods.rb +64 -0
- data/lib/jdc/cli/populators/space.rb +33 -0
- data/lib/jdc/cli/populators/target.rb +13 -0
- data/lib/jdc/cli/route/base.rb +9 -0
- data/lib/jdc/cli/route/delete.rb +28 -0
- data/lib/jdc/cli/route/map.rb +68 -0
- data/lib/jdc/cli/route/routes.rb +26 -0
- data/lib/jdc/cli/route/unmap.rb +56 -0
- data/lib/jdc/cli/service/base.rb +9 -0
- data/lib/jdc/cli/service/bind.rb +44 -0
- data/lib/jdc/cli/service/create.rb +159 -0
- data/lib/jdc/cli/service/delete.rb +83 -0
- data/lib/jdc/cli/service/rename.rb +36 -0
- data/lib/jdc/cli/service/service.rb +42 -0
- data/lib/jdc/cli/service/service_instance_helper.rb +99 -0
- data/lib/jdc/cli/service/services.rb +111 -0
- data/lib/jdc/cli/service/unbind.rb +37 -0
- data/lib/jdc/cli/space/base.rb +29 -0
- data/lib/jdc/cli/space/create.rb +67 -0
- data/lib/jdc/cli/space/delete.rb +56 -0
- data/lib/jdc/cli/space/rename.rb +38 -0
- data/lib/jdc/cli/space/space.rb +66 -0
- data/lib/jdc/cli/space/spaces.rb +57 -0
- data/lib/jdc/cli/space/switch.rb +19 -0
- data/lib/jdc/cli/start/base.rb +41 -0
- data/lib/jdc/cli/start/colors.rb +13 -0
- data/lib/jdc/cli/start/target.rb +50 -0
- data/lib/jdc/cli/start/target_prettifier.rb +17 -0
- data/lib/jdc/cli/start/targets.rb +16 -0
- data/lib/jdc/cli/user/base.rb +30 -0
- data/lib/jdc/cli/user/create.rb +52 -0
- data/lib/jdc/cli/user/passwd.rb +37 -0
- data/lib/jdc/cli/user/register.rb +43 -0
- data/lib/jdc/cli/user/users.rb +32 -0
- data/lib/jdc/constants.rb +11 -0
- data/lib/jdc/errors.rb +19 -0
- data/lib/jdc/object_extensions.rb +15 -0
- data/lib/jdc/plugin.rb +56 -0
- data/lib/jdc/spacing.rb +89 -0
- data/lib/jdc/spec_helper.rb +1 -0
- data/lib/jdc/test_support.rb +6 -0
- data/lib/jdc/version.rb +3 -0
- data/lib/manifests/errors.rb +35 -0
- data/lib/manifests/loader.rb +31 -0
- data/lib/manifests/loader/builder.rb +39 -0
- data/lib/manifests/loader/normalizer.rb +145 -0
- data/lib/manifests/loader/resolver.rb +79 -0
- data/lib/manifests/manifests.rb +344 -0
- data/lib/manifests/plugin.rb +140 -0
- data/lib/micro/README.md +9 -0
- data/lib/micro/errors.rb +4 -0
- data/lib/{jdc → micro}/micro.rb +15 -15
- data/lib/micro/plugin.rb +197 -0
- data/lib/micro/switcher/base.rb +79 -0
- data/lib/{jdc/micro → micro}/switcher/darwin.rb +5 -3
- data/lib/{jdc/micro → micro}/switcher/dummy.rb +1 -1
- data/lib/micro/switcher/linux.rb +16 -0
- data/lib/{jdc/micro → micro}/switcher/windows.rb +5 -5
- data/lib/{jdc/micro → micro}/vmrun.rb +26 -19
- data/lib/tasks/gem_release.rake +42 -0
- data/lib/tunnel/README.md +29 -0
- data/{config → lib/tunnel/config}/clients.yml +2 -2
- data/lib/tunnel/helper-app/Gemfile +10 -0
- data/lib/tunnel/helper-app/Gemfile.lock +48 -0
- data/{caldecott_helper → lib/tunnel/helper-app}/server.rb +5 -5
- data/lib/tunnel/plugin.rb +183 -0
- data/lib/tunnel/tunnel.rb +295 -0
- metadata +371 -210
- data/README.md +0 -102
- data/config/micro/paths.yml +0 -22
- data/config/micro/refresh_ip.rb +0 -20
- data/lib/cli.rb +0 -53
- data/lib/cli/commands/admin.rb +0 -58
- data/lib/cli/commands/apps.rb +0 -1129
- data/lib/cli/commands/base.rb +0 -228
- data/lib/cli/commands/manifest.rb +0 -56
- data/lib/cli/commands/micro.rb +0 -115
- data/lib/cli/commands/misc.rb +0 -126
- data/lib/cli/commands/services.rb +0 -178
- data/lib/cli/commands/user.rb +0 -14
- data/lib/cli/config.rb +0 -173
- data/lib/cli/console_helper.rb +0 -170
- data/lib/cli/core_ext.rb +0 -122
- data/lib/cli/errors.rb +0 -19
- data/lib/cli/frameworks.rb +0 -265
- data/lib/cli/manifest_helper.rb +0 -300
- data/lib/cli/runner.rb +0 -505
- data/lib/cli/services_helper.rb +0 -84
- data/lib/cli/tunnel_helper.rb +0 -332
- data/lib/cli/usage.rb +0 -86
- data/lib/cli/version.rb +0 -7
- data/lib/cli/zip_util.rb +0 -77
- data/lib/jdc/client.rb +0 -457
- data/lib/jdc/const.rb +0 -25
- data/lib/jdc/micro/switcher/base.rb +0 -97
- data/lib/jdc/micro/switcher/linux.rb +0 -16
- data/lib/jdc/signature/version.rb +0 -27
- data/lib/jdc/signer.rb +0 -13
- data/lib/jdc/timer.rb +0 -12
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
class TargetPrettifier
|
|
2
|
+
def self.prettify(client, outputter)
|
|
3
|
+
outputter.line("Target Information (where will apps be pushed):")
|
|
4
|
+
outputter.line(" JDC instance: #{print_var(client.try(:target), outputter)} (API version: #{print_var(client.try(:version), outputter)})")
|
|
5
|
+
outputter.line(" user: #{print_var(client.try(:current_user).try(:email), outputter)}")
|
|
6
|
+
#outputter.line(" user: #{print_var(client.try(:current_user), outputter)}")
|
|
7
|
+
outputter.line(" target app space: #{print_var(client.try(:current_space).try(:name), outputter)} (org: #{print_var(client.try(:current_organization).try(:name), outputter)})")
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.print_var(object_name, outputter)
|
|
11
|
+
if object_name
|
|
12
|
+
outputter.c(object_name, :good)
|
|
13
|
+
else
|
|
14
|
+
outputter.c('N/A', :bad)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require "jdc/cli"
|
|
2
|
+
|
|
3
|
+
module JDC
|
|
4
|
+
module User
|
|
5
|
+
class Base < CLI
|
|
6
|
+
def precondition
|
|
7
|
+
check_key
|
|
8
|
+
#check_logged_in
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
private
|
|
12
|
+
|
|
13
|
+
def validate_password!(password)
|
|
14
|
+
validate_password_verified!(password)
|
|
15
|
+
validate_password_strength!(password)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def validate_password_verified!(password)
|
|
19
|
+
fail "Passwords do not match." unless force? || password == input[:verify]
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def validate_password_strength!(password)
|
|
23
|
+
strength = client.base.password_score(password)
|
|
24
|
+
msg = "Your password strength is: #{strength}"
|
|
25
|
+
fail msg if strength == :weak
|
|
26
|
+
line msg
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
require "jdc/cli/user/base"
|
|
2
|
+
=begin
|
|
3
|
+
module JDC::User
|
|
4
|
+
class Create < Base
|
|
5
|
+
desc "Create a user"
|
|
6
|
+
group :admin, :user
|
|
7
|
+
input :email, :desc => "User email", :argument => :optional
|
|
8
|
+
input :password, :desc => "User password"
|
|
9
|
+
input :verify, :desc => "Repeat password"
|
|
10
|
+
input :organization, :desc => "User organization",
|
|
11
|
+
:aliases => %w{--org -o},
|
|
12
|
+
:default => proc { client.current_organization },
|
|
13
|
+
:from_given => by_name(:organization)
|
|
14
|
+
|
|
15
|
+
def create_user
|
|
16
|
+
org = JDC::Populators::Organization.new(input).populate_and_save!
|
|
17
|
+
email = input[:email]
|
|
18
|
+
password = input[:password]
|
|
19
|
+
|
|
20
|
+
if !force? && password != input[:verify]
|
|
21
|
+
fail "Passwords don't match."
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
user = nil
|
|
25
|
+
with_progress("Creating user") do
|
|
26
|
+
user = client.register(email, password)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
with_progress("Adding user to #{org.name}") do
|
|
30
|
+
user.audited_organizations = user.managed_organizations = user.organizations = [org]
|
|
31
|
+
user.update!
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
alias_command :add_user, :create_user
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
def ask_email
|
|
40
|
+
ask("Email")
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def ask_password
|
|
44
|
+
ask("Password", :echo => "*", :forget => true)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def ask_verify
|
|
48
|
+
ask("Verify Password", :echo => "*", :forget => true)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
=end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
require "jdc/cli/user/base"
|
|
2
|
+
=begin
|
|
3
|
+
module JDC::User
|
|
4
|
+
class Passwd < Base
|
|
5
|
+
desc "Update the current user's password"
|
|
6
|
+
group :admin, :user
|
|
7
|
+
input :password, :desc => "Current password"
|
|
8
|
+
input :new_password, :desc => "New password"
|
|
9
|
+
input :verify, :desc => "Repeat new password"
|
|
10
|
+
|
|
11
|
+
def passwd
|
|
12
|
+
password = input[:password]
|
|
13
|
+
new_password = input[:new_password]
|
|
14
|
+
|
|
15
|
+
validate_password! new_password
|
|
16
|
+
|
|
17
|
+
with_progress("Changing password") do
|
|
18
|
+
client.current_user.change_password!(new_password, password)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def ask_password
|
|
25
|
+
ask("Current Password", :echo => "*", :forget => true)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def ask_new_password
|
|
29
|
+
ask("New Password", :echo => "*", :forget => true)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def ask_verify
|
|
33
|
+
ask("Verify Password", :echo => "*", :forget => true)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
=end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require "jdc/cli/user/base"
|
|
2
|
+
=begin
|
|
3
|
+
module JDC::User
|
|
4
|
+
class Register < Base
|
|
5
|
+
def precondition; end
|
|
6
|
+
|
|
7
|
+
desc "Create a user and log in"
|
|
8
|
+
group :admin, :user
|
|
9
|
+
input :email, :desc => "Desired email", :argument => :optional
|
|
10
|
+
input :password, :desc => "Desired password"
|
|
11
|
+
input :verify, :desc => "Repeat password"
|
|
12
|
+
input :login, :desc => "Automatically log in?", :default => true
|
|
13
|
+
def register
|
|
14
|
+
email = input[:email]
|
|
15
|
+
password = input[:password]
|
|
16
|
+
|
|
17
|
+
validate_password!(password)
|
|
18
|
+
|
|
19
|
+
with_progress("Creating user") do
|
|
20
|
+
client.register(email, password)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
if input[:login]
|
|
24
|
+
invoke :login, :username => email, :password => password
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def ask_email
|
|
31
|
+
ask("Email")
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def ask_password
|
|
35
|
+
ask("Password", :echo => "*", :forget => true)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def ask_verify
|
|
39
|
+
ask("Confirm Password", :echo => "*", :forget => true)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
=end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
require "jdc/cli/user/base"
|
|
2
|
+
|
|
3
|
+
module JDC::User
|
|
4
|
+
class Users < Base
|
|
5
|
+
desc "List all users"
|
|
6
|
+
group :admin
|
|
7
|
+
def users
|
|
8
|
+
users =
|
|
9
|
+
with_progress("Getting users") do
|
|
10
|
+
client.users(:depth => 0)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
spaced(users) do |u|
|
|
14
|
+
display_user(u)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def display_user(u)
|
|
21
|
+
if quiet?
|
|
22
|
+
puts u.email
|
|
23
|
+
else
|
|
24
|
+
line "#{c(u.email, :name)}:"
|
|
25
|
+
|
|
26
|
+
indented do
|
|
27
|
+
line "admin?: #{c(u.admin?, u.admin? ? :yes : :no)}"
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module JDC
|
|
2
|
+
CONFIG_DIR = "~/.jdc".freeze
|
|
3
|
+
|
|
4
|
+
LOGS_DIR = "#{CONFIG_DIR}/logs".freeze
|
|
5
|
+
PLUGINS_FILE = "#{CONFIG_DIR}/plugins.yml".freeze
|
|
6
|
+
TARGET_FILE = "#{CONFIG_DIR}/target".freeze
|
|
7
|
+
TOKENS_FILE = "#{CONFIG_DIR}/tokens.yml".freeze
|
|
8
|
+
COLORS_FILE = "#{CONFIG_DIR}/colors.yml".freeze
|
|
9
|
+
CRASH_FILE = "#{CONFIG_DIR}/crash".freeze
|
|
10
|
+
DEFAULT_API_URL = "api.jd-app.com".freeze
|
|
11
|
+
end
|
data/lib/jdc/errors.rb
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module JDC
|
|
2
|
+
class UserFriendlyError < RuntimeError
|
|
3
|
+
def initialize(msg)
|
|
4
|
+
@message = msg
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def to_s
|
|
8
|
+
@message
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
class UserError < UserFriendlyError; end
|
|
13
|
+
|
|
14
|
+
class NotAuthorized < UserError
|
|
15
|
+
def initialize
|
|
16
|
+
@message = "Not authorized."
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
data/lib/jdc/plugin.rb
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
require "set"
|
|
2
|
+
require "yaml"
|
|
3
|
+
|
|
4
|
+
require "jdc/constants"
|
|
5
|
+
require "jdc/cli"
|
|
6
|
+
|
|
7
|
+
module JDC
|
|
8
|
+
module Plugin
|
|
9
|
+
@@plugins = []
|
|
10
|
+
|
|
11
|
+
def self.load_all
|
|
12
|
+
# auto-load gems with 'jdc-plugin' in their name
|
|
13
|
+
matching =
|
|
14
|
+
if Gem::Specification.respond_to? :find_all
|
|
15
|
+
Gem::Specification.find_all do |s|
|
|
16
|
+
s.name =~ /jdc-plugin/
|
|
17
|
+
end
|
|
18
|
+
else
|
|
19
|
+
Gem.source_index.find_name(/jdc-plugin/)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
enabled = Set.new(matching.collect(&:name))
|
|
23
|
+
|
|
24
|
+
jdc_gems = Gem.loaded_specs["jdc"]
|
|
25
|
+
((jdc_gems && jdc_gems.dependencies) || Gem.loaded_specs.values).each do |dep|
|
|
26
|
+
if dep.name =~ /jdc-plugin/
|
|
27
|
+
require "#{dep.name}/plugin"
|
|
28
|
+
enabled.delete dep.name
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# allow explicit enabling/disabling of gems via config
|
|
33
|
+
plugins = File.expand_path(JDC::PLUGINS_FILE)
|
|
34
|
+
if File.exists?(plugins) && yaml = YAML.load_file(plugins)
|
|
35
|
+
enabled += yaml["enabled"] if yaml["enabled"]
|
|
36
|
+
enabled -= yaml["disabled"] if yaml["disabled"]
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# load up each gem's 'plugin' file
|
|
40
|
+
#
|
|
41
|
+
# we require this file specifically so people can require the gem
|
|
42
|
+
# without it plugging into JDC
|
|
43
|
+
enabled.each do |gemname|
|
|
44
|
+
begin
|
|
45
|
+
require "#{gemname}/plugin"
|
|
46
|
+
rescue Gem::LoadError => e
|
|
47
|
+
puts "Failed to load #{gemname}:"
|
|
48
|
+
puts " #{e}"
|
|
49
|
+
puts
|
|
50
|
+
puts "You may need to update or remove this plugin."
|
|
51
|
+
puts
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
data/lib/jdc/spacing.rb
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
module JDC
|
|
2
|
+
module Spacing
|
|
3
|
+
@@indentation = 0
|
|
4
|
+
|
|
5
|
+
def indented
|
|
6
|
+
@@indentation += 1
|
|
7
|
+
yield
|
|
8
|
+
ensure
|
|
9
|
+
@@indentation -= 1
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def line(msg = "")
|
|
13
|
+
return puts "" if msg.empty?
|
|
14
|
+
|
|
15
|
+
start_line(msg)
|
|
16
|
+
puts ""
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def start_line(msg)
|
|
20
|
+
print " " * @@indentation unless quiet?
|
|
21
|
+
print msg
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def lines(blob)
|
|
25
|
+
blob.each_line do |line|
|
|
26
|
+
start_line(line)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
line
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def quiet?
|
|
33
|
+
false
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def spaced(vals)
|
|
37
|
+
num = 0
|
|
38
|
+
vals.each do |val|
|
|
39
|
+
line unless quiet? || num == 0
|
|
40
|
+
yield val
|
|
41
|
+
num += 1
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def tabular(*rows)
|
|
46
|
+
spacings = []
|
|
47
|
+
rows.each do |row|
|
|
48
|
+
next unless row
|
|
49
|
+
|
|
50
|
+
row.each.with_index do |col, i|
|
|
51
|
+
next unless col
|
|
52
|
+
|
|
53
|
+
width = text_width(col)
|
|
54
|
+
|
|
55
|
+
if !spacings[i] || width > spacings[i]
|
|
56
|
+
spacings[i] = width
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
columns = spacings.size
|
|
62
|
+
rows.each do |row|
|
|
63
|
+
next unless row
|
|
64
|
+
|
|
65
|
+
row.each.with_index do |col, i|
|
|
66
|
+
next unless col
|
|
67
|
+
|
|
68
|
+
start_line justify(col, spacings[i])
|
|
69
|
+
print " " unless i + 1 == columns
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
line
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def trim_escapes(str)
|
|
77
|
+
str.gsub(/\e\[\d+m/, "")
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def text_width(str)
|
|
81
|
+
trim_escapes(str).size
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def justify(str, width)
|
|
85
|
+
trimmed = trim_escapes(str)
|
|
86
|
+
str.ljust(width + (str.size - trimmed.size))
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require File.expand_path("../../../spec/spec_helper", __FILE__)
|