designshell 0.0.1

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.
Files changed (56) hide show
  1. data/.gitignore +18 -0
  2. data/.idea/.name +1 -0
  3. data/.idea/.rakeTasks +7 -0
  4. data/.idea/codeStyleSettings.xml +13 -0
  5. data/.idea/compiler.xml +25 -0
  6. data/.idea/copyright/profiles_settings.xml +5 -0
  7. data/.idea/encodings.xml +5 -0
  8. data/.idea/misc.xml +11 -0
  9. data/.idea/modules.xml +11 -0
  10. data/.idea/scopes/scope_settings.xml +5 -0
  11. data/.idea/vcs.xml +9 -0
  12. data/Gemfile +2 -0
  13. data/Gemfile.lock +196 -0
  14. data/LICENSE +22 -0
  15. data/README.md +35 -0
  16. data/README.rdoc +6 -0
  17. data/Rakefile +46 -0
  18. data/bin/designshelld.example.sh +5 -0
  19. data/bin/designshelld.example2.sh +3 -0
  20. data/bin/designshellserver +22 -0
  21. data/bin/ds +177 -0
  22. data/designshell.gemspec +40 -0
  23. data/designshell.iml +84 -0
  24. data/designshell.rdoc +5 -0
  25. data/features/designshell.feature +8 -0
  26. data/features/step_definitions/designshell_steps.rb +6 -0
  27. data/features/support/env.rb +15 -0
  28. data/lib/buzzcore_mods.rb +19 -0
  29. data/lib/designshell/context.rb +48 -0
  30. data/lib/designshell/core.rb +78 -0
  31. data/lib/designshell/deploy_plan.rb +40 -0
  32. data/lib/designshell/key_chain.rb +40 -0
  33. data/lib/designshell/repo.rb +112 -0
  34. data/lib/designshell/repo_server.rb +25 -0
  35. data/lib/designshell/site_client.rb +141 -0
  36. data/lib/designshell/utils.rb +18 -0
  37. data/lib/designshell/version.rb +3 -0
  38. data/lib/designshell.rb +19 -0
  39. data/lib/designshellserver/command.rb +180 -0
  40. data/lib/designshellserver/core.rb +41 -0
  41. data/lib/designshellserver.rb +17 -0
  42. data/spec/KeyChain_spec.rb +94 -0
  43. data/spec/RepoServer_spec.rb +54 -0
  44. data/spec/Repo_spec.rb +105 -0
  45. data/spec/build_spec.rb +29 -0
  46. data/spec/client_to_server_spec.rb +111 -0
  47. data/spec/designshell_context_spec.rb +18 -0
  48. data/spec/designshell_core_spec.rb +45 -0
  49. data/spec/rspec_helper.rb +8 -0
  50. data/spec/server/deploy_spec.rb +210 -0
  51. data/spec/server/dummy_spec.rb +52 -0
  52. data/spec/site_client_spec.rb +90 -0
  53. data/test/default_test.rb +14 -0
  54. data/test/test_helper.rb +9 -0
  55. data/testmart.iml +9 -0
  56. metadata +390 -0
@@ -0,0 +1,40 @@
1
+ # Ensure we require the local version and not one we might have installed already
2
+ require File.join([File.dirname(__FILE__),'lib','designshell','version.rb'])
3
+ spec = Gem::Specification.new do |s|
4
+ s.name = 'designshell'
5
+ s.version = DesignShell::VERSION
6
+ s.author = 'Gary McGhee'
7
+ s.email = 'contact@buzzware.com.au'
8
+ s.summary = 'DesignShell is the shell for designers'
9
+ s.description = 'All-round workflow tool for designers. Enables designers to comfortably use geek goodness like git, git deploy, SASS etc'
10
+ s.require_paths = ["lib"]
11
+ s.homepage = 'http://github.com/buzzware/designshell'
12
+ s.platform = Gem::Platform::RUBY
13
+ # Add your other files here if you make them
14
+ s.files = `git ls-files`.split($\)
15
+ s.bindir = 'bin'
16
+ s.executables = s.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
18
+ #s.has_rdoc = true
19
+ #s.extra_rdoc_files = ['README.rdoc','designshell.rdoc']
20
+ #s.rdoc_options << '--title' << 'designshell' << '--main' << 'README.rdoc' << '-ri'
21
+ s.add_development_dependency('rake')
22
+ s.add_development_dependency('rspec')
23
+ s.add_development_dependency('rspec-core')
24
+ s.add_development_dependency('rdoc')
25
+ s.add_development_dependency('aruba')
26
+ s.add_development_dependency('ruby-debug')
27
+ s.add_runtime_dependency('gli','2.5.0')
28
+ s.add_runtime_dependency('termios')
29
+ s.add_runtime_dependency('highline')
30
+ s.add_runtime_dependency('git')
31
+ s.add_runtime_dependency('middleman')
32
+ s.add_runtime_dependency('buzzcore')
33
+ s.add_runtime_dependency('POpen4')
34
+ s.add_runtime_dependency('bitbucket_rest_api')
35
+ s.add_runtime_dependency('osx_keychain')
36
+ s.add_runtime_dependency('json')
37
+ s.add_runtime_dependency('net_dav')
38
+ s.add_runtime_dependency('net-ssh')
39
+
40
+ end
data/designshell.iml ADDED
@@ -0,0 +1,84 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="RUBY_MODULE" version="4">
3
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
4
+ <exclude-output />
5
+ <content url="file://$MODULE_DIR$" />
6
+ <orderEntry type="jdk" jdkName="RVM: ruby-1.8.7-p358 [dash]" jdkType="RUBY_SDK" />
7
+ <orderEntry type="sourceFolder" forTests="false" />
8
+ <orderEntry type="library" scope="PROVIDED" name="POpen4 (v0.1.4, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
9
+ <orderEntry type="library" scope="PROVIDED" name="Platform (v0.4.0, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
10
+ <orderEntry type="library" scope="PROVIDED" name="RubyInline (v3.12.0, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
11
+ <orderEntry type="library" scope="PROVIDED" name="ZenTest (v4.8.3, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
12
+ <orderEntry type="library" scope="PROVIDED" name="activesupport (v3.2.11, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
13
+ <orderEntry type="library" scope="PROVIDED" name="aruba (v0.5.1, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
14
+ <orderEntry type="library" scope="PROVIDED" name="bitbucket_rest_api (v0.1.1, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
15
+ <orderEntry type="library" scope="PROVIDED" name="builder (v3.1.4, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
16
+ <orderEntry type="library" scope="PROVIDED" name="bundler (v1.1.3, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
17
+ <orderEntry type="library" scope="PROVIDED" name="buzzcore (v0.6.4, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
18
+ <orderEntry type="library" scope="PROVIDED" name="childprocess (v0.3.6, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
19
+ <orderEntry type="library" scope="PROVIDED" name="chunky_png (v1.2.7, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
20
+ <orderEntry type="library" scope="PROVIDED" name="coffee-script (v2.2.0, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
21
+ <orderEntry type="library" scope="PROVIDED" name="coffee-script-source (v1.3.3, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
22
+ <orderEntry type="library" scope="PROVIDED" name="columnize (v0.3.6, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
23
+ <orderEntry type="library" scope="PROVIDED" name="compass (v0.12.2, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
24
+ <orderEntry type="library" scope="PROVIDED" name="cucumber (v1.2.1, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
25
+ <orderEntry type="library" scope="PROVIDED" name="diff-lcs (v1.1.3, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
26
+ <orderEntry type="library" scope="PROVIDED" name="execjs (v1.4.0, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
27
+ <orderEntry type="library" scope="PROVIDED" name="faraday (v0.8.4, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
28
+ <orderEntry type="library" scope="PROVIDED" name="faraday_middleware (v0.8.8, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
29
+ <orderEntry type="library" scope="PROVIDED" name="ffi (v1.3.1, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
30
+ <orderEntry type="library" scope="PROVIDED" name="fssm (v0.2.9, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
31
+ <orderEntry type="library" scope="PROVIDED" name="gherkin (v2.11.5, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
32
+ <orderEntry type="library" scope="PROVIDED" name="git (v1.2.5, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
33
+ <orderEntry type="library" scope="PROVIDED" name="gli (v2.5.0, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
34
+ <orderEntry type="library" scope="PROVIDED" name="haml (v3.1.7, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
35
+ <orderEntry type="library" scope="PROVIDED" name="hashie (v1.2.0, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
36
+ <orderEntry type="library" scope="PROVIDED" name="highline (v1.6.15, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
37
+ <orderEntry type="library" scope="PROVIDED" name="hike (v1.2.1, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
38
+ <orderEntry type="library" scope="PROVIDED" name="http_router (v0.10.2, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
39
+ <orderEntry type="library" scope="PROVIDED" name="i18n (v0.6.1, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
40
+ <orderEntry type="library" scope="PROVIDED" name="json (v1.7.6, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
41
+ <orderEntry type="library" scope="PROVIDED" name="linecache (v0.46, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
42
+ <orderEntry type="library" scope="PROVIDED" name="listen (v0.5.3, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
43
+ <orderEntry type="library" scope="PROVIDED" name="maruku (v0.6.1, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
44
+ <orderEntry type="library" scope="PROVIDED" name="middleman (v3.0.9, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
45
+ <orderEntry type="library" scope="PROVIDED" name="middleman-core (v3.0.9, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
46
+ <orderEntry type="library" scope="PROVIDED" name="middleman-more (v3.0.9, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
47
+ <orderEntry type="library" scope="PROVIDED" name="middleman-sprockets (v3.0.6, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
48
+ <orderEntry type="library" scope="PROVIDED" name="multi_json (v1.5.0, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
49
+ <orderEntry type="library" scope="PROVIDED" name="multipart-post (v1.1.5, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
50
+ <orderEntry type="library" scope="PROVIDED" name="net-ssh (v2.6.3, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
51
+ <orderEntry type="library" scope="PROVIDED" name="net_dav (v0.5.0, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
52
+ <orderEntry type="library" scope="PROVIDED" name="nokogiri (v1.5.6, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
53
+ <orderEntry type="library" scope="PROVIDED" name="open4 (v1.3.0, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
54
+ <orderEntry type="library" scope="PROVIDED" name="osx_keychain (v1.0.0, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
55
+ <orderEntry type="library" scope="PROVIDED" name="padrino-core (v0.10.7, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
56
+ <orderEntry type="library" scope="PROVIDED" name="padrino-helpers (v0.10.7, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
57
+ <orderEntry type="library" scope="PROVIDED" name="rack (v1.4.1, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
58
+ <orderEntry type="library" scope="PROVIDED" name="rack-protection (v1.3.2, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
59
+ <orderEntry type="library" scope="PROVIDED" name="rack-test (v0.6.2, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
60
+ <orderEntry type="library" scope="PROVIDED" name="rake (v10.0.3, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
61
+ <orderEntry type="library" scope="PROVIDED" name="rb-fsevent (v0.9.3, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
62
+ <orderEntry type="library" scope="PROVIDED" name="rb-inotify (v0.8.8, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
63
+ <orderEntry type="library" scope="PROVIDED" name="rbx-require-relative (v0.0.9, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
64
+ <orderEntry type="library" scope="PROVIDED" name="rdoc (v3.12, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
65
+ <orderEntry type="library" scope="PROVIDED" name="rspec (v2.12.0, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
66
+ <orderEntry type="library" scope="PROVIDED" name="rspec-core (v2.12.2, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
67
+ <orderEntry type="library" scope="PROVIDED" name="rspec-expectations (v2.12.1, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
68
+ <orderEntry type="library" scope="PROVIDED" name="rspec-mocks (v2.12.1, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
69
+ <orderEntry type="library" scope="PROVIDED" name="ruby-debug (v0.10.4, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
70
+ <orderEntry type="library" scope="PROVIDED" name="ruby-debug-base (v0.10.4, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
71
+ <orderEntry type="library" scope="PROVIDED" name="sass (v3.2.5, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
72
+ <orderEntry type="library" scope="PROVIDED" name="simple_oauth (v0.2.0, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
73
+ <orderEntry type="library" scope="PROVIDED" name="sinatra (v1.3.3, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
74
+ <orderEntry type="library" scope="PROVIDED" name="sprockets (v2.4.5, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
75
+ <orderEntry type="library" scope="PROVIDED" name="sprockets-sass (v0.9.1, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
76
+ <orderEntry type="library" scope="PROVIDED" name="syntax (v1.0.0, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
77
+ <orderEntry type="library" scope="PROVIDED" name="termios (v0.9.4, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
78
+ <orderEntry type="library" scope="PROVIDED" name="thor (v0.15.4, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
79
+ <orderEntry type="library" scope="PROVIDED" name="tilt (v1.3.3, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
80
+ <orderEntry type="library" scope="PROVIDED" name="uglifier (v1.2.7, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
81
+ <orderEntry type="library" scope="PROVIDED" name="url_mount (v0.2.1, RVM: ruby-1.8.7-p358 [dash]) [gem]" level="application" />
82
+ </component>
83
+ </module>
84
+
data/designshell.rdoc ADDED
@@ -0,0 +1,5 @@
1
+ = designshell
2
+
3
+ Generate this with
4
+ ds rdoc
5
+ After you have described your command line interface
@@ -0,0 +1,8 @@
1
+ Feature: My bootstrapped app kinda works
2
+ In order to get going on coding my awesome app
3
+ I want to have aruba and cucumber setup
4
+ So I don't have to do it myself
5
+
6
+ Scenario: App just runs
7
+ When I get help for "ds"
8
+ Then the exit status should be 0
@@ -0,0 +1,6 @@
1
+ When /^I get help for "([^"]*)"$/ do |app_name|
2
+ @app_name = app_name
3
+ step %(I run `#{app_name} help`)
4
+ end
5
+
6
+ # Add more step definitions here
@@ -0,0 +1,15 @@
1
+ #require 'aruba/cucumber'
2
+ #
3
+ #ENV['PATH'] = "#{File.expand_path(File.dirname(__FILE__) + '/../../bin')}#{File::PATH_SEPARATOR}#{ENV['PATH']}"
4
+ #LIB_DIR = File.join(File.expand_path(File.dirname(__FILE__)),'..','..','lib')
5
+ #
6
+ #Before do
7
+ # # Using "announce" causes massive warnings on 1.9.2
8
+ # @puts = true
9
+ # @original_rubylib = ENV['RUBYLIB']
10
+ # ENV['RUBYLIB'] = LIB_DIR + File::PATH_SEPARATOR + ENV['RUBYLIB'].to_s
11
+ #end
12
+ #
13
+ #After do
14
+ # ENV['RUBYLIB'] = @original_rubylib
15
+ #end
@@ -0,0 +1,19 @@
1
+ MiscUtils.module_eval do
2
+ # Like bite, but returns the first match instead of the subject
3
+ #if !self.instance_methods.include? "extract!"
4
+ #end
5
+ def self.ensure_slashes(aString,aLeading,aTrailing)
6
+ if (aLeading)
7
+ aString = ensure_prefix(aString,'/')
8
+ else
9
+ aString = aString.bite('/')
10
+ end
11
+ if (aTrailing)
12
+ aString = ensure_suffix(aString,'/')
13
+ else
14
+ aString = aString.chomp('/') unless aString=='/' && aLeading
15
+ end
16
+ aString
17
+ end
18
+
19
+ end
@@ -0,0 +1,48 @@
1
+ module DesignShell
2
+
3
+ class Context
4
+ attr_reader :global_options,:options,:pwd,:argv,:env,:stdout,:stdin,:stderr,:credentials,:key_chain
5
+ attr_writer :pwd
6
+
7
+ def initialize(aValues=nil)
8
+ return if !aValues
9
+ @global_options = aValues[:global_options]
10
+ @options = aValues[:options]
11
+ @pwd = MiscUtils.real_path(Dir.pwd)
12
+ @argv = aValues[:argv]
13
+ @env = aValues[:env]
14
+ @stdout = aValues[:stdout]
15
+ @stdin = aValues[:stdin]
16
+ @stderr = aValues[:stderr]
17
+ @credentials = aValues[:credentials]
18
+ @key_chain = aValues[:key_chain]
19
+ end
20
+
21
+ # http://thinkingdigitally.com/archive/capturing-output-from-puts-in-ruby/
22
+ #class SimpleSemParserTest < Test::Unit::TestCase
23
+ # def test_set_stmt_write
24
+ # out = capture_stdout do
25
+ # parser = SimpleSemParser.new
26
+ # parser.parse('set write, "Hello World!"').execute
27
+ # end
28
+ # assert_equal "Hello World!\n", out.string
29
+ # end
30
+ #end
31
+ def capture_stdout
32
+ stdout_before = @stdout
33
+ out = StringIO.new
34
+ @stdout = out
35
+ yield
36
+ return out.string
37
+ ensure
38
+ @stdout = stdout_before
39
+ end
40
+
41
+ def find_git_root
42
+ git_folder = MiscUtils.find_upwards(@pwd,'.git')
43
+ return git_folder && git_folder.chomp('/.git')
44
+ end
45
+
46
+ end
47
+
48
+ end
@@ -0,0 +1,78 @@
1
+ module DesignShell
2
+ class Core
3
+
4
+ attr_reader :repo,:configured,:context
5
+
6
+ def initialize(aDependencies=nil)
7
+ @@instance = self unless (defined? @@instance) && @@instance
8
+ if aDependencies
9
+ @context = aDependencies[:context]
10
+ @repo = aDependencies[:repo]
11
+ @keyChain = aDependencies[:keyChain] || @context.key_chain
12
+ end
13
+ configure(@context) if @context
14
+ end
15
+
16
+ def self.instance
17
+ (defined? @@instance) && @@instance
18
+ end
19
+
20
+ def configure(aContext)
21
+ @configured = true
22
+ end
23
+
24
+ def ensure_repo_open
25
+ if (!@repo && @context)
26
+ if git_root = @context.find_git_root
27
+ @repo = DesignShell::Repo.new
28
+ @repo.open git_root
29
+ end
30
+ end
31
+ raise "unable to open repository" unless @repo.open?
32
+ @repo
33
+ end
34
+
35
+ def ensure_deploy_server
36
+ @conn ||= Net::SSH.start(@context.credentials[:deploy_host],nil)
37
+ end
38
+
39
+ def deploy_plan(*args)
40
+ return @deploy_plan if args.empty?
41
+ plan = args.first
42
+ if plan.is_a?(DesignShell::DeployPlan)
43
+ @deploy_plan = plan
44
+ elsif plan
45
+ @deploy_plan = DesignShell::DeployPlan.new(:core => self,:plan => plan)
46
+ end
47
+ @deploy_plan
48
+ end
49
+
50
+ def build
51
+ response = POpen4::shell('ls')
52
+ # puts result[:stdout]
53
+ end
54
+
55
+ def deploy
56
+ ensure_repo_open
57
+ deploy_branch = 'master'
58
+ deploy_plan(repo.get_file_content('.deploy_plan.xml',deploy_branch))
59
+ params = deploy_plan.deploy_items_values.clone
60
+ params['site'] = deploy_plan.site
61
+ params['repo_url'] = repo.origin.url
62
+ call_server_command('DEPLOY',params)
63
+ end
64
+
65
+ def call_server_command(aCommand, aParams=nil)
66
+ #ds_conn = ensure_deploy_server
67
+ command = aCommand
68
+ command += " " + JSON.generate(aParams) if aParams
69
+ #result = ds_conn.exec!(command)
70
+ result = nil
71
+ Net::SSH.start(@context.credentials[:deploy_host],nil) do |ssh|
72
+ result = ssh.exec!(command)
73
+ end
74
+ result
75
+ end
76
+
77
+ end
78
+ end
@@ -0,0 +1,40 @@
1
+ module DesignShell
2
+ class DeployPlan
3
+ def initialize(aConfig=nil)
4
+ return if !aConfig
5
+ @core = aConfig[:core]
6
+ read(aConfig[:plan]) if aConfig[:plan]
7
+ end
8
+
9
+ def read(aDeployPlan)
10
+ @deployPlanNode = XmlUtils.get_xml_root(aDeployPlan)
11
+ end
12
+
13
+ def site
14
+ XmlUtils.peek_node_value(@deployPlanNode,'/deployPlan/@site')
15
+ end
16
+
17
+ def deploy_node() # later accept criteria
18
+ XmlUtils.single_node(@deployPlanNode,'/deployPlan/plan/deploy')
19
+ end
20
+
21
+ def key_chain
22
+ @core && @core.context && @core.context.key_chain
23
+ end
24
+
25
+ def deploy_items_values(aDeployNode=nil)
26
+ aDeployNode ||= deploy_node()
27
+ result = {}
28
+ aDeployNode.get_elements('item').each do |n|
29
+ next unless name = XmlUtils.attr(n,'name')
30
+ if text = n.text.to_nil # value in node
31
+ result[name] = text
32
+ elsif key_chain # value in keyChain
33
+ key = XmlUtils.attr(n,'key') || name
34
+ result[name] = key_chain[key]
35
+ end
36
+ end
37
+ result
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,40 @@
1
+ module DesignShell
2
+ class KeyChain
3
+
4
+ def initialize(aNamespace)
5
+ @keychain = OSXKeychain.new
6
+ @namespace = aNamespace
7
+ end
8
+
9
+ def [](aKey)
10
+ get(aKey)
11
+ end
12
+
13
+ def []=(aKey,aValue)
14
+ set(aKey,aValue)
15
+ end
16
+
17
+ def set(aKey,aValue=nil,aPrefix='')
18
+ if (aKey.is_a?(String) || aKey.is_a?(Symbol))
19
+ @keychain[@namespace,aPrefix.to_s+aKey.to_s] = aValue
20
+ elsif aKey.is_a?(Hash)
21
+ prefix = aValue || aPrefix
22
+ aKey.each {|k,v| set(k,v,prefix)}
23
+ end
24
+ end
25
+
26
+ def get(aKey,aPrefix=nil,aKeepPrefix=false)
27
+ if (aKey.is_a?(Array))
28
+ result = {}
29
+ aKey.each do |k|
30
+ storeKey = (aKeepPrefix ? aPrefix.to_s+k.to_s : k.to_s)
31
+ v = get(k.to_s,aPrefix)
32
+ result[storeKey] = v
33
+ end
34
+ return result
35
+ else
36
+ return @keychain[@namespace,aPrefix.to_s+aKey.to_s]
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,112 @@
1
+ Git::Lib.class_eval do
2
+ public :command, :command_lines
3
+ end
4
+
5
+ module DesignShell
6
+ class Repo
7
+
8
+ attr_reader :git,:configured
9
+
10
+ GIT_METHODS = [:commit,:add,:reset_hard,:path,:clone,:log,:size,:branches,:status,:remotes,:pull,:fetch,:push,:merge]
11
+
12
+ def initialize(aDesignShell=nil)
13
+ @ds = aDesignShell
14
+ end
15
+
16
+ def method_missing(sym, *args, &block)
17
+ if @git && GIT_METHODS.include?(sym)
18
+ @git.send sym, *args, &block
19
+ else
20
+ super
21
+ end
22
+ end
23
+
24
+ #def configure(aContext=nil)
25
+ # # set @path
26
+ # @configured = true
27
+ #end
28
+
29
+ def open(aPath)
30
+ @git = Git.open(aPath, :log => Logger.new(STDOUT))
31
+ end
32
+
33
+ def init(*args)
34
+ @git = Git.init(*args)
35
+ end
36
+
37
+ def clone(aUrl,aPath)
38
+ @git = Git::clone(aUrl,aPath)
39
+ end
40
+
41
+ def open?
42
+ !!@git
43
+ end
44
+
45
+ def empty?
46
+ !@git.branches[0]
47
+ end
48
+
49
+ def commit_all(*args)
50
+ result = begin
51
+ @git.commit_all(*args)
52
+ rescue Git::GitExecuteError => e
53
+ if e.message.index("nothing to commit (working directory clean)")
54
+ nil
55
+ else
56
+ raise e
57
+ end
58
+ end
59
+ result = commitFromString(result)
60
+ result
61
+ end
62
+
63
+ # "[master (root-commit) 6bdd9e1] first commit 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 file1.txt"
64
+ def commitFromString(aString)
65
+ return nil if !aString || aString.empty?
66
+ sha = aString.scan(/ ([a-f0-9]+)\]/).flatten.first
67
+ @git.gcommit(sha)
68
+ end
69
+
70
+ def path
71
+ @git.dir.path
72
+ end
73
+
74
+ def origin
75
+ @git.remotes.find {|r| r.name=='origin'}
76
+ end
77
+
78
+ def url
79
+ (o = origin) && o.url
80
+ end
81
+
82
+ def checkout(commit=nil,branch=nil)
83
+ specific_commit = !!commit && !commit.index('HEAD')
84
+ if specific_commit
85
+ @git.checkout commit
86
+ else
87
+ branch ||= 'master'
88
+ @git.checkout(branch)
89
+ end
90
+ end
91
+
92
+ def branch
93
+ @git.current_branch
94
+ end
95
+
96
+ def head
97
+ @git.log.first
98
+ end
99
+
100
+ # git --no-pager diff --name-status 26bb87c3981 191d64820f2b
101
+ # result is array of paths prefixed with status letter then a tab
102
+ # see http://git-scm.com/docs/git-diff under --diff-filter=
103
+ # Added (A), Copied (C), Deleted (D), Modified (M), Renamed (R), have their type (i.e. regular file, symlink, submodule, ...) changed (T)
104
+ def changesBetweenCommits(aFromCommit, aToCommit)
105
+ @git.lib.command_lines('diff',['--name-status',aFromCommit,aToCommit])
106
+ end
107
+
108
+ def get_file_content(aPath,aCommitOrBranch=nil)
109
+ @git.lib.command('show',[[aCommitOrBranch||'master',aPath].join(':')]) rescue nil
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,25 @@
1
+ require 'bitbucket_rest_api'
2
+
3
+ module DesignShell
4
+ class RepoServer
5
+
6
+ DELEGATE_METHODS = [:user,:oauth_token,:oauth_secret,:basic_auth,:login,:password,:adapter,:adapter=,:setup]
7
+
8
+ def initialize
9
+ @bitbucket = BitBucket::Client.new({})
10
+ end
11
+
12
+ def method_missing(sym, *args, &block)
13
+ if @bitbucket && DELEGATE_METHODS.include?(sym)
14
+ @bitbucket.send sym, *args, &block
15
+ else
16
+ super
17
+ end
18
+ end
19
+
20
+ def repos
21
+ @bitbucket.repos.all
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,141 @@
1
+ module DesignShell
2
+
3
+ # might have to work on net_dav to support curl with put ie implement request_sending_body
4
+ # http://curb.rubyforge.org/classes/Curl/Easy.html
5
+ #
6
+
7
+ class SiteClient
8
+
9
+ attr_accessor :deploy_status_file
10
+
11
+ def initialize(aConfig)
12
+ #@context = aContext
13
+ @server_path = MiscUtils.remove_slash(aConfig[:site_url])
14
+ site_username = aConfig[:site_username]
15
+ site_password = aConfig[:site_password]
16
+
17
+ @dav = Net::DAV.new(MiscUtils.append_slash(@server_path), :curl => false)
18
+ @dav.verify_server = false
19
+ @dav.credentials(site_username,site_password)
20
+ @deploy_status_file = '/content/.deploy-status.txt'
21
+ end
22
+
23
+ DAV_METHODS = [:find]
24
+
25
+ def method_missing(sym, *args, &block)
26
+ if @dav && DAV_METHODS.include?(sym)
27
+ @dav.send sym, *args, &block
28
+ else
29
+ super
30
+ end
31
+ end
32
+
33
+ def full_path(aRelativePath)
34
+ File.join(@server_path, URI.escape(aRelativePath))
35
+ end
36
+
37
+ def ls(aPath=nil,aRecursive=false)
38
+ result = []
39
+ path = MiscUtils.append_slash(full_path(aPath||''))
40
+ @dav.find(path,:recursive=>aRecursive,:suppress_errors=>false) do | item |
41
+ result << item.url.to_s.bite(path)
42
+ end
43
+ result
44
+ end
45
+
46
+ def list_files(aPath=nil,aRecursive=false)
47
+ result = ls(aPath,aRecursive)
48
+ result.delete_if {|f| f.ends_with? '/'}
49
+ result
50
+ end
51
+
52
+ def get_string(aPath)
53
+ begin
54
+ @dav.get(full_path(aPath))
55
+ rescue Net::HTTPServerException => e
56
+ e.response.is_a?(Net::HTTPNotFound) ? nil : raise
57
+ rescue Net::HTTPError => e
58
+ e.message.index('404') ? nil : raise
59
+ end
60
+ end
61
+
62
+ def put_string(aPath,aString)
63
+ @dav.put_string(full_path(aPath),aString)
64
+ end
65
+
66
+ def ensure_folder_path(aPath)
67
+ path_parts = aPath.bite('/').chomp('/').split('/')
68
+ last_part = path_parts.length-1
69
+ existing_part = nil
70
+ last_part.downto(0) do |i|
71
+ existing_part = i if !existing_part && exists?(path = '/'+path_parts[0..i].join('/'))
72
+ end
73
+ (existing_part ? existing_part+1 : 0).upto(last_part) do |i|
74
+ mkdir('/'+path_parts[0..i].join('/'))
75
+ end
76
+ end
77
+
78
+ def delete(aPath)
79
+ begin
80
+ @dav.delete(full_path(aPath))
81
+ rescue Net::HTTPServerException => e
82
+ e.response.is_a?(Net::HTTPNotFound) ? nil : raise
83
+ end
84
+ end
85
+
86
+ def deploy_status
87
+ s = get_string(deploy_status_file)
88
+ s ? JSON.parse(s) : nil
89
+ end
90
+
91
+ def deploy_status=(aObject)
92
+ if aObject
93
+ s = JSON.generate(aObject)
94
+ put_string(deploy_status_file,s)
95
+ else
96
+ delete deploy_status_file
97
+ end
98
+ aObject
99
+ end
100
+
101
+ def put_file(aLocalFile, aRemotePath, aEnsureFolder=true)
102
+ s = MiscUtils.string_from_file(aLocalFile)
103
+ ensure_folder_path(File.dirname(aRemotePath)) if aEnsureFolder
104
+ put_string(aRemotePath,s)
105
+ end
106
+
107
+ def get_file(aRemotePath, aLocalFile)
108
+ s = get_string(aRemotePath)
109
+ MiscUtils.string_to_file(s,aLocalFile)
110
+ end
111
+
112
+ def upload_files(aLocalDir,aFiles,aFromPath=nil,aToPath=nil)
113
+ aFiles.each do |f|
114
+ to = f
115
+ to = MiscUtils.path_rebase(to,aFromPath,aToPath) if aFromPath && aToPath
116
+ put_file(File.join(aLocalDir,f),to)
117
+ end
118
+ end
119
+
120
+ def delete_files(aPaths,aFromPath=nil,aToPath=nil)
121
+ if (aFromPath && aToPath)
122
+ aPaths.each do |p|
123
+ delete(MiscUtils.path_rebase(p,aFromPath,aToPath))
124
+ end
125
+ else
126
+ aPaths.each do |p|
127
+ delete(p)
128
+ end
129
+ end
130
+ end
131
+
132
+ def exists?(aPath)
133
+ @dav.exists? full_path(aPath)
134
+ end
135
+
136
+ def mkdir(aPath)
137
+ @dav.mkdir full_path(aPath)
138
+ end
139
+
140
+ end
141
+ end