samus 1.0.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.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +22 -0
  3. data/README.md +255 -0
  4. data/bin/samus +87 -0
  5. data/commands/build/archive-git-full +3 -0
  6. data/commands/build/archive-git-full.help.md +7 -0
  7. data/commands/build/archive-tgz +3 -0
  8. data/commands/build/archive-tgz.help.md +7 -0
  9. data/commands/build/archive-zip +3 -0
  10. data/commands/build/archive-zip.help.md +7 -0
  11. data/commands/build/fs-copy +3 -0
  12. data/commands/build/fs-copy.help.md +8 -0
  13. data/commands/build/fs-mkdir +3 -0
  14. data/commands/build/fs-mkdir.help.md +7 -0
  15. data/commands/build/fs-rmrf +3 -0
  16. data/commands/build/fs-rmrf.help.md +7 -0
  17. data/commands/build/fs-sedfiles +7 -0
  18. data/commands/build/fs-sedfiles.help.md +8 -0
  19. data/commands/build/gem-build +5 -0
  20. data/commands/build/gem-build.help.md +7 -0
  21. data/commands/build/git-archive +3 -0
  22. data/commands/build/git-archive.help.md +8 -0
  23. data/commands/build/git-commit +7 -0
  24. data/commands/build/git-commit.help.md +8 -0
  25. data/commands/build/git-merge +9 -0
  26. data/commands/build/git-merge.help.md +8 -0
  27. data/commands/build/npm-test +3 -0
  28. data/commands/build/npm-test.help.md +7 -0
  29. data/commands/build/rake-task +3 -0
  30. data/commands/build/rake-task.help.md +7 -0
  31. data/commands/publish/cf-invalidate +16 -0
  32. data/commands/publish/cf-invalidate.help.md +8 -0
  33. data/commands/publish/gem-push +6 -0
  34. data/commands/publish/gem-push.help.md +7 -0
  35. data/commands/publish/git-push +15 -0
  36. data/commands/publish/git-push.help.md +8 -0
  37. data/commands/publish/npm-publish +3 -0
  38. data/commands/publish/npm-publish.help.md +7 -0
  39. data/commands/publish/s3-put +13 -0
  40. data/commands/publish/s3-put.help.md +10 -0
  41. data/lib/samus.rb +37 -0
  42. data/lib/samus/action.rb +60 -0
  43. data/lib/samus/build_action.rb +46 -0
  44. data/lib/samus/builder.rb +101 -0
  45. data/lib/samus/command.rb +99 -0
  46. data/lib/samus/credentials.rb +48 -0
  47. data/lib/samus/publish_action.rb +7 -0
  48. data/lib/samus/publisher.rb +38 -0
  49. data/lib/samus/version.rb +3 -0
  50. data/samus.gemspec +13 -0
  51. data/samus.json +44 -0
  52. metadata +95 -0
@@ -0,0 +1,7 @@
1
+ Removes a set of files from the build directory.
2
+
3
+ Files:
4
+ * A list of files relative to the build directory to delete.
5
+
6
+ Arguments:
7
+ * (none)
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ ARGV.each do |file|
4
+ contents = File.read(file)
5
+ contents = contents.gsub(Regexp.new(ENV['_search']), ENV['_replace'])
6
+ File.open(file, 'w') {|f| f.write(contents) }
7
+ end
@@ -0,0 +1,8 @@
1
+ Replaces text in a list of files in the working copy.
2
+
3
+ Files:
4
+ * A list of files to perform text replacement on.
5
+
6
+ Arguments:
7
+ * search: a regular expression to search for.
8
+ * replace: the text to replace.
@@ -0,0 +1,5 @@
1
+ #!/bin/sh
2
+
3
+ set -e
4
+ gem build $1
5
+ mv ${1%.gemspec}-$_version.gem $__build_dir
@@ -0,0 +1,7 @@
1
+ Builds a RubyGem package (.gem file)
2
+
3
+ Files:
4
+ * The name of the gemspec file to build
5
+
6
+ Arguments:
7
+ * (none)
@@ -0,0 +1,3 @@
1
+ #!/bin/sh
2
+
3
+ git archive --prefix="$_prefix" -o $__build_dir/$1 ${_ref-HEAD}
@@ -0,0 +1,8 @@
1
+ Exports the Git repository using the git archive command.
2
+
3
+ Files:
4
+ * The filename of the exported Git archive.
5
+
6
+ Arguments:
7
+ * ref: a commit, branch, or tag to export.
8
+ * prefix: a prefix to append to every path in the exported archive.
@@ -0,0 +1,7 @@
1
+ #!/bin/sh
2
+
3
+ set -e
4
+ git add $*
5
+ git commit -m "${_message-Bump version to v$_version}"
6
+ git tag ${_tag-v$_version}
7
+ echo tag ${_tag-v$_version} >> $__restore_file
@@ -0,0 +1,8 @@
1
+ Performs a commit on the working copy repository and tags the commit.
2
+
3
+ Files:
4
+ * The list of files to stage for commit.
5
+
6
+ Arguments:
7
+ * message: the commit message, defaults to "Bump version to vVERSION".
8
+ * tag: the tag name, defaults to vVERSION.
@@ -0,0 +1,9 @@
1
+ #!/bin/sh
2
+
3
+ set -e
4
+ git fetch ${_remote-origin}
5
+ git checkout -q $_branch
6
+ echo branch $_branch $(git rev-parse HEAD) >> $__restore_file
7
+ git rebase ${_remote-origin}/$_branch
8
+ git merge $__build_branch -q -m "Merge release branch into $_branch" -s recursive -Xtheirs --ff
9
+ git checkout -q $__build_branch
@@ -0,0 +1,8 @@
1
+ Merges release branch into a destination branch.
2
+
3
+ Files:
4
+ * (none)
5
+
6
+ Arguments:
7
+ * branch: the destination branch to merge.
8
+ * remote: the remote to fetch before merging. Defaults to "origin".
@@ -0,0 +1,3 @@
1
+ #!/bin/sh
2
+
3
+ npm test
@@ -0,0 +1,7 @@
1
+ Runs npm test on the working directory.
2
+
3
+ Files:
4
+ * (none)
5
+
6
+ Arguments:
7
+ * (none)
@@ -0,0 +1,3 @@
1
+ #!/bin/sh
2
+
3
+ rake $_task
@@ -0,0 +1,7 @@
1
+ Runs a Rake task.
2
+
3
+ Files:
4
+ * (none)
5
+
6
+ Arguments:
7
+ * task: the task to execute.
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ ENV['AWS_ACCESS_KEY_ID'] = ENV['__creds_key']
4
+ ENV['AWS_SECRET_ACCESS_KEY'] = ENV['__creds_secret']
5
+
6
+ require 'aws-sdk-core'
7
+
8
+ Aws.config[:region] = ENV['_region']
9
+ Aws.cloudfront.create_invalidation(
10
+ distribution_id: ENV['_distribution'],
11
+ invalidation_batch: {
12
+ paths: {
13
+ quantity: ARGV.size,
14
+ items: ARGV },
15
+ caller_reference: Time.now.to_s
16
+ })
@@ -0,0 +1,8 @@
1
+ Invalidates a CloudFront distribution.
2
+
3
+ Files:
4
+ * A list of URIs to invalidate.
5
+
6
+ Arguments:
7
+ * distribution: The CloudFront distribution ID.
8
+ * region: The region of the CloudFront distribution.
@@ -0,0 +1,6 @@
1
+ #!/bin/sh
2
+
3
+ curl --fail --silent -X POST \
4
+ -H "Content-Type: application/octet-stream" \
5
+ -H "Authorization: $__creds_secret" \
6
+ --data-binary @$* https://rubygems.org/api/v1/gems
@@ -0,0 +1,7 @@
1
+ Publishes a RubyGem package (.gem file).
2
+
3
+ Files:
4
+ * The .gem file to publish.
5
+
6
+ Arguments:
7
+ * (none)
@@ -0,0 +1,15 @@
1
+ #!/bin/sh
2
+
3
+ set -e
4
+ olddir=$(pwd)
5
+ dir=$(mktemp -d -t samus)
6
+
7
+ tar -xzf $* -C $dir
8
+
9
+ cd $dir
10
+ for r in $_remotes; do
11
+ git push $r $_refs
12
+ done
13
+ cd $olddir
14
+
15
+ rm -rf $dir
@@ -0,0 +1,8 @@
1
+ Pushes Git repository refs to a set of remotes.
2
+
3
+ Files:
4
+ * The repository archive filename.
5
+
6
+ Arguments:
7
+ * refs: a space delimited set of commits, branches, or tags to push.
8
+ * remotes: a space delimited set of remotes to push refs to.
@@ -0,0 +1,3 @@
1
+ #!/bin/sh
2
+
3
+ npm publish --email=$__creds_key --_auth=$__creds_secret ./$*
@@ -0,0 +1,7 @@
1
+ Publishes an npm package.
2
+
3
+ Files:
4
+ * The filename of the archived npm package
5
+
6
+ Arguments:
7
+ * (none)
@@ -0,0 +1,13 @@
1
+ #!/bin/sh
2
+
3
+ export AWS_ACCESS_KEY_ID=$__creds_key
4
+ export AWS_SECRET_ACCESS_KEY=$__creds_secret
5
+
6
+ set -e
7
+ for f in $*; do
8
+ recursive=""
9
+ if [ -d $f ]; then
10
+ recursive="--recursive"
11
+ fi
12
+ aws s3 cp $recursive --acl public-read --region $_region $f s3://$_bucket/$_prefix$_key
13
+ done
@@ -0,0 +1,10 @@
1
+ Uploads files or directories to an Amazon S3 bucket.
2
+
3
+ Files:
4
+ * A list of files to upload to the S3 bucket.
5
+
6
+ Arguments:
7
+ * region: the region of the S3 bucket.
8
+ * bucket: the name of the S3 bucket.
9
+ * prefix: (optional) a path to prefix to the uploaded key names.
10
+ * key: (optional) a key prefix path.
@@ -0,0 +1,37 @@
1
+ require_relative './samus/publisher'
2
+ require_relative './samus/builder'
3
+
4
+ module Samus
5
+ CONFIG_PATH = File.expand_path(ENV['SAMUS_CONFIG_PATH'] || '~/.samus')
6
+
7
+ module_function
8
+
9
+ def config_paths; @@config_paths end
10
+
11
+ @@config_paths = []
12
+
13
+ def load_configuration_directory
14
+ if File.exist?(CONFIG_PATH)
15
+ Dir.foreach(CONFIG_PATH) do |dir|
16
+ next if dir == '.' || dir == '..'
17
+ dir = File.join(CONFIG_PATH, dir)
18
+ config_paths.unshift(dir) if File.directory?(dir)
19
+ end
20
+ end
21
+ end
22
+
23
+ def load_commands
24
+ config_paths.each do |path|
25
+ path = File.join(path, 'commands')
26
+ Samus::Command.command_paths.unshift(path) if File.directory?(path)
27
+ end
28
+ end
29
+
30
+ def error(msg)
31
+ puts "[E] #{msg}"
32
+ exit(1)
33
+ end
34
+ end
35
+
36
+ Samus.load_configuration_directory
37
+ Samus.load_commands
@@ -0,0 +1,60 @@
1
+ require_relative './command'
2
+ require_relative './credentials'
3
+
4
+ module Samus
5
+ class Action
6
+ def initialize(opts = {})
7
+ @raw_options = opts
8
+ @dry_run = opts[:dry_run]
9
+ @allow_fail = false
10
+ @command = nil
11
+ @creds = nil
12
+ @arguments = opts[:arguments] || {}
13
+ end
14
+
15
+ def stage; raise NotImplementedError, 'action must define stage' end
16
+
17
+ def load(opts = {})
18
+ opts.each do |key, value|
19
+ meth = "#{key}="
20
+ if respond_to?(meth)
21
+ send(meth, value)
22
+ else
23
+ Samus.error("Unknown action property: #{key}")
24
+ end
25
+ end
26
+ self
27
+ end
28
+
29
+ def run
30
+ @command.run(command_options) if @command
31
+ end
32
+
33
+ def command_options
34
+ {
35
+ :arguments => @creds ? @arguments.merge(@creds.load) : @arguments,
36
+ :files => @files,
37
+ :dry_run => @dry_run,
38
+ :allow_fail => @allow_fail
39
+ }
40
+ end
41
+
42
+ def action=(name)
43
+ @command = Command.new(stage, name)
44
+ end
45
+
46
+ def credentials=(key)
47
+ @creds = Credentials.new(key)
48
+ end
49
+
50
+ def allowFail=(value)
51
+ @allow_fail = value
52
+ end
53
+
54
+ attr_writer :files
55
+
56
+ def arguments=(args)
57
+ args.each {|k, v| @arguments[k] = v }
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,46 @@
1
+ require_relative './action'
2
+
3
+ module Samus
4
+ class BuildAction < Action
5
+ def initialize(opts = {})
6
+ super(opts)
7
+ @pwd = nil
8
+ @skip = false
9
+ end
10
+
11
+ attr_reader :publish
12
+
13
+ def stage; 'build' end
14
+
15
+ def command_options
16
+ super.merge(:pwd => @pwd)
17
+ end
18
+
19
+ def pwd=(pwd)
20
+ @pwd = pwd
21
+ end
22
+
23
+ def run
24
+ return if @skip
25
+ super
26
+ end
27
+
28
+ def publish=(publish)
29
+ @publish = Array === publish ? publish : [publish]
30
+ @publish.each do |publish_action|
31
+ publish_action['files'] ||= @files if @files
32
+ end
33
+ @publish
34
+ end
35
+
36
+ attr_reader :skip
37
+ def condition=(condition)
38
+ begin
39
+ @skip = !eval(condition)
40
+ rescue => e
41
+ puts "[E] Condition failed on #{@raw_options['action']}"
42
+ raise e
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,101 @@
1
+ require 'json'
2
+ require 'tmpdir'
3
+
4
+ require_relative './build_action'
5
+
6
+ module Samus
7
+ class Builder
8
+ RESTORE_FILE = ".git/samus-restore"
9
+
10
+ attr_reader :build_manifest
11
+
12
+ def initialize(build_manifest_file)
13
+ @stage = 'build'
14
+ @build_manifest_file = build_manifest_file
15
+ @build_manifest = JSON.parse(File.read(build_manifest_file).gsub('$version', $VERSION))
16
+ @manifest = {}
17
+ end
18
+
19
+ def build(dry_run = false, zip_release = true)
20
+ orig_pwd = Dir.pwd
21
+ manifest = {'version' => $VERSION, 'actions' => []}
22
+ build_branch = "samus-release/v#{$VERSION}"
23
+ orig_branch = `git symbolic-ref -q --short HEAD`.chomp
24
+
25
+ system "git checkout -qb #{build_branch} 2>/dev/null"
26
+ remove_restore_file
27
+
28
+ Dir.mktmpdir do |build_dir|
29
+ actions.map do |action|
30
+ BuildAction.new(:dry_run => dry_run, :arguments => {
31
+ "_restore_file" => RESTORE_FILE,
32
+ "_build_dir" => build_dir,
33
+ "_build_branch" => build_branch,
34
+ "version" => $VERSION
35
+ }).load(action)
36
+ end.each do |action|
37
+ next if action.skip
38
+ action.run
39
+ manifest['actions'] += action.publish if action.publish
40
+ end
41
+
42
+ Dir.chdir(build_dir) do
43
+ generate_manifest(manifest)
44
+ generate_release(orig_pwd, zip_release)
45
+ end unless dry_run
46
+ end
47
+
48
+ ensure
49
+ restore_git_repo
50
+ system "git checkout -q #{orig_branch}"
51
+ system "git branch -qD #{build_branch}"
52
+ end
53
+
54
+ private
55
+
56
+ def generate_manifest(manifest)
57
+ File.open('manifest.json', 'w') do |f|
58
+ f.puts JSON.pretty_generate(manifest, indent: ' ')
59
+ end
60
+ end
61
+
62
+ def generate_release(orig_pwd, zip_release = true)
63
+ file = build_manifest['output'] || "release-v#{$VERSION}"
64
+ file = File.join(orig_pwd, file)
65
+ if zip_release
66
+ file += '.tar.gz'
67
+ system "tar cfz #{file} *"
68
+ else
69
+ system "mkdir -p #{file} && cp -r * #{file}"
70
+ end
71
+ puts "[I] Built release package: #{File.basename(file)}"
72
+ end
73
+
74
+ def actions
75
+ build_manifest['actions']
76
+ end
77
+
78
+ def restore_git_repo
79
+ return unless File.file?(RESTORE_FILE)
80
+
81
+ File.readlines(RESTORE_FILE).each do |line|
82
+ type, branch, commit = *line.split(/\s+/)
83
+ case type
84
+ when "tag"
85
+ puts "[D] Removing tag #{branch}" if $DEBUG
86
+ system "git tag -d #{branch} >/dev/null"
87
+ when "branch"
88
+ puts "[D] Restoring #{branch} to #{commit}" if $DEBUG
89
+ system "git checkout -q #{branch}"
90
+ system "git reset -q --hard #{commit}"
91
+ end
92
+ end
93
+ ensure
94
+ remove_restore_file
95
+ end
96
+
97
+ def remove_restore_file
98
+ File.unlink(RESTORE_FILE) if File.file?(RESTORE_FILE)
99
+ end
100
+ end
101
+ end