cide 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 (5) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +52 -0
  3. data/bin/cide +146 -0
  4. data/cide.gemspec +19 -0
  5. metadata +49 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f8b7306c43d5aaabf79afd1e12b0a1eae76589e4
4
+ data.tar.gz: 7aa28b61d7eb8c89c1a8c039fdc3f4e02be2b669
5
+ SHA512:
6
+ metadata.gz: 4e69fc8cb1ea540a41b2e50235c3789a6c21e5c8bec795358fcbceb0d00284dcea468459a5337cb0e315365510a4eea1bef7e466fcc7dad1506606f703227a57
7
+ data.tar.gz: 0e909b70f7e562466500aa5aebd7d261b8d549a8878eff8f677375088d9acc813fbe279200865cf3e31a4f0047bbf912a6b6b6d13042a828c487d9aa86ef61e2
data/README.md ADDED
@@ -0,0 +1,52 @@
1
+ cide - Continuous Integration Docker Environment
2
+ ================================================
3
+
4
+ `cide` makes it easy to reproduce CI builds on the developer computer by
5
+ providing the same docker environment.
6
+
7
+ Run `cide` in the project root to run a build. Configure by providing a
8
+ `.cide.yml` file.
9
+
10
+ Usage
11
+ -----
12
+
13
+ Just run `cide` inside of your project. cide will look for a .cide.yml file
14
+ for configuration but all arguments are also passable trough command-line
15
+ arguments. If a Dockerfile already exists it will be used instead.
16
+
17
+ Example
18
+ -------
19
+
20
+ `.cide.yml`
21
+ ```
22
+ ---
23
+ image: "ruby:2.1"
24
+ as_root:
25
+ - apt-get update -qy && apt-get install -qy libxml2-dev
26
+ command: bundle && bundle exec rspec
27
+ ```
28
+
29
+ Features
30
+ --------
31
+
32
+ * straighforward to use, just run `cide` inside of your project
33
+ * works on OSX with boot2docker
34
+ * integrates easily with jenkins or other CI systems
35
+
36
+ Limitations
37
+ -----------
38
+
39
+ A temporary Dockerfile has to be created in the project's root because docker
40
+ doesn't allow referencing files outside of the directory (even with a symlink)
41
+
42
+ TODO
43
+ ----
44
+
45
+ * schema validation
46
+ * use the /cache volume
47
+ * multi-container runs
48
+ * `cide setup` to configure inside of a project
49
+ * `cide gc` to cleanup old cide builds
50
+ * travis.yml compatiblity with docker containers that map to languages
51
+ * add ways of exporting artifacts
52
+ * ENV GEM_HOME is container specific
data/bin/cide ADDED
@@ -0,0 +1,146 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # cide - Continuous Integration Docker Environment
4
+ #
5
+
6
+ require "erb"
7
+ require "optparse"
8
+ require "yaml"
9
+
10
+ module Fmt; extend self
11
+ def fmt(obj)
12
+ dump_obj(obj)
13
+ end
14
+
15
+ protected
16
+
17
+ def dump(obj)
18
+ case obj
19
+ when Array
20
+ "[" + obj.map{|v| dump v}.join(' ') + "]"
21
+ when Hash
22
+ "{" + dump_obj(obj) + "}"
23
+ else
24
+ obj = obj.to_s
25
+ obj.index(/['"\s\{\}\[\]\=]/) ? obj.inspect : obj
26
+ end
27
+ rescue
28
+ dump($!.to_s)
29
+ end
30
+
31
+ def dump_obj(obj)
32
+ obj.map do |(k, v)|
33
+ "#{k}=#{dump v}"
34
+ end.join(' ')
35
+ end
36
+ end
37
+
38
+ def log(opts={})
39
+ $stdout.puts "cide: #{Fmt.fmt opts}"
40
+ end
41
+
42
+ def struct(opts={})
43
+ Class.new(Struct.new(*opts.keys)) do
44
+ def set(name)
45
+ method("#{name}=")
46
+ end
47
+
48
+ def to_dockerfile
49
+ ERB.new(DATA.read).result(binding)
50
+ end
51
+
52
+ def merge!(opts={})
53
+ opts.each_pair{|k,v| self[k] = v }
54
+ end
55
+ end.new(*opts.values)
56
+ end
57
+
58
+ # Replaces invalid docker tag characters by underscores
59
+ def id(str)
60
+ "#{str}".downcase.gsub(/[^a-z0-9\-_.]/, '_')
61
+ end
62
+
63
+ def sh(*args)
64
+ log cmd: args
65
+ unless system(*args.map(&:to_s))
66
+ fail "command failed"
67
+ end
68
+ end
69
+
70
+ def docker(*args)
71
+ sh "docker", *args
72
+ end
73
+
74
+ config = struct(
75
+ image: "ubuntu",
76
+ tag: id(File.basename(Dir.pwd)),
77
+ as_root: [],
78
+ command: 'script/ci',
79
+ )
80
+
81
+ CIDEFILE = '.cide.yml'
82
+ if !File.exists?(CIDEFILE)
83
+ log reason: "not found", file: CIDEFILE
84
+ else
85
+ config.merge! YAML.load_file(CIDEFILE)
86
+ end
87
+
88
+ OptionParser.new do |opts|
89
+ opts.on('-i', '--image IMAGE', "Select the source image (#{config.image})", &config.set(:image))
90
+ opts.on('-t', '--tag TAG', "Name of the build (#{config.tag})", &config.set(:tag))
91
+ opts.on('-c', '--command CMD', "CI script to run (#{config.command})", &config.set(:command))
92
+ opts.on_tail('-h', '--help', 'Shows this help') do
93
+ puts opts
94
+ exit
95
+ end
96
+ end.parse!
97
+
98
+ config.tag = id("cide-#{config.tag}")
99
+
100
+ log config: config.to_h
101
+
102
+ if !File.exist?('Dockerfile')
103
+ log msg: "Creating temporary Dockerfile"
104
+ File.write('Dockerfile', config.to_dockerfile)
105
+ at_exit do
106
+ File.unlink('Dockerfile')
107
+ end
108
+ else
109
+ log msg: "Using existing Dockerfile"
110
+ end
111
+
112
+ if `uname`.strip == "Darwin" && !ENV['DOCKER_HOST']
113
+ if !system("which boot2docker >/dev/null 2>&1")
114
+ puts "make sure boot2docker is installed and running"
115
+ puts
116
+ puts "> brew install boot2docker"
117
+ exit 1
118
+ end
119
+ ENV['DOCKER_HOST'] = `boot2docker socket 2>/dev/null`.strip
120
+ end
121
+
122
+ docker :build, '-t', config.tag, '.'
123
+ docker :run, '--rm', '-t', config.tag, "sh", "-c", config.command
124
+
125
+ __END__
126
+ FROM <%= image %>
127
+ RUN useradd -m -U -d /cide cide
128
+
129
+ # Install system build dependencies here
130
+
131
+ <% as_root.each do |cmd| %>
132
+ RUN <%= cmd %>
133
+ <% end %>
134
+
135
+ # Add project data
136
+
137
+ ADD . /cide/src
138
+ RUN chown -R cide:cide /cide
139
+
140
+ # Switch to cide user
141
+
142
+ USER cide
143
+
144
+ WORKDIR /cide/src
145
+ ENV HOME /cide
146
+ ENV GEM_HOME /cide/.gem
data/cide.gemspec ADDED
@@ -0,0 +1,19 @@
1
+ # coding: utf-8
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = 'cide'
5
+ s.version = '0.0.1'
6
+ s.authors = ['zimbatm']
7
+ s.email = ['zimbatm@zimbatm.com']
8
+ s.summary = 'CI docker runner'
9
+ s.description = <<DESC
10
+ cide makes it easy to reproduce CI builds on the developer computer by
11
+ providing the same docker environment.
12
+ DESC
13
+ s.homepage = 'https://github.com/zimbatm/cide'
14
+ s.license = 'MIT'
15
+
16
+ s.files = `git ls-files`.split($/)
17
+ s.test_files = `git ls-files spec`.split($/)
18
+ s.require_paths = ['lib']
19
+ end
metadata ADDED
@@ -0,0 +1,49 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cide
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - zimbatm
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-09-13 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: |
14
+ cide makes it easy to reproduce CI builds on the developer computer by
15
+ providing the same docker environment.
16
+ email:
17
+ - zimbatm@zimbatm.com
18
+ executables: []
19
+ extensions: []
20
+ extra_rdoc_files: []
21
+ files:
22
+ - README.md
23
+ - bin/cide
24
+ - cide.gemspec
25
+ homepage: https://github.com/zimbatm/cide
26
+ licenses:
27
+ - MIT
28
+ metadata: {}
29
+ post_install_message:
30
+ rdoc_options: []
31
+ require_paths:
32
+ - lib
33
+ required_ruby_version: !ruby/object:Gem::Requirement
34
+ requirements:
35
+ - - '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ required_rubygems_version: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - '>='
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ requirements: []
44
+ rubyforge_project:
45
+ rubygems_version: 2.0.14
46
+ signing_key:
47
+ specification_version: 4
48
+ summary: CI docker runner
49
+ test_files: []