pushwagner 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.
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ .idea
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use 1.9.3@pw --create
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source :rubygems
2
+
3
+ gemspec
4
+
5
+ group :development do
6
+ gem 'pry'
7
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,42 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ pushwagner (0.0.1)
5
+ net-scp
6
+ net-ssh
7
+ nokogiri (~> 1.5)
8
+
9
+ GEM
10
+ remote: http://rubygems.org/
11
+ specs:
12
+ coderay (1.0.8)
13
+ diff-lcs (1.1.3)
14
+ method_source (0.8.1)
15
+ net-scp (1.0.4)
16
+ net-ssh (>= 1.99.1)
17
+ net-ssh (2.6.1)
18
+ nokogiri (1.5.5)
19
+ pry (0.9.10)
20
+ coderay (~> 1.0.5)
21
+ method_source (~> 0.8)
22
+ slop (~> 3.3.1)
23
+ rake (0.9.5)
24
+ rspec (2.12.0)
25
+ rspec-core (~> 2.12.0)
26
+ rspec-expectations (~> 2.12.0)
27
+ rspec-mocks (~> 2.12.0)
28
+ rspec-core (2.12.0)
29
+ rspec-expectations (2.12.0)
30
+ diff-lcs (~> 1.1.3)
31
+ rspec-mocks (2.12.0)
32
+ slop (3.3.3)
33
+
34
+ PLATFORMS
35
+ ruby
36
+
37
+ DEPENDENCIES
38
+ bundler (~> 1.0)
39
+ pry
40
+ pushwagner!
41
+ rake (~> 0.9)
42
+ rspec (~> 2.11)
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'rake/testtask'
2
+
3
+ task :spec do
4
+ exec "rspec --color --format=documentation spec"
5
+ end
6
+
7
+ desc "Run tests"
8
+ task :default => :spec
data/bin/pw ADDED
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'pushwagner'
4
+
5
+ def get_version
6
+ puts "You must specify which version you wish to deploy: "
7
+ STDIN.gets.strip
8
+ end
9
+
10
+ # TODO: detect version requirement from config
11
+ version = 1 # ENV["VERSION"] || get_version
12
+
13
+ main = Pushwagner::Main.new(:config_file => 'config/deploy.yml', :version => version, :environment => 'staging')
14
+
15
+ # TODO: detect cli from config
16
+ case ARGV[0]
17
+ when "deploy"
18
+ main.deploy
19
+ main.restart
20
+
21
+ when "restart"
22
+ main.restart
23
+
24
+ else
25
+ puts "Usage: pw <deploy|restart>"
26
+ end
@@ -0,0 +1,56 @@
1
+ require 'pushwagner/ext'
2
+ require 'pushwagner/maven'
3
+
4
+ module Pushwagner
5
+
6
+ class Environment
7
+ attr_reader :config
8
+ attr_accessor :current, :version
9
+
10
+ def initialize(opts = {})
11
+ opts = HashWithIndifferentAccess.new(opts)
12
+
13
+ config_file = opts[:config_file] || File.join(File.dirname(__FILE__), '/config/deploy.yml')
14
+ @version = opts[:version]
15
+ @current = opts[:environment] || 'development'
16
+
17
+ @config = HashWithIndifferentAccess.new(YAML::load_file(config_file) || {})
18
+ end
19
+
20
+ def path_prefix
21
+ config['path_prefix'] || '/srv/www'
22
+ end
23
+
24
+ def maven
25
+ @maven = config['maven'] ? Maven.new(config['maven'], version) : {}
26
+ end
27
+
28
+ def maven?
29
+ maven.any?
30
+ end
31
+
32
+ def static
33
+ config['static'] || {}
34
+ end
35
+
36
+ def static?
37
+ static.any?
38
+ end
39
+
40
+ def environments
41
+ config['environments'] || {}
42
+ end
43
+
44
+ def environment
45
+ environments[current] || {}
46
+ end
47
+
48
+ def hosts
49
+ environment['hosts'] || []
50
+ end
51
+
52
+ def user
53
+ environment['user'] || "nobody"
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,59 @@
1
+ module Pushwagner
2
+ class HashWithIndifferentAccess < ::Hash
3
+ def initialize(hash={})
4
+ super()
5
+ hash.each do |key, value|
6
+ self[convert_key(key)] = value
7
+ end
8
+ end
9
+
10
+ def [](key)
11
+ super(convert_key(key))
12
+ end
13
+
14
+ def []=(key, value)
15
+ super(convert_key(key), value)
16
+ end
17
+
18
+ def delete(key)
19
+ super(convert_key(key))
20
+ end
21
+
22
+ def values_at(*indices)
23
+ indices.collect { |key| self[convert_key(key)] }
24
+ end
25
+
26
+ def merge(other)
27
+ dup.merge!(other)
28
+ end
29
+
30
+ def merge!(other)
31
+ other.each do |key, value|
32
+ self[convert_key(key)] = value
33
+ end
34
+ self
35
+ end
36
+
37
+ def to_hash
38
+ Hash.new(default).merge!(self)
39
+ end
40
+
41
+ protected
42
+ def convert_key(key)
43
+ key.is_a?(Symbol) ? key.to_s : key
44
+ end
45
+
46
+ def method_missing(method, *args, &block)
47
+ method = method.to_s
48
+ if method =~ /^(\w+)\?$/
49
+ if args.empty?
50
+ !!self[$1]
51
+ else
52
+ self[$1] == args.first
53
+ end
54
+ else
55
+ self[method]
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,25 @@
1
+ module Pushwagner
2
+
3
+ class Main
4
+ def initialize(opts = {})
5
+ @environment = Pushwagner::Environment.new(opts)
6
+ end
7
+
8
+ def set_environment(env)
9
+ @environment.current = env.to_s
10
+ end
11
+
12
+ def set_version(version)
13
+ @environment.version = version
14
+ end
15
+
16
+ def deploy(opts = {})
17
+ Maven::Deployer.new(@environment, opts).deploy
18
+ Static::Deployer.new(@environment, opts).deploy
19
+ end
20
+
21
+ def restart(opts = {})
22
+ Supervisord::Restarter.new(@environment, opts).restart
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,142 @@
1
+ require 'net/https'
2
+ require 'net/ssh'
3
+ require 'net/scp'
4
+ require 'open-uri'
5
+ require 'nokogiri'
6
+
7
+ module Pushwagner
8
+ class Maven
9
+
10
+ attr_reader :repository, :artifacts
11
+ def initialize(maven, version)
12
+ return if !maven or maven.empty?
13
+
14
+ @version = version || required("Deployment version for artifacts is required")
15
+ @repository = Repository.new(maven['repositories'])
16
+ @artifacts = Hash[(maven['artifacts'] || {}).map { |k,h| [k, Artifact.new(h['artifact_id'], h['group_id'], h['version'] || version)] }]
17
+ end
18
+
19
+ def required(msg)
20
+ raise StandardError.new(msg)
21
+ end
22
+ end
23
+
24
+ class Maven::Artifact
25
+ attr_reader :artifact_id, :group_id, :version
26
+
27
+ def initialize(artifact_id, group_id, version)
28
+ @artifact_id = artifact_id
29
+ @group_id = group_id
30
+ @version = version
31
+ end
32
+
33
+ def base_path
34
+ "#{group_id.gsub('.', '/')}/#{artifact_id.gsub('.', '/')}/#{version}"
35
+ end
36
+
37
+ def jar_name
38
+ "#{artifact_id}-#{version}.jar"
39
+ end
40
+
41
+ def jar_path
42
+ "#{base_path}/#{jar_name}"
43
+ end
44
+
45
+ def snapshot?
46
+ version.downcase =~ /snapshot/
47
+ end
48
+
49
+ end
50
+
51
+ class Maven::Repository
52
+ attr_reader :snapshots_url
53
+ attr_reader :releases_url
54
+
55
+ def initialize(repositories)
56
+ required(repositories, "repositories configuration required")
57
+ required(repositories['snapshots'], "snapshots repository required")
58
+ required(repositories['releases'], "releases repository required")
59
+
60
+ @snapshots_url = repositories['snapshots']
61
+ @releases_url = repositories['releases']
62
+ end
63
+
64
+ def absolute_url(artifact)
65
+ if artifact.snapshot?
66
+ doc = Nokogiri::XML(open(URI.parse("#{snapshots_url}/#{artifact.base_path}/maven-metadata.xml"), :http_basic_authentication => authentication(false)))
67
+ snapshot_version = doc.xpath("//metadata/versioning/snapshotVersions/snapshotVersion/value/text()").first.content
68
+ return "#{snapshots_url}/#{artifact.base_path}/#{artifact.artifact_id}-#{snapshot_version}.jar"
69
+ end
70
+
71
+ "#{releases_url}/#{artifact.jar_path}"
72
+ end
73
+
74
+ def authentication(snapshots = false)
75
+ @settings_file ||= ENV['M2_HOME'] ? "#{ENV['M2_HOME']}/conf/settings.xml" : "#{ENV['HOME']}/.m2/settings.xml"
76
+
77
+ if File.exists?(@settings_file)
78
+ Nokogiri::XML(open(@settings_file)).css("settings servers server").each do |n|
79
+ return "#{n.css("username").text}:#{n.css("password").text}" if n.css("id").text == (snapshots ? 'snapshots' : 'releases')
80
+ end
81
+ end
82
+ ""
83
+ end
84
+
85
+ def required(exp, message)
86
+ raise StandardError.new(message) unless exp
87
+ end
88
+
89
+ end
90
+
91
+ #
92
+ # Deployer strategy for maven repos (wip).
93
+ #
94
+ class Maven::Deployer
95
+
96
+ attr_reader :environment, :artifacts, :repository
97
+
98
+ def initialize(env, opts = {})
99
+ @environment = env
100
+ # TODO: nil-object instead?
101
+ @artifacts = env.maven? ? env.maven.artifacts : {}
102
+ @repository = env.maven? ? env.maven.repository : nil
103
+ end
104
+
105
+ def deploy
106
+ artifacts.each do |name, artifact|
107
+ environment.hosts.each do |host|
108
+ mark_previous(name, host)
109
+ pull_artifact(name, artifact, host)
110
+ mark_new(name, artifact, host)
111
+ end
112
+ end
113
+ true # false if failed
114
+ end
115
+
116
+ protected
117
+
118
+ def pull_artifact(name, artifact, host)
119
+ Net::SSH.start(host, environment.user) do |ssh|
120
+ puts "Pulling #{repository.absolute_url(artifact)} to #{host}:#{environment.path_prefix}/#{artifact.jar_name}..."
121
+ ssh.exec("curl --user '#{repository.authentication(artifact.snapshot?)}' #{repository.absolute_url(artifact)} > #{environment.path_prefix}/#{artifact.jar_name}")
122
+ end
123
+ end
124
+
125
+ def mark_previous(name, host)
126
+ Net::SSH.start(host, user) do |ssh|
127
+ puts "Marking previous release on #{host}..."
128
+ ssh.exec("cp -P #{environment.path_prefix}/#{name}.jar #{environment.path_prefix}/#{name}.previous.jar")
129
+ end
130
+ end
131
+
132
+ def mark_new(name, artifact, host)
133
+ Net::SSH.start(host, user) do |ssh|
134
+ cwd = deploy_path(app_name)
135
+ puts "Marking #{artifact.jar_name} as current on #{host}..."
136
+ ssh.exec("ln -sf #{environment.path_prefix}/#{artifact.jar_name} #{environment.path_prefix}/#{name}.jar")
137
+ end
138
+ end
139
+
140
+ end
141
+ ##
142
+ end
@@ -0,0 +1,33 @@
1
+ require 'net/ssh'
2
+ require 'net/scp'
3
+
4
+ module Pushwagner
5
+ module Static
6
+ class Deployer
7
+ attr_reader :environment
8
+
9
+ def initialize(environment, opts = {})
10
+ @environment = environment
11
+ end
12
+
13
+ def deploy
14
+ environment.static.each do |name, files|
15
+ environment.hosts.each do |host|
16
+ Net::SCP.start(host, environment.user) do |scp|
17
+ puts "Uploading files to #{host}:#{environment.path_prefix}/#{name}/"
18
+ files.each do |f|
19
+ if File.exists?(f)
20
+ scp.upload!(f, "#{environment.path_prefix}/#{name}/", :recursive => File.directory?(f))
21
+ else
22
+ puts "Warning: File #{f} does not exist"
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ # EOC
30
+ end
31
+ # EOM
32
+ end
33
+ end
@@ -0,0 +1,14 @@
1
+ require 'net/ssh'
2
+
3
+ module Pushwagner
4
+ module Supervisord
5
+ class Restarter
6
+ def initialize(environment, opts = {})
7
+ end
8
+
9
+ def restart
10
+ puts "..."
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,3 @@
1
+ module Pushwagner
2
+ VERSION = "0.0.1"
3
+ end
data/lib/pushwagner.rb ADDED
@@ -0,0 +1,6 @@
1
+ require 'pushwagner/ext'
2
+ require 'pushwagner/environment'
3
+ require 'pushwagner/maven'
4
+ require 'pushwagner/static'
5
+ require 'pushwagner/supervisord'
6
+ require 'pushwagner/main'
@@ -0,0 +1,32 @@
1
+ $LOAD_PATH.push File.expand_path('../lib', __FILE__)
2
+ require 'pushwagner/version'
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = 'pushwagner'
6
+ s.version = Pushwagner::VERSION
7
+ s.date = Time.now.strftime("%Y-%m-%d")
8
+
9
+ s.description = "Simple remote automation wrapper."
10
+ s.summary = "Simple remote automation wrapper (wip)."
11
+
12
+ s.authors = ["Ole Christian Rynning"]
13
+ s.email = 'oc@rynning.no'
14
+
15
+ s.files = `git ls-files`.split("\n")
16
+ s.test_files = `git ls-files spec`.split("\n")
17
+ s.licenses = ['MIT']
18
+ s.homepage = 'http://rubygems.org/gems/pushwagner'
19
+ s.executables = ['pw']
20
+ s.require_paths = ['lib']
21
+
22
+ s.required_rubygems_version = Gem::Requirement.new('>= 1.3.6')
23
+
24
+ s.add_runtime_dependency 'net-ssh'
25
+ s.add_runtime_dependency 'net-scp'
26
+ s.add_runtime_dependency 'nokogiri', '~> 1.5'
27
+
28
+ s.add_development_dependency 'bundler', '~> 1.0'
29
+ s.add_development_dependency 'rake', '~> 0.9'
30
+ s.add_development_dependency 'rspec', '~> 2.11'
31
+
32
+ end
@@ -0,0 +1 @@
1
+ # empty.
@@ -0,0 +1,26 @@
1
+ path_prefix: /full/path
2
+
3
+ maven:
4
+ repositories:
5
+ releases: http://foo.mu/nexus/content/repositories/releases
6
+ snapshots: http://foo.mu/nexus/content/repositories/snapshots
7
+ artifacts:
8
+ bubble-api:
9
+ group_id: double
10
+ artifact_id: trouble-api
11
+ bubble-notifier:
12
+ group_id: double
13
+ artifact_id: trouble-notifier
14
+
15
+ static:
16
+ diakonhjemmet.uppercase.no:
17
+ - index.htm
18
+ - static
19
+
20
+ environments:
21
+ staging:
22
+ hosts: [staging.uppercase.no]
23
+ user: www-data
24
+ production:
25
+ hosts: [prod1.uppercase.no]
26
+ user: www-data
@@ -0,0 +1,24 @@
1
+ <metadata modelVersion="1.1.0">
2
+ <groupId>bar</groupId>
3
+ <artifactId>foo</artifactId>
4
+ <version>1.0-SNAPSHOT</version>
5
+ <versioning>
6
+ <snapshot>
7
+ <timestamp>20121114.152717</timestamp>
8
+ <buildNumber>3</buildNumber>
9
+ </snapshot>
10
+ <lastUpdated>20121114152717</lastUpdated>
11
+ <snapshotVersions>
12
+ <snapshotVersion>
13
+ <extension>jar</extension>
14
+ <value>1.0-20121114.152717-3</value>
15
+ <updated>20121114152717</updated>
16
+ </snapshotVersion>
17
+ <snapshotVersion>
18
+ <extension>pom</extension>
19
+ <value>1.0-20121114.152717-3</value>
20
+ <updated>20121114152717</updated>
21
+ </snapshotVersion>
22
+ </snapshotVersions>
23
+ </versioning>
24
+ </metadata>
@@ -0,0 +1,19 @@
1
+ path_prefix: /var/www
2
+
3
+ maven:
4
+ repositories:
5
+ releases: http://w00t.uppercase.no/nexus/content/repositories/releases
6
+ snapshots: http://w00t.uppercase.no/nexus/content/repositories/snapshots
7
+ artifacts:
8
+ some-api:
9
+ group_id: uppercase
10
+ artifact_id: uc-api
11
+ some-notifier:
12
+ group_id: uppercase
13
+ artifact_id: uc-notifier
14
+ version: 1.0final
15
+
16
+ environments:
17
+ simple:
18
+ hosts: [simple.uppercase.no]
19
+ user: www-data
@@ -0,0 +1,14 @@
1
+ <settings>
2
+ <servers>
3
+ <server>
4
+ <id>releases</id>
5
+ <username>foo</username>
6
+ <password>bar</password>
7
+ </server>
8
+ <server>
9
+ <id>snapshots</id>
10
+ <username>bar</username>
11
+ <password>baz</password>
12
+ </server>
13
+ </servers>
14
+ </settings>
@@ -0,0 +1,11 @@
1
+ path_prefix: /static/path
2
+
3
+ static:
4
+ diakonhjemmet.uppercase.no:
5
+ - index.htm
6
+ - static
7
+
8
+ environments:
9
+ www:
10
+ hosts: [www.uppercase.no, www2.uppercase.no]
11
+ user: www-data
@@ -0,0 +1,74 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+ require 'pushwagner/environment'
3
+
4
+ describe Pushwagner::Environment do
5
+ describe "#initialize" do
6
+ it "requires config_file" do
7
+ expect { Pushwagner::Environment.new('config_file' => File.join(config_root, 'nonexisting.yml'))}.to raise_error
8
+ end
9
+
10
+ it "supports config_file" do
11
+ env = Pushwagner::Environment.new(:config_file => File.join(config_root, 'full.yml'))
12
+ expect(env.path_prefix).to eq("/full/path")
13
+ end
14
+
15
+ it "supports :config_file" do
16
+ env = Pushwagner::Environment.new(:config_file => File.join(config_root, 'static.yml'))
17
+ expect(env.path_prefix).to eq("/static/path")
18
+ end
19
+
20
+ it "supports :version" do
21
+ env = Pushwagner::Environment.new(:config_file => File.join(config_root, 'full.yml'), :version => "1.3.3.7")
22
+ expect(env.version).to eq("1.3.3.7")
23
+ end
24
+ end
25
+ describe "#maven" do
26
+ it "requires a version" do
27
+ env = Pushwagner::Environment.new(:config_file => File.join(config_root, 'maven.yml'))
28
+ expect { env.maven }.to raise_error(StandardError, "Deployment version for artifacts is required")
29
+ end
30
+
31
+ it "returns empty hash when not configured" do
32
+ env = Pushwagner::Environment.new(:config_file => File.join(config_root, 'static.yml'), :version => "1foo" )
33
+ expect(env.maven?).to be_false
34
+ expect(env.maven).to eq({})
35
+ end
36
+ end
37
+ describe "#static" do
38
+ it "returns empty hash when not configured" do
39
+ env = Pushwagner::Environment.new(:config_file => File.join(config_root, 'maven.yml'), :version => "1foo" )
40
+ expect(env.static?).to be_false
41
+ expect(env.static).to eq({})
42
+ end
43
+ it "is a hash with files" do
44
+ env = Pushwagner::Environment.new(:config_file => File.join(config_root, 'static.yml'))
45
+ expect(env.static).to eq({'diakonhjemmet.uppercase.no' => ['index.htm', 'static']})
46
+ end
47
+ end
48
+ describe "#environments" do
49
+ it "returns all environments" do
50
+ env = Pushwagner::Environment.new(:config_file => File.join(config_root, 'full.yml'), :version => "1foo" )
51
+ expect(env.environments.size).to eq(2)
52
+ end
53
+ end
54
+ describe "#environment" do
55
+ it "returns empty environment if it doesn't exist" do
56
+ env = Pushwagner::Environment.new(:config_file => File.join(config_root, 'full.yml'), :version => "1foo" )
57
+ expect(env.environment).to eq({})
58
+ end
59
+ it "returns environment if it exists" do
60
+ env = Pushwagner::Environment.new(:config_file => File.join(config_root, 'full.yml'), :version => "1foo", :environment => "staging")
61
+ expect(env.environment).to eq({'hosts' => ["staging.uppercase.no"], 'user' => "www-data"})
62
+ end
63
+ end
64
+ describe "#hosts" do
65
+ it "returns empty list if it doesn't exist" do
66
+ env = Pushwagner::Environment.new(:config_file => File.join(config_root, 'empty.yml'), :version => "1foo" )
67
+ expect(env.hosts).to eq([])
68
+ end
69
+ it "returns environment if it exists" do
70
+ env = Pushwagner::Environment.new(:config_file => File.join(config_root, 'full.yml'), :version => "1foo", :environment => "staging")
71
+ expect(env.environment).to eq({'hosts' => ["staging.uppercase.no"], 'user' => "www-data"})
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,104 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+ require 'pushwagner/environment'
3
+
4
+ describe Pushwagner::Maven do
5
+ let(:cfg) {YAML::load_file(File.join(config_root, 'maven.yml'))['maven']}
6
+
7
+ describe "#initialize" do
8
+ it "requires a version" do
9
+ expect { Pushwagner::Maven.new(cfg, nil) }.to raise_error(StandardError, "Deployment version for artifacts is required")
10
+ end
11
+
12
+ it "trickles the version down to artifacts" do
13
+ m = Pushwagner::Maven.new(cfg, "1foo")
14
+ expect(m.artifacts["some-api"].version).to eq("1foo")
15
+ end
16
+
17
+ it "allows stable versions on artifacts" do
18
+ m = Pushwagner::Maven.new(cfg, "1bar")
19
+ expect(m.artifacts["some-notifier"].version).to eq("1.0final")
20
+ end
21
+
22
+ it "returns nil-object maven when not configured" do
23
+ m = Pushwagner::Maven.new({}, "1baz")
24
+ expect(m.artifacts).to be_nil
25
+ expect(m).to_not be_nil
26
+ end
27
+
28
+ describe "initialization of artifacts" do
29
+ it "handles no artifacts" do
30
+ cfg.delete('artifacts')
31
+ m = Pushwagner::Maven.new(cfg, "1bar")
32
+ expect(m.artifacts.size).to eq(0)
33
+ end
34
+ it "parses two artifacts" do
35
+ m = Pushwagner::Maven.new(cfg, "1bar")
36
+ expect(m.artifacts.size).to eq(2)
37
+ expect(m.artifacts.keys.first).to eq("some-api")
38
+ expect(m.artifacts.keys.last).to eq("some-notifier")
39
+ end
40
+ end
41
+
42
+ describe "initialization of repositories" do
43
+ it "requires snapshots repository" do
44
+ cfg.delete('repositories')
45
+ expect {Pushwagner::Maven.new(cfg, "1")}.to raise_error(StandardError)
46
+ end
47
+ it "requires snapshots repository" do
48
+ cfg['repositories'].delete('snapshots')
49
+ expect {Pushwagner::Maven.new(cfg, "1")}.to raise_error(StandardError)
50
+ end
51
+ it "requires releases repository" do
52
+ cfg['repositories'].delete('releases')
53
+ expect {Pushwagner::Maven.new(cfg, "1")}.to raise_error(StandardError)
54
+ end
55
+ it "parses repository" do
56
+ m = Pushwagner::Maven.new(cfg, "1")
57
+ expect(m.repository.snapshots_url).to eq("http://w00t.uppercase.no/nexus/content/repositories/snapshots")
58
+ expect(m.repository.releases_url).to eq("http://w00t.uppercase.no/nexus/content/repositories/releases")
59
+ end
60
+ end
61
+ end
62
+
63
+ describe "repositories" do
64
+ let(:settings) {IO.read(File.join(config_root, 'settings.xml'))}
65
+
66
+ it "reads releases authentication from maven settings.xml" do
67
+ m = Pushwagner::Maven.new(cfg, "1")
68
+ m.repository.should_receive(:open).
69
+ with(/.*settings.xml$/).
70
+ and_return(settings)
71
+
72
+ expect(m.repository.authentication).to eq("foo:bar")
73
+ end
74
+
75
+ it "reads snapshots authentication from maven settings.xml" do
76
+ m = Pushwagner::Maven.new(cfg, "1")
77
+ m.repository.should_receive(:open).
78
+ with(/.*settings.xml$/).
79
+ and_return(settings)
80
+
81
+ expect(m.repository.authentication(true)).to eq("bar:baz")
82
+ end
83
+
84
+ let(:metadata) {IO.read(File.join(config_root, 'maven-metadata.xml'))}
85
+
86
+ it "builds maven2-repo-style urls and retrieves metadata" do
87
+ m = Pushwagner::Maven.new(cfg, "1")
88
+
89
+ m.repository.should_receive(:authentication).and_return("")
90
+ m.repository.should_receive(:open).and_return(metadata)
91
+
92
+ snapshot = Pushwagner::Maven::Artifact.new("foo", "bar", "1.0-SNAPSHOT")
93
+ expect(m.repository.absolute_url(snapshot)).to eq("http://w00t.uppercase.no/nexus/content/repositories/snapshots/bar/foo/1.0-SNAPSHOT/foo-1.0-20121114.152717-3.jar")
94
+ end
95
+
96
+ it "builds maven2-repo-style urls for release artifacts" do
97
+ m = Pushwagner::Maven.new(cfg, "1")
98
+ release = Pushwagner::Maven::Artifact.new("foo", "bar", "1.0")
99
+ expect(m.repository.absolute_url(release)).to eq("http://w00t.uppercase.no/nexus/content/repositories/releases/bar/foo/1.0/foo-1.0.jar")
100
+ end
101
+
102
+ end
103
+
104
+ end
@@ -0,0 +1,19 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
2
+ require 'pushwagner'
3
+ require 'stringio'
4
+
5
+ require 'rspec'
6
+ require 'diff/lcs'
7
+
8
+ RSpec.configure do |config|
9
+ config.before do
10
+ ARGV.replace []
11
+ end
12
+
13
+ config.expect_with(:rspec) { |c| c.syntax = :expect }
14
+
15
+ def config_root
16
+ File.join(File.dirname(__FILE__), 'configs')
17
+ end
18
+
19
+ end
metadata ADDED
@@ -0,0 +1,175 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pushwagner
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Ole Christian Rynning
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-11-21 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: net-ssh
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: net-scp
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: nokogiri
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: '1.5'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1.5'
62
+ - !ruby/object:Gem::Dependency
63
+ name: bundler
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: '1.0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: '1.0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: rake
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: '0.9'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: '0.9'
94
+ - !ruby/object:Gem::Dependency
95
+ name: rspec
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ~>
100
+ - !ruby/object:Gem::Version
101
+ version: '2.11'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ version: '2.11'
110
+ description: Simple remote automation wrapper.
111
+ email: oc@rynning.no
112
+ executables:
113
+ - pw
114
+ extensions: []
115
+ extra_rdoc_files: []
116
+ files:
117
+ - .gitignore
118
+ - .rvmrc
119
+ - Gemfile
120
+ - Gemfile.lock
121
+ - Rakefile
122
+ - bin/pw
123
+ - lib/pushwagner.rb
124
+ - lib/pushwagner/environment.rb
125
+ - lib/pushwagner/ext.rb
126
+ - lib/pushwagner/main.rb
127
+ - lib/pushwagner/maven.rb
128
+ - lib/pushwagner/static.rb
129
+ - lib/pushwagner/supervisord.rb
130
+ - lib/pushwagner/version.rb
131
+ - pushwagner.gemspec
132
+ - spec/configs/empty.yml
133
+ - spec/configs/full.yml
134
+ - spec/configs/maven-metadata.xml
135
+ - spec/configs/maven.yml
136
+ - spec/configs/settings.xml
137
+ - spec/configs/static.yml
138
+ - spec/environment_spec.rb
139
+ - spec/maven_spec.rb
140
+ - spec/spec_helper.rb
141
+ homepage: http://rubygems.org/gems/pushwagner
142
+ licenses:
143
+ - MIT
144
+ post_install_message:
145
+ rdoc_options: []
146
+ require_paths:
147
+ - lib
148
+ required_ruby_version: !ruby/object:Gem::Requirement
149
+ none: false
150
+ requirements:
151
+ - - ! '>='
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
154
+ required_rubygems_version: !ruby/object:Gem::Requirement
155
+ none: false
156
+ requirements:
157
+ - - ! '>='
158
+ - !ruby/object:Gem::Version
159
+ version: 1.3.6
160
+ requirements: []
161
+ rubyforge_project:
162
+ rubygems_version: 1.8.24
163
+ signing_key:
164
+ specification_version: 3
165
+ summary: Simple remote automation wrapper (wip).
166
+ test_files:
167
+ - spec/configs/empty.yml
168
+ - spec/configs/full.yml
169
+ - spec/configs/maven-metadata.xml
170
+ - spec/configs/maven.yml
171
+ - spec/configs/settings.xml
172
+ - spec/configs/static.yml
173
+ - spec/environment_spec.rb
174
+ - spec/maven_spec.rb
175
+ - spec/spec_helper.rb