punt 0.0.3 → 0.0.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 687b38915674b3400cd3b3d16615c26f4628c546
4
- data.tar.gz: 861ddf532ff4c71e1d51cbdf59eb87292f152e71
3
+ metadata.gz: 85662d179b096c017a378b0b34fea547c5da584f
4
+ data.tar.gz: 06f3732c176a5c0f7e681c7c00f5598388ec3d80
5
5
  SHA512:
6
- metadata.gz: 39bae4b4a2fc7ad3ceb4a09d6b1c21f1174ad1f9cde866ef6ab5484581b7127cc24139aa6289293d91ad605043edc5c140f009a1293b9a06fba0d00aa61dcf70
7
- data.tar.gz: 95fb837f967c75d4cfe94a0d09b90f0469c0adc0e59ca91b1dd0c859009ae9a15e451f7d4b8bb14ffa370174bb88d60db795c1133a787906e7e392b71daf17ec
6
+ metadata.gz: 6805ab861ee0fb061e4df7f7f23124b3b3720740066e2c6c31f50a72556b2a0476c54f8789c3fdb521c087d2aed339d7e8963834049d9644070f19f338aeec15
7
+ data.tar.gz: dead02ac41701114854d8ebec2091a19a09e8ea0ef538e1f5842862009495652ff2c677b88ae082d26d0e062cb747789b0867b1e64529566254fb6bd6d7ef168
data/lib/punt.rb CHANGED
@@ -1,7 +1,14 @@
1
1
  require 'yaml'
2
2
 
3
- require 'punt/asset_helper'
4
- require 'punt/puntfile'
3
+ require 'punt/mode/mode_scp'
4
+ require 'punt/repo/repo_git'
5
+
6
+ require 'punt/helper/asset_helper'
7
+ require 'punt/helper/puntfile_helper'
8
+ require 'punt/helper/mode_helper'
9
+ require 'punt/helper/repo_helper'
10
+
11
+ require 'punt/deploy'
5
12
 
6
13
  require 'punt/cmd/cmd'
7
14
  require 'punt/cmd/cmd_init'
@@ -2,141 +2,20 @@ require 'optparse'
2
2
  require 'tempfile'
3
3
 
4
4
  class CmdDeploy < Cmd
5
- include Puntfile
6
5
 
7
6
  tag name: "deploy"
8
7
  tag summary: "Deploy to the specified environment"
9
8
 
10
9
  def run(argv)
11
10
  opts = parse_opts(argv)
12
-
13
- if (opts[:dry_run])
14
- puts "Dry Run! Nothing will be deployed or modified. All commands that would cause side-effects will be printed below"
15
- end
16
-
17
11
  env = argv.shift
18
- ref = argv.shift
19
-
20
-
21
- env = puntfile.first.first unless env
22
-
23
- environment = puntfile[env] if env
24
-
25
-
26
-
27
- if (!environment)
28
- raise "No environment #{env} was found in the puntfile"
29
- end
30
-
31
- mode = environment["mode"]
32
-
33
- if mode != "scp"
34
- raise "No mode available for the given mode '#{mode}'"
35
- end
36
-
37
-
38
- # Some Git Stuff
39
- repo = environment["repo"]
40
- if (repo != "git")
41
- raise "No repo available for the given repository type #{repo}"
42
- end
43
-
44
- original_head = `git rev-parse --short HEAD`.strip
45
- original_branch = `git rev-parse --abbrev-ref HEAD`.strip
46
-
47
- ref = original_head unless ref
48
- ref = `git rev-parse --short --verify #{ref}`.strip
49
- ref_full = `git rev-parse --verify #{ref}`.strip
50
-
51
- # TODO: Check to see if there are any changes! Yell and complain if there are any changes
52
-
53
-
54
-
55
- puts "Deploying #{ref} to #{env}"
56
- puts ""
57
-
58
- # Checkout the code
59
- if ref != original_head
60
- if opts[:dry_run]
61
- puts "git checkout #{ref}"
62
- else
63
- `git checkout #{ref}`
64
- end
65
- end
66
-
67
- # Upload Version File
68
- scp_versionfile(ref_full, "start", environment, dry_run: opts[:dry_run] || false)
69
- if environment["files"]
70
- environment["files"].each do |key, value|
71
- scp_upload(key, value, environment, dry_run: opts[:dry_run] || false)
72
- end
73
- end
74
- scp_versionfile(ref_full, "success", environment, dry_run: opts[:dry_run] || false)
12
+ repo_ref = argv.shift
75
13
 
76
- # Revert to our previous checkout
77
- if ref != original_head
78
- if opts[:dry_run]
79
- puts "git checkout #{original_branch}"
80
- else
81
- `git checkout #{original_branch}`
82
- end
83
- end
14
+ Deploy.new.deploy(env: env, repo_ref: repo_ref, dry_run: opts[:dry_run], force_local: opts[:force_local])
84
15
  end
85
16
 
86
17
  private
87
18
 
88
- def scp_versionfile(ref, version_name, environment, dry_run: false)
89
-
90
- if (!dry_run)
91
- versionfile = Tempfile.new('foo')
92
- versionfile.write("#{ref}")
93
- versionfile.close()
94
-
95
- scp_upload(versionfile.path, ".punt_#{version_name}", environment, dry_run: dry_run)
96
-
97
- versionfile.unlink
98
- end
99
- end
100
-
101
- def scp_upload(local_file, remote, environment, dry_run: false)
102
- scp_args = ["scp"]
103
- scp = scp_opts(environment, scp_args)
104
-
105
- if (File.directory?(local_file))
106
- scp << "-r"
107
- end
108
-
109
- scp << local_file
110
- scp << scp_remote_file(remote, environment)
111
-
112
- scp_command = scp.join(" ")
113
-
114
- puts scp_command
115
- `#{scp_command}` unless dry_run
116
- end
117
-
118
- def scp_opts(environment, scp_args)
119
- if (environment["ssh_key"])
120
- scp_args << "-i"
121
- scp_args << environment["ssh_key"]
122
- end
123
- end
124
-
125
- def scp_remote_file(remote, environment)
126
- if !remote.start_with?("/") && !remote.start_with?("~")
127
- remote = File.join(environment["remote_base"], remote)
128
- end
129
-
130
- return "#{scp_host(environment)}#{remote}"
131
- end
132
-
133
- def scp_host(environment)
134
- arg = "#{environment["host"]}:"
135
- arg = "#{environment["username"]}@#{arg}" if environment["username"]
136
-
137
- return arg
138
- end
139
-
140
19
  def parse_opts(argv)
141
20
  options = {}
142
21
 
@@ -146,6 +25,10 @@ class CmdDeploy < Cmd
146
25
  opts.on("-d", "--dry-run", "Show the commands that punt would execute, but don't actually do anything.") do |d|
147
26
  options[:dry_run] = d
148
27
  end
28
+
29
+ opts.on("-l", "--force-local", "Try and push commits even if there are local changes") do |f|
30
+ options[:force_local] = f
31
+ end
149
32
  end
150
33
 
151
34
  opt_parser.parse!(argv)
@@ -1,7 +1,7 @@
1
1
  require 'tempfile'
2
2
 
3
3
  class CmdRemote < Cmd
4
- include Puntfile
4
+ include PuntfileHelper
5
5
 
6
6
  tag name: "remote"
7
7
  tag summary: "Return the SHA1 of the version deployed to the remote"
@@ -0,0 +1,66 @@
1
+ class Deploy
2
+ include PuntfileHelper
3
+ include ModeHelper
4
+ include RepoHelper
5
+
6
+ def deploy(env: nil, repo_ref: nil, dry_run: false, force_local: false)
7
+
8
+ dry_run_banner if dry_run
9
+
10
+ environment = punt_environment(env: env)
11
+
12
+ mode = get_mode(environment)
13
+ repo = get_repo(environment)
14
+
15
+ repo_state = repo.save_state()
16
+ mode_opts = mode.mode_opts(environment)
17
+
18
+ starting_revision = repo.current_revision_name(short: true)
19
+
20
+ repo_ref = starting_revision unless repo_ref
21
+ desired_revision = repo.canonical_revision_name(repo_ref, short: true)
22
+ desired_revision_long = repo.canonical_revision_name(repo_ref, short: false)
23
+
24
+ if (repo.any_uncommited_changes?)
25
+ if force_local
26
+ puts "There are uncommitted changes! We're going to try and deploy anyway because the --force-local flag was present"
27
+ else
28
+ raise "There are uncommitted changes! Run `git status` to view the uncommitted files. Commit all of your changes, so that the deploy comes from a specific git revision. To force a deploy using these local changes use the parameter --force-local and don't specify a specific commit ref"
29
+ end
30
+ end
31
+
32
+ puts "Deploying #{desired_revision} to #{env}"
33
+ puts ""
34
+
35
+ # Checkout the code
36
+ if desired_revision != starting_revision
37
+ repo.checkout_revision(desired_revision, dry_run: dry_run)
38
+ end
39
+
40
+ # Upload Starting File
41
+ mode.upload_versionfile(desired_revision_long, "start", mode_opts: mode_opts ) unless dry_run
42
+
43
+ # Upload Files
44
+ if environment["files"]
45
+ environment["files"].each do |key, value|
46
+ mode.upload(key, value, mode_opts: mode_opts, dry_run: dry_run, verbose: true)
47
+ end
48
+ end
49
+
50
+ # Upload Success File
51
+ mode.upload_versionfile(desired_revision_long, "success", mode_opts: mode_opts ) unless dry_run
52
+
53
+ # Revert to our previous checkout
54
+ if desired_revision != starting_revision
55
+ repo.restore_state(repo_state, dry_run: dry_run)
56
+ end
57
+ end
58
+
59
+ private
60
+
61
+ def dry_run_banner
62
+ puts "Dry Run!"
63
+ puts "\tNothing will be deployed or modified. All commands that would cause side-effects will be printed below"
64
+ puts ""
65
+ end
66
+ end
@@ -0,0 +1,9 @@
1
+ module ModeHelper
2
+ def get_mode(environment)
3
+ env_mode = environment["mode"]
4
+ mode = ModeScp.new if env_mode == "scp"
5
+
6
+ raise "No mode available for the given mode '#{env_mode}'" unless mode
7
+ return mode
8
+ end
9
+ end
@@ -0,0 +1,42 @@
1
+ module PuntfileHelper
2
+
3
+ SUPPORTED_PUNTFILES = ["puntfile.yml", "puntfile.yaml", "Puntfile.yml", "Puntfile.yaml", "puntfile", "Puntfile"]
4
+
5
+ # Returns the puntfile hash for the current program. This will scan the various supported Puntfile
6
+ # file formats and attempt to load the first one it finds.
7
+ def puntfile
8
+ load_puntfile
9
+
10
+ return @@puntfile
11
+ end
12
+
13
+ # Pulls the specific environment hash out of the Puntfile. If no environment is
14
+ # given, this automatically returns the default environment.
15
+ def punt_environment(env: nil)
16
+ env = puntfile.first.first unless env
17
+ environment = puntfile[env] if env
18
+
19
+ if (!environment)
20
+ raise "No environment #{env} was found in the puntfile"
21
+ end
22
+
23
+ return environment
24
+ end
25
+
26
+ private
27
+
28
+ def load_puntfile
29
+ return if defined?(@@puntfile)
30
+
31
+ SUPPORTED_PUNTFILES.each do |puntfile|
32
+ if File.exists?(puntfile)
33
+ @@puntfile = YAML.load_file(puntfile)
34
+ return
35
+ end
36
+ end
37
+
38
+ raise "We couldn't find puntfile.yml in the current directory"
39
+ end
40
+
41
+
42
+ end
@@ -0,0 +1,9 @@
1
+ module RepoHelper
2
+ def get_repo(environment)
3
+ env_repo = environment["repo"]
4
+ repo = RepoGit.new if env_repo == "git"
5
+
6
+ raise "No repo available for the given repo '#{env_repo}'" unless repo
7
+ return repo
8
+ end
9
+ end
@@ -0,0 +1,59 @@
1
+ class ModeScp
2
+
3
+ def mode_opts(environment)
4
+ return environment["scp"]
5
+ end
6
+
7
+ def upload(local_path, remote_path, mode_opts: nil, dry_run: false, verbose: true)
8
+ scp_args = ["scp"]
9
+ scp_common_options(mode_opts, scp_args)
10
+
11
+ if (File.directory?(local_path))
12
+ scp_args << "-r"
13
+ end
14
+
15
+ scp_args << local_path
16
+ scp_args << scp_remote_file(remote_path, mode_opts)
17
+
18
+ scp_command = scp_args.join(" ")
19
+
20
+ puts scp_command if verbose
21
+ `#{scp_command}` unless dry_run
22
+ end
23
+
24
+ def upload_versionfile(version, deploystage, mode_opts: nil)
25
+ filename = ".punt_#{deploystage}"
26
+
27
+ versionfile = Tempfile.new(filename)
28
+ versionfile.write("#{version}")
29
+ versionfile.close()
30
+
31
+ upload(versionfile.path, filename, mode_opts: mode_opts)
32
+
33
+ versionfile.unlink
34
+ end
35
+
36
+ private
37
+
38
+ def scp_common_options(scp_opts, scp_args)
39
+ if (scp_opts["ssh_key"])
40
+ scp_args << "-i"
41
+ scp_args << scp_opts["ssh_key"]
42
+ end
43
+ end
44
+
45
+ def scp_remote_file(remote_path, scp_opts)
46
+ if !remote_path.start_with?("/") && !remote_path.start_with?("~")
47
+ remote_path = File.join(scp_opts["remote_base"], remote_path)
48
+ end
49
+
50
+ return "#{scp_host(scp_opts)}#{remote_path}"
51
+ end
52
+
53
+ def scp_host(scp_opts)
54
+ arg = "#{scp_opts["host"]}:"
55
+ arg = "#{scp_opts["user"]}@#{arg}" if scp_opts["user"]
56
+
57
+ return arg
58
+ end
59
+ end
@@ -0,0 +1,37 @@
1
+ class RepoGit
2
+
3
+ def any_uncommited_changes?()
4
+ return true if `git diff --numstat | wc -l`.strip != "0"
5
+ return true if `git diff --cached --numstat | wc -l`.strip != "0"
6
+ return true if `git ls-files --others --exclude-standard | wc -l`.strip != "0"
7
+ return false
8
+ end
9
+
10
+ def current_revision_name(short: false)
11
+ canonical_revision_name("HEAD", short: short)
12
+ end
13
+
14
+ def canonical_revision_name(revision_name, short: false)
15
+ return `git rev-parse --short --verify #{revision_name}`.strip if short
16
+ return `git rev-parse --verify #{revision_name}`.strip
17
+ end
18
+
19
+ def checkout_revision(revision_name, dry_run: false)
20
+ puts "git checkout #{revision_name}" if dry_run
21
+ `git checkout #{revision_name}` unless dry_run
22
+ end
23
+
24
+ def save_state()
25
+ current_branch = `git rev-parse --abbrev-ref HEAD`
26
+
27
+ return current_revision_name if current_branch == "HEAD"
28
+ return current_branch
29
+ end
30
+
31
+ def restore_state(state, dry_run: false)
32
+ puts "git checkout #{state}" if dry_run
33
+ `git checkout #{state}` unless dry_run
34
+ end
35
+
36
+
37
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: punt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Noah Callaway
@@ -21,12 +21,17 @@ files:
21
21
  - assets/init/puntfile.yml
22
22
  - bin/punt
23
23
  - lib/punt.rb
24
- - lib/punt/asset_helper.rb
25
24
  - lib/punt/cmd/cmd.rb
26
25
  - lib/punt/cmd/cmd_deploy.rb
27
26
  - lib/punt/cmd/cmd_init.rb
28
27
  - lib/punt/cmd/cmd_remote.rb
29
- - lib/punt/puntfile.rb
28
+ - lib/punt/deploy.rb
29
+ - lib/punt/helper/asset_helper.rb
30
+ - lib/punt/helper/mode_helper.rb
31
+ - lib/punt/helper/puntfile_helper.rb
32
+ - lib/punt/helper/repo_helper.rb
33
+ - lib/punt/mode/mode_scp.rb
34
+ - lib/punt/repo/repo_git.rb
30
35
  homepage: http://rubygems.org/gems/punt
31
36
  licenses:
32
37
  - MIT
data/lib/punt/puntfile.rb DELETED
@@ -1,27 +0,0 @@
1
- module Puntfile
2
-
3
- SUPPORTED_PUNTFILES = ["puntfile.yml", "puntfile.yaml", "Puntfile.yml", "Puntfile.yaml", "puntfile", "Puntfile"]
4
-
5
- def puntfile
6
- load_puntfile
7
-
8
- return @@puntfile
9
- end
10
-
11
- private
12
-
13
- def load_puntfile
14
- return if defined?(@@puntfile)
15
-
16
- SUPPORTED_PUNTFILES.each do |puntfile|
17
- if File.exists?(puntfile)
18
- @@puntfile = YAML.load_file(puntfile)
19
- return
20
- end
21
- end
22
-
23
- raise "We couldn't find puntfile.yml in the current directory"
24
- end
25
-
26
-
27
- end