gaffer 0.0.2 → 0.1.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.
data/Rakefile CHANGED
@@ -10,6 +10,9 @@ Jeweler::Tasks.new do |s|
10
10
  s.files = FileList["[A-Z]*", "{bin,default,lib,spec}/**/*"]
11
11
  s.executables = %w(gaffer)
12
12
  s.add_dependency "git"
13
+ s.add_dependency "right_aws"
14
+ s.add_dependency "bundler"
15
+ s.add_dependency "rush"
13
16
  end
14
17
 
15
18
  #Jeweler::RubyforgeTasks.new
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.2
1
+ 0.1.0
data/bin/gaffer CHANGED
@@ -4,23 +4,15 @@ require File.dirname(__FILE__) + '/../lib/gaffer'
4
4
 
5
5
  require 'optparse'
6
6
 
7
- options = { }
7
+ options = {}
8
8
 
9
9
  optparse = OptionParser.new do|opts|
10
10
  opts.banner = <<banner
11
- Usage: gaffer [options] ...
11
+ Usage: gaffer [options] ACTION [ DIR [ DIR [ ... ] ] ]
12
12
  banner
13
13
 
14
- opts.on( '-p', '--project NAME', 'Specify a project name. Default is $DIR.' ) do |project|
15
- options[:project] = project
16
- end
17
-
18
- opts.on( '-P', '--prefix PREFIX', 'Install prefix. Default is /opt/$PROJECT/' ) do |prefix|
19
- options[:prefix] = prefix
20
- end
21
-
22
- opts.on( '-v', '--version VERSION', 'Specify a project name. Default is $DIR/VERSION' ) do |version|
23
- options[:version] = version
14
+ opts.on( '-f', '--force', 'Force an action' ) do
15
+ options[:force] = true
24
16
  end
25
17
 
26
18
  opts.on( '-h', '--help', 'Display this screen' ) do
@@ -31,5 +23,26 @@ end
31
23
 
32
24
  optparse.parse!
33
25
 
34
- Gaffer::Base.new(options).compile
26
+ command = ARGV.shift
27
+ target = ARGV.shift || Dir::pwd
28
+
29
+ gaffer = Gaffer::Base.new(options)
30
+
31
+ case command
32
+ when "initrepo"
33
+ gaffer.repro.init
34
+ when "pull"
35
+ gaffer.repro.pull
36
+ when "build"
37
+ gaffer.build(target)
38
+ when "push"
39
+ gaffer.repro.push
40
+ when "add"
41
+ gaffer.add(target)
42
+ when "publish"
43
+ gaffer.push gaffer.compile(target)
44
+ else
45
+ puts "No action: --help for help [#{command}]"
46
+ exit 1
47
+ end
35
48
 
@@ -1,4 +1,9 @@
1
1
  require 'tmpdir'
2
+ require 'erb'
2
3
  require 'git'
4
+ require 'rush'
5
+ require 'fileutils'
6
+ require 'right_aws'
3
7
  require File.dirname(__FILE__) + '/gaffer/base'
4
8
  require File.dirname(__FILE__) + '/gaffer/deb'
9
+ require File.dirname(__FILE__) + '/gaffer/repro'
@@ -1,35 +1,85 @@
1
1
  module Gaffer
2
2
  class Base
3
- attr_accessor :dir, :git, :project, :readme, :depends, :version, :prefix, :maintainer, :build
3
+ attr_accessor :dir, :git, :project, :readme, :depends, :version, :prefix, :maintainer, :build_name
4
4
 
5
5
  def initialize(options)
6
- @dir = options[:dir] || Dir.pwd
7
- @git = Git.open(@dir)
8
- @version = options[:version]
9
- @project = options[:project] || File.basename(File.dirname(@git.repo.path))
6
+ @force = options[:force]
7
+ end
8
+
9
+ def build(dir)
10
+ @git = Git::open(dir)
11
+
12
+ @project = File::basename(File::dirname(@git.repo.path))
10
13
  @maintainer = "#{@git.config["user.name"]} <#{@git.config["user.email"]}>"
11
- @prefix = options[:prefix] || "opt/#{@project}"
14
+ @prefix = "opt/#{@project}"
12
15
 
13
- @git.chdir do
14
- @readme = File.read("README") rescue "no README file"
15
- @depends = File.read("DEPENDS").chomp rescue "libc6 (>= 2.10)"
16
- @version ||= File.read("VERSION").chomp
17
- end
16
+ @readme = File::read("#{dir}/README") rescue "no README file"
17
+ @depends = File::read("#{dir}/DEPENDS").chomp rescue "libc6 (>= 2.10)"
18
+ @version = File::read("#{dir}/VERSION").chomp
19
+
20
+ raise "Bad version #{@version}" unless @version =~ /^\d+[.]\d+[.]\d+$/
18
21
 
19
- puts "======> #{@version.inspect}"
20
22
  build_id = @git.tags.map { |a| a.name =~ /^#{@version}-(.+)/; $1.to_i }.sort.last.to_i + 1
21
- @build = "#{@version}-#{build_id}"
23
+ @build_name = "#{@version}-#{build_id}"
22
24
 
23
- raise "Bad version #{@version}" unless @version =~ /^\d+[.]\d+[.]\d+$/
24
- end
25
+ puts "======> #{@version.inspect}"
25
26
 
26
- def compile
27
- @git.add_tag(@build)
27
+ @git.add_tag(@build_name)
28
28
  ## check version - tag repo
29
- [ "i386", "amd64" ].each do |arch|
30
- Gaffer::Deb.new(self, arch, project, depends).compile
31
- Gaffer::Deb.new(self, arch, "#{project}-dev", "#{project} (>= #{@version})").compile
29
+
30
+ Gaffer::Deb::new(self, project, depends).build
31
+ # Gaffer::Deb::new(self, "#{project}-dev", "#{project} (>= #{@version})").build
32
+ end
33
+
34
+ def add(file)
35
+ file = File.expand_path(file)
36
+ Dir.chdir(repro_dir) do
37
+ repro.include(file)
32
38
  end
33
39
  end
40
+
41
+ def push_changed(dir, &blk)
42
+ # I can optimze later
43
+ start = Time::now
44
+ Dir.chdir(dir) do
45
+ blk.call
46
+ Dir["**/*"].select { |file| File::stat(file).mtime >= start }.each do |file|
47
+ puts "PUSHING: #{f}"
48
+ end
49
+ end
50
+ end
51
+
52
+ def repro
53
+ options = {}
54
+
55
+ options[:aws_key] ||= ENV['AWS_ACCESS_KEY_ID']
56
+ options[:aws_secret] ||= ENV['AWS_SECRET_ACCESS_KEY']
57
+ options[:bucket] ||= ENV['REP_BUCKET']
58
+ options[:email] ||= ENV['REP_EMAIL']
59
+ options[:maintainer] ||= ENV['REP_MAINTAINER']
60
+ options[:key] ||= options[:email]
61
+
62
+ options[:codename] ||= "maverick"
63
+ options[:components] ||= "main"
64
+ options[:force] ||= !!@force
65
+
66
+ dir = repro_dir
67
+
68
+ puts "Repo: #{dir}"
69
+
70
+ Gaffer::Repro.new(dir, options)
71
+ end
72
+
73
+ def repro_dir
74
+ if ENV['HOME']
75
+ "#{ENV['HOME']}/.gaffer/repo"
76
+ else
77
+ "/var/lib/gaffer/repo"
78
+ end
79
+ end
80
+
81
+ def repro_ready?
82
+ File.exists? "#{repro_dir}/ubuntu/conf/distributions"
83
+ end
34
84
  end
35
85
  end
@@ -1,66 +1,83 @@
1
1
  module Gaffer
2
2
  class Deb
3
- def initialize(base, arch, package, depends)
3
+ attr_accessor :package, :readme, :depends, :arch
4
+
5
+ def initialize(base, _package, _depends)
4
6
  @base = base
5
- @arch = arch
6
- @package = package
7
- @depends = depends
7
+ @arch = "all"
8
+ @package = _package
9
+ @depends = _depends
8
10
  @dev = !!(@package =~ /-dev$/)
9
11
  end
10
12
 
11
- def compile
12
- puts self.inspect
13
+ def build
13
14
  Dir.mktmpdir do |dir|
14
15
  install_dir = "#{dir}/#{@base.prefix}"
15
16
  Git.clone(@base.dir, install_dir)
16
- system "mkdir #{dir}/DEBIAN"
17
- puts control
17
+ Rush.bash "mkdir #{dir}/DEBIAN"
18
18
  File.open("#{dir}/DEBIAN/control", "w") do |f|
19
19
  f.write(control)
20
20
  end
21
+ puts control
21
22
  if @dev
22
- system "find #{install_dir} | grep -v [.]git | grep -v #{install_dir}$ | xargs rm -rf"
23
+ Rush.bash "find #{install_dir} | grep -v [.]git | grep -v #{install_dir}$ | xargs rm -rf"
23
24
  else
24
- system "rm -rf #{install_dir}/.git"
25
- [ "preinst", "postinst", "prerm", "postrm" ].each do |script|
26
- system "cp #{@base.dir}/#{script} #{dir}/DEBIAN/" if File.exists?("#{@base.dir}/#{script}")
27
- end
28
- if File.exists?("#{@base.dir}/init.conf")
25
+ Rush.bash "find #{install_dir} | grep [.]git | grep -v #{install_dir}$ | xargs rm -rf"
26
+ # [ :preinst, :postinst, :prerm, :postrm ].each do |script|
27
+ # file = File.open("#{dir}/DEBIAN/#{script}","w")
28
+ # file.chmod(0755)
29
+ # file.write(template(script))
30
+ # file.close
31
+ # end
32
+ if has_init?
29
33
  puts "INSTALLING init.conf"
30
- system "mkdir -p #{dir}/etc/init"
31
- system "cp #{@base.dir}/init.conf #{dir}/etc/init/#{@base.project}.conf"
34
+ Rush.bash "mkdir -p #{dir}/etc/init"
35
+ Rush.bash "cp #{@base.dir}/init.conf #{dir}/etc/init/#{@base.project}.conf"
36
+ end
37
+ if File.exists?("#{@base.dir}/Gemfile")
38
+ Dir.chdir(@base.dir) do
39
+ # TODO this can break in strange ways - STDOUT/STDERR is a mess
40
+ if Rush.bash('bundle install --deployment').match(/native extensions/)
41
+ @arch = Rush.bash "dpkg --print-architecture"
42
+ end
43
+ end
32
44
  end
33
45
  end
34
- system "dpkg-deb -b #{dir} ./#{filebase}.deb"
46
+ Rush.bash "dpkg-deb -b #{dir} ./#{filebase}.deb"
47
+ File.expand_path("./#{filebase}.deb")
35
48
  end
36
49
  end
37
50
 
51
+ def has_init?
52
+ File.exists?("#{@base.dir}/init.conf")
53
+ end
54
+
38
55
  def origin_url
39
56
  @base.git.remotes.select { |r| r.name == "origin" }.map { |r| r.url }.first
40
57
  end
41
58
 
42
59
  def description
43
- "Gaffer package #{@package} #{@base.build}"
60
+ "Gaffer package #{package} #{build_name}"
44
61
  end
45
62
 
46
63
  def filebase
47
- "#{@package}_#{@base.build}_#{@arch}"
64
+ "#{package}_#{build_name}_#{@arch}"
65
+ end
66
+
67
+ def template(type)
68
+ ERB.new(File.read("#{File.dirname(__FILE__)}/../../templates/#{type}.erb")).result(binding)
69
+ end
70
+
71
+ def maintainer
72
+ @base.maintainer
73
+ end
74
+
75
+ def build_name
76
+ @base.build_name
48
77
  end
49
78
 
50
79
  def control
51
- <<CONTROL
52
- Source: #{@package}
53
- Section: unknown
54
- Priority: extra
55
- Maintainer: #{@base.maintainer}
56
- Version: #{@base.build}
57
- Homepage: #{origin_url}
58
- Package: #{@package}
59
- Architecture: #{@arch}
60
- Depends: #{@depends}
61
- Description: #{description}
62
- #{@readme}
63
- CONTROL
80
+ template(:control)
64
81
  end
65
82
  end
66
83
  end
@@ -0,0 +1,175 @@
1
+ module Gaffer
2
+ class Repro
3
+
4
+ def initialize(root, options = {})
5
+ @root = root
6
+ @maintainer = options[:maintainer]
7
+ @email = options[:email]
8
+ @key = options[:key]
9
+ @force = options[:force]
10
+ @codename = options[:codename]
11
+ @components = options[:components]
12
+ @bucket = options[:bucket]
13
+ @aws_key = options[:aws_key]
14
+ @aws_secret = options[:aws_secret]
15
+ end
16
+
17
+ def init
18
+ if not Dir[@root].empty?
19
+ raise "Dir #{@root} not empty - cannot init" unless @force
20
+ FileUtils.rm_rf @root
21
+ end
22
+ create_dirs
23
+ write_file "ubuntu/conf/options", options
24
+ write_file "ubuntu/conf/distributions", distributes
25
+ write_version 1
26
+ end
27
+
28
+ def create_dirs
29
+ repo_dirs.each do |dir|
30
+ if not File.exists?("#{@root}/ubuntu/#{dir}")
31
+ puts "* mkdir -p #{@root}/ubuntu/#{dir}"
32
+ FileUtils.mkdir_p "#{@root}/ubuntu/#{dir}"
33
+ end
34
+ end
35
+ end
36
+
37
+ def include(file)
38
+ bump_version
39
+ file = File.expand_path(file)
40
+ Dir.chdir("#{@root}/ubuntu") do
41
+ run "reprepro includedeb #{@codename} #{file}"
42
+ end
43
+ end
44
+
45
+ def ready!
46
+ raise "No repo. Use 'gaffer pull' to download a repo from S3 or 'gaffer initrepo' to make a new one" unless File.include? "#{@root}/ubuntu/conf/distributions"
47
+ end
48
+
49
+ def push
50
+ raise "Remote version #{remote_version} is higher than local #{local_version}. Use --force to override" if (remote_version > local_version && !@force)
51
+ puts "Version: #{local_version}"
52
+ delete_remote
53
+ write_remote
54
+ puts " [apt source]"
55
+ puts url
56
+ puts ""
57
+ end
58
+
59
+ def pull
60
+ raise "Local version #{local_version} is higher than local #{remote_version}. Use --force to override" if (remote_version < local_version && !@force)
61
+ create_dirs
62
+ puts "Version: #{remote_version}"
63
+ delete_local
64
+ write_local
65
+ end
66
+
67
+ def url
68
+ "deb http://#{@bucket}.s3.amazonaws.com/ubuntu/ #{@codename} #{@components}"
69
+ end
70
+
71
+ private
72
+
73
+ def repo_dirs
74
+ %w(conf dists incoming indices logs pool project tmp)
75
+ end
76
+
77
+ def write_file(path, data)
78
+ FileUtils.mkdir_p File.dirname("#{@root}/#{path}")
79
+ File.open("#{@root}/#{path}","w") do |f|
80
+ f.write(data)
81
+ end
82
+ end
83
+
84
+ def options
85
+ d = []
86
+ d << "ask-passphrase"
87
+ d << "basedir ."
88
+ d.join("\n") + "\n"
89
+ end
90
+
91
+ def distributes
92
+ d = []
93
+ d << "Origin: #{@maintainer}"
94
+ d << "Label: #{@maintainer} Deploy Repo"
95
+ d << "Codename: #{@codename}"
96
+ d << "Architectures: i386 amd64 source"
97
+ d << "Components: #{@components}"
98
+ d << "Description: Deploy repo for #{@maintainer}"
99
+ d << "SignWith: #{@key}" if @key
100
+ d.join("\n") + "\n"
101
+ end
102
+
103
+ def run(cmd)
104
+ Dir.chdir("#{@root}/ubuntu") do
105
+ puts "DEBUG: #{cmd}"
106
+ system(cmd) || (raise "Commmand failed: #{cmd}")
107
+ end
108
+ end
109
+
110
+ def s3
111
+ raise "Need aws key and secret to use s3" if @aws_key.nil? or @aws_secret.nil?
112
+ @s3 ||= RightAws::S3.new(@aws_key, @aws_secret, :logger => Logger.new(nil))
113
+ end
114
+
115
+ def remote
116
+ bucket.keys('prefix' => 'ubuntu').map { |k| k.to_s }
117
+ end
118
+
119
+ def local
120
+ Dir.chdir(@root) do
121
+ Dir["**/*"].reject { |f| File.directory?(f) }
122
+ end
123
+ end
124
+
125
+ def delete_local
126
+ (local - remote).each do |file|
127
+ puts "* local delete #{file}"
128
+ File.delete("#{@root}/#{file}")
129
+ end
130
+ end
131
+
132
+ def delete_remote
133
+ (remote - local).each do |file|
134
+ puts "* remote delete #{file}"
135
+ bucket.delete(file)
136
+ end
137
+ end
138
+
139
+ def write_local
140
+ remote.each do |file|
141
+ puts "* local write #{file}"
142
+ write_file(file, bucket.get(file))
143
+ end
144
+ end
145
+
146
+ def write_remote
147
+ local.each do |file|
148
+ next if File.directory?("#{@root}/#{file}")
149
+ puts "* remote write #{file}"
150
+ bucket.put("#{file}", File.open("#{@root}/#{file}"), {}, file =~ /^ubuntu\/(db|conf)\// ? 'private' : 'public-read')
151
+ end
152
+ end
153
+
154
+ def bucket
155
+ raise "bucket not set" unless @bucket
156
+ s3.bucket(@bucket, true)
157
+ end
158
+
159
+ def local_version
160
+ File.read("#{@root}/ubuntu/conf/version").to_i rescue 0
161
+ end
162
+
163
+ def remote_version
164
+ bucket.get("ubuntu/conf/version").to_i rescue 0
165
+ end
166
+
167
+ def bump_version
168
+ write_version(local_version + 1)
169
+ end
170
+
171
+ def write_version(version)
172
+ write_file "ubuntu/conf/version", version.to_s
173
+ end
174
+ end
175
+ end
metadata CHANGED
@@ -5,9 +5,9 @@ version: !ruby/object:Gem::Version
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
+ - 1
8
9
  - 0
9
- - 2
10
- version: 0.0.2
10
+ version: 0.1.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Orion Henry
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-11-01 00:00:00 -07:00
18
+ date: 2010-11-23 00:00:00 -08:00
19
19
  default_executable: gaffer
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -32,6 +32,48 @@ dependencies:
32
32
  version: "0"
33
33
  type: :runtime
34
34
  version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: right_aws
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ type: :runtime
48
+ version_requirements: *id002
49
+ - !ruby/object:Gem::Dependency
50
+ name: bundler
51
+ prerelease: false
52
+ requirement: &id003 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ type: :runtime
62
+ version_requirements: *id003
63
+ - !ruby/object:Gem::Dependency
64
+ name: rush
65
+ prerelease: false
66
+ requirement: &id004 !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ hash: 3
72
+ segments:
73
+ - 0
74
+ version: "0"
75
+ type: :runtime
76
+ version_requirements: *id004
35
77
  description: Duct tape together some debian packages
36
78
  email: orion@heroku.com
37
79
  executables:
@@ -47,13 +89,14 @@ files:
47
89
  - lib/gaffer.rb
48
90
  - lib/gaffer/base.rb
49
91
  - lib/gaffer/deb.rb
92
+ - lib/gaffer/repro.rb
50
93
  has_rdoc: true
51
94
  homepage: http://github.com/orionz/gaffer
52
95
  licenses: []
53
96
 
54
97
  post_install_message:
55
- rdoc_options:
56
- - --charset=UTF-8
98
+ rdoc_options: []
99
+
57
100
  require_paths:
58
101
  - lib
59
102
  required_ruby_version: !ruby/object:Gem::Requirement