org-converge 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/.gitmodules ADDED
@@ -0,0 +1,3 @@
1
+ [submodule "org-ruby"]
2
+ path = org-ruby
3
+ url = https://github.com/wallyqs/org-ruby
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ group :development, :test do
4
+ gem 'rake'
5
+ gem 'rspec'
6
+ end
7
+
8
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Waldemar Quevedo
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.org ADDED
@@ -0,0 +1,109 @@
1
+ # -*- mode: org; mode: auto-fill; -*-
2
+ #+TITLE: Org Converge
3
+ #+STARTUP: showeverything
4
+
5
+ * Description
6
+
7
+ This attempts to be an experiment of using Org mode syntax to
8
+ describe, configure and setting up something, borrowing some ideas
9
+ of what is possible to do with tools like =chef-solo=, =puppet=,
10
+ =ansible=, etc...
11
+
12
+ * Motivation
13
+
14
+ The Org babel syntax has proven to be flexible enough to produce
15
+ /reproducible research/ papers. Then, I believe that configuring and setting up
16
+ a server for example is something that could be also be done using
17
+ the same syntax, given that /converging/ the configuration is something
18
+ that one ought to be able to reproduce.
19
+
20
+ * Usage
21
+
22
+ : org-converge path/to/setup-file.org
23
+
24
+ * How it works
25
+
26
+ Org Converge uses an liberally extended version of Org Babel
27
+ features in order to give support for converging the configuration
28
+ of a server.
29
+
30
+ For example, using Org Babel and macros we can easily spread config
31
+ files on a server by writing the following on a ~server.org~ file.
32
+
33
+ #+begin_src org
34
+ ,#+MACRO: multitenancy_enabled true
35
+ ,#+MACRO: status_port true
36
+
37
+ ,#+begin_src yaml :tangle /etc/component.yml
38
+ multitenant: false
39
+ status_port: 10004
40
+ ,#+end_src
41
+ #+end_src
42
+
43
+ And then configure it by running it as follows, (considering we have
44
+ the correct permissions):
45
+
46
+ #+begin_src sh
47
+ org-converge server.org
48
+ #+end_src
49
+
50
+ This leverages on the syntax already provided by Org Babel, but one
51
+ difference here is that if we run it once again without changes...
52
+
53
+ #+begin_src sh
54
+ org-converge server.org
55
+ #+end_src
56
+
57
+ ...it would finish soon since the configuration has already converged.
58
+
59
+ Next, let's say that we no only one want to set the configured templates,
60
+ but that we also want to install some packages. In that case, we
61
+ should be able to do the following:
62
+
63
+ #+begin_src org
64
+ ,#+macro: multitenancy_enabled true
65
+ ,#+macro: status_port true
66
+ ,#+macro: project_path path/to/project
67
+
68
+ ,* Configuring the component
69
+
70
+ ,#+begin_src yaml :tangle /etc/component.yml
71
+ multitenant: false
72
+ status_port: 10004
73
+ ,#+end_src
74
+
75
+ ,* Installing the dependencies
76
+
77
+ Need the following so that ~bundle install~ can compile
78
+ the native extensions correctly.
79
+
80
+ ,#+begin_src sh
81
+ apt-get install build-essentials -y
82
+ ,#+end_src
83
+
84
+ Then the following should work:
85
+
86
+ ,#+begin_src sh
87
+ cd {{{project_path}}}
88
+ bundle install
89
+ ,#+end_src
90
+ #+end_src
91
+
92
+ As long as the repo has been already checked out in the directory,
93
+ the previous example will succeed.
94
+
95
+ #+begin_src sh
96
+ org-converge server.org
97
+ #+end_src
98
+
99
+ If that is not the case, then org-converge will fail
100
+ and pickup from that last step.
101
+
102
+ More practical examples can be found [[here]], more will be added as
103
+ long as dogfooding from this goes well.
104
+
105
+ * Contributing
106
+
107
+ The project is in very early development at this moment, but if you
108
+ feel that it is interesting enough, please create a ticket so start
109
+ the discussion.
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env rake
2
+ require 'bundler/gem_tasks'
3
+
4
+ require 'rspec/core'
5
+ require 'rspec/core/rake_task'
6
+
7
+ RSpec::Core::RakeTask.new(:spec) do |spec|
8
+ spec.pattern = FileList['spec/**/*_spec.rb']
9
+ spec.rspec_opts = ['--format', 'documentation', '--colour']
10
+ end
data/TODO ADDED
@@ -0,0 +1,167 @@
1
+ # -*- mode: org; mode: auto-fill; -*-
2
+ #+TODO: TODO | DONE CANCELED
3
+ #+startup: showeverything
4
+
5
+ * [0/2] 0.0.3 version
6
+
7
+ - [ ] Macros can be loaded and applied to the configuration
8
+ - [ ] Actually support converging and idempotency
9
+ + Do not do an operation unless it is required
10
+ + Abort in case there was a failure in executing the script.
11
+
12
+ * [0/2] 0.0.2 version
13
+
14
+ Run the code blocks!
15
+
16
+ - [ ] Code blocks are executed by default after tangling
17
+ Only when :shebang exists as an argument
18
+ - [ ] Display how the run would look like
19
+ : org-converge setupfile.org --dry-run
20
+
21
+ * [3/3] 0.0.1 version
22
+
23
+ Need some basic functionality of what Org babel offers first.
24
+
25
+ - [X] Display files that were captured with command
26
+ : org-converge setupfile.org --showfiles
27
+ - [X] ~:tangle~ puts the files in the correct path
28
+ - [X] ~--tangle~ flag
29
+ - [X] Support a root dir for when not running relative to the directory
30
+
31
+ * [2/14] Ideas
32
+ ** CANCELED We don't need to create the directories in most cases
33
+
34
+ Something like this is not required because the ~:tangle~ blocks
35
+ would create the necessary directories behind the scenes.
36
+
37
+ #+begin_src org
38
+ ,We need to prepare some directories for the configuration:
39
+
40
+ ,#+begin_src converge
41
+ ,mkdir -p etc/fluentd/config
42
+ ,#+end_src
43
+ #+end_src
44
+
45
+ ** CANCELED How to set the permissions from the directory from the file that is being tangled when it does not exists?
46
+
47
+ By default, this would be 0644, but we also need to specify the
48
+ user:group of it so the syntax would have to be:
49
+
50
+ #+begin_src conf :tangle etc/something/config/path :chmod 0664 :user td-agent :group
51
+ hmm dont't like this syntax for folders
52
+ #+end_src
53
+
54
+ Let's keep it simple and just use a babel block that shells out to create the directories
55
+ until I can think of something better.
56
+
57
+ ** TODO By default, it should use current dir for tangling
58
+ ** TODO Converging: Only do an operation when it didn't finish
59
+
60
+ Hence the name of the project
61
+
62
+ ** TODO For now we keep the indentation of the code blocks
63
+
64
+ The indentatin of the ~#+begin_src~ should always
65
+ be at the beginning of the file, not at the indentation
66
+ level from when the file was written in Org mode.
67
+
68
+ ** TODO We should have a whitelist of languages that can be executed and ignore everything
69
+
70
+ Under which heuristics or configuration should we decide which will be the
71
+ binary that should be used to execute the block? Specify with shebang?
72
+
73
+ - For now, unless shebang is specified it will be executed.
74
+ Then in the scripts buffer used ~index::shebang~ as a key.
75
+
76
+ ** TODO Setting permissions from a tangled file
77
+
78
+ It should be possible to tangle the files this way:
79
+
80
+ #+begin_src conf :tangle etc/something/config/path :chmod 0664 :user td-agent :group td-agent
81
+ <source>
82
+ </source>
83
+ #+end_src
84
+
85
+ ** TODO Adopting the ~#+SETUPFILE~ for loading a config that is done JSON or YAML
86
+
87
+ It seems that there is support for a ~#+SETUPFILE~
88
+
89
+ ** TODO Something more flexible than macros:
90
+
91
+ One example of syntax that we could use instead of macros:
92
+
93
+ #+begin_src yaml :session
94
+ fluentd:
95
+ port: 4224
96
+ path: here.log
97
+ #+end_src
98
+
99
+ But need to
100
+
101
+ ** TODO Using the :tags: to setup the things to run right away
102
+
103
+ Kind of like the chef-solo runlist, a headline like this...
104
+
105
+ #+begin_src org
106
+ ,* Everything in its right place :config:
107
+
108
+ ,#+begin_src conf :tangle etc/this.yml
109
+ ,hello: "world"
110
+ ,#+end_src
111
+ #+end_src
112
+
113
+ ...could be called like this
114
+
115
+ #+begin_src sh
116
+ org-converge fluentd.org -t config
117
+ #+end_src
118
+
119
+ ** TODO Managing dependencies: could be handled with ~#+include~ directives
120
+
121
+ One idea is that it would be useful to compile different manuals
122
+ that are dependent among each other.
123
+
124
+ For example, the centralized logs server would require fluentd.
125
+ We should be able to express that dependency somehow:
126
+
127
+ #+begin_src org :tangle logserver.org
128
+ ,#+include: "fluentd.org"
129
+
130
+ ,* Setup the centralized logserver :setup:
131
+
132
+ ,Once the fluentd.org has been converged, we can build upon this and
133
+ ,override the original config to make it particular for this logserver
134
+ #+end_src
135
+
136
+ # But one problem, is that once I have included something, sometimes we
137
+ # will want "reopen" the previous manuals?
138
+
139
+ ** TODO Loading all the Org mode files first and then setup only one part
140
+
141
+ So maybe, each one of these tags would have to be namespaces under the
142
+ name of the file:
143
+
144
+ : org-converge logserver.org -t "fluentd::setup, fluentd::config, logserver::setup"
145
+
146
+ ** TODO Choosing a templating language: default for now is mustache
147
+
148
+ We could implement the macro systems, but it seems that it may not be
149
+ strong enough for providing with all the cases we may run into.
150
+
151
+ ** TODO Chaining resources with ~#+NAME:~ directives and ~:notify~ argument
152
+
153
+ One idea is to be able to notify resources by naming the code blocks.
154
+
155
+ Example: Here first the td-agent service would try to start,
156
+ and if it succeeds, then it would execute the script defined in the
157
+ ~announce-availability~ resource.
158
+
159
+ #+name: td-agent-start
160
+ #+begin_src sh :notify announce-availability
161
+ sudo service td-agent start
162
+ #+end_src
163
+
164
+ #+name: announce-availability
165
+ #+begin_src sh
166
+ sudo /etc/register-to-balancer
167
+ #+end_src
data/bin/org-converge ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- mode: ruby -*-
3
+ require 'docopt'
4
+ require 'org-converge'
5
+
6
+ doc = <<OPTIONS
7
+
8
+ org-converge: A light configuration management tool for Org mode
9
+
10
+ Usage:
11
+ org-converge <org_file> [--tangle] [--showfiles] [--log=<logfile>] [--root-dir=<root_dir>]
12
+
13
+ Options:
14
+
15
+ -h --help Show this screen.
16
+
17
+ OPTIONS
18
+
19
+ begin
20
+ require "pp"
21
+ cmd = Docopt::docopt(doc)
22
+ rescue Docopt::Exit => e
23
+ puts e.message
24
+ end
25
+
26
+ exit 1 unless cmd
27
+
28
+ o = OrgConverge::Command.new(cmd)
29
+ o.execute!
@@ -0,0 +1,11 @@
1
+ #+TITLE: Installing some packages
2
+
3
+ * Just install some packages for example
4
+
5
+ #+begin_src sh
6
+ sudo apt-get install build-essentials
7
+ #+end_src
8
+
9
+ Should be able to be run with something like:
10
+
11
+ : org-converge examples/apt-get-install.org
@@ -0,0 +1,50 @@
1
+ # -*- mode: org; auto-fill-mode -*-
2
+ #+TITLE: Setting up Fluentd
3
+ #+startup: showeverything
4
+
5
+ * Introduction
6
+
7
+ The following will setup and configure ~fluentd~ on a node.
8
+
9
+ * Settings
10
+
11
+ These can be defined with Org mode macro directives, but thinking on
12
+ other ways to do it as well.
13
+
14
+ #+macro: fluentd_port 4224
15
+ #+macro: fluentd_filepath here.log
16
+
17
+ * Setup :setup:
18
+
19
+ Fluentd can be installed either as a package from treasure data or
20
+ just as a gem. In this example, we only install as a gem:
21
+
22
+ #+begin_src sh
23
+ gem install fluentd
24
+ #+end_src
25
+
26
+ * Configuration :config:
27
+
28
+ Set Fluentd to listen on the ~fluentd_port~ port and to write logs
29
+ to ~fluentd_filepath~.
30
+
31
+ #+begin_src conf :tangle etc/fluentd.conf
32
+ <source>
33
+ type forward
34
+ port {{{ fluentd_port }}}
35
+ </source>
36
+
37
+ <match **>
38
+ type file
39
+ path {{{ fluentd_filepath }}}
40
+ </match>
41
+ #+end_src
42
+
43
+ # A script to daemonize the process could be written here, as well as
44
+ # any /etc/default/* required settings...
45
+
46
+ * Start which was configured here :start:
47
+
48
+ #+begin_src sh
49
+ fluentd -c etc/fluentd.conf -vvv
50
+ #+end_src
@@ -0,0 +1,14 @@
1
+ #+TITLE: Using macros for configuration
2
+
3
+ #+macro: hello world
4
+ #+macro: application my-application
5
+
6
+ Hello {{{hello}}}, this will setup something for {{{application}}}.
7
+
8
+ #+begin_src sh :results output
9
+ echo "Hello for {{{application}}}" > /tmp/hello
10
+ #+end_src
11
+
12
+ #+RESULTS:
13
+ : Hello for {{{application}}}
14
+
@@ -0,0 +1,51 @@
1
+ #+TITLE: Simple example
2
+
3
+ It does not get more simple than this:
4
+
5
+ - First, configure something:
6
+
7
+ #+begin_src conf :tangle /tmp/my-conf
8
+ <source>
9
+ bind 0.0.0.0
10
+
11
+
12
+
13
+ port 4224
14
+
15
+
16
+
17
+
18
+ </source>
19
+
20
+ <match **>
21
+ type file
22
+
23
+
24
+ path /var/tmp/a.log
25
+ </match>
26
+ #+end_src
27
+
28
+ - And then run something
29
+
30
+ #+begin_src sh
31
+ echo "1) Hello world" > /tmp/my-echo
32
+ echo "2) Hello world" > /tmp/my-echo
33
+ echo "3) Hello world" > /tmp/my-echo
34
+ #+end_src
35
+
36
+ - Then configure something again
37
+
38
+ #+begin_src sh
39
+ echo "4) Hello world" >> /tmp/my-echo
40
+ echo "5) Hello world" >> /tmp/my-echo
41
+ echo "6) Hello world" >> /tmp/my-echo
42
+
43
+ echo "7) Hello world" >> /tmp/my-echo
44
+ #+end_src
45
+
46
+ - And send something to babel once again
47
+
48
+ #+begin_src conf :tangle /tmp/hello-conf.yml
49
+ status_port: 9090
50
+ no_tab_after_that: true
51
+ #+end_src
@@ -0,0 +1,60 @@
1
+ #
2
+ # Class with util methods that try to reimplement some of
3
+ # the functionality provided by Org Babel from Emacs
4
+ #
5
+ require 'fileutils'
6
+
7
+ module Orgmode
8
+ class Babel
9
+ attr_reader :ob # Babel Output Buffer with parsed contents
10
+ attr_reader :logger
11
+
12
+ def initialize(babel_output_buffer, options={})
13
+ @ob = babel_output_buffer
14
+ @options = options
15
+ @logger = options[:logger] || Logger.new(STDOUT)
16
+ @root_dir = options[:root_dir]
17
+ end
18
+
19
+ # TODO: should be able to tangle relatively to a dir
20
+ def tangle!
21
+ logger.info "Tangling #{ob.tangle.keys.count} files..."
22
+
23
+ ob.tangle.each do |tangle_file, lines|
24
+ file = if @root_dir
25
+ File.join(@root_dir, tangle_file)
26
+ else
27
+ tangle_file
28
+ end
29
+
30
+ logger.info "BEGIN(#{tangle_file}): Tangling #{lines.count} lines at '#{file}'"
31
+ # TODO: should abort when the directory does not exists
32
+ # TODO: should abort when the directory failed because of permissions
33
+ if not Dir.exists?(File.dirname(file))
34
+ logger.error "Could not tangle #{file} because directory does not exists!"
35
+ raise TangleError
36
+ end
37
+
38
+ if File.exists?(file)
39
+ logger.warn "File already exists at #{file}, it will be overwritten"
40
+ end
41
+
42
+ begin
43
+ File.open(file, 'w') do |f|
44
+ lines.each do |line|
45
+ f.puts line
46
+ end
47
+ end
48
+ rescue => e
49
+ logger.error "Problem while writing to '#{file}': #{e}"
50
+ raise TangleError
51
+ end
52
+ logger.info "END(#{file}): done."
53
+ end
54
+
55
+ logger.info "Tangling succeeded!".green
56
+ end
57
+
58
+ class TangleError < Exception; end
59
+ end
60
+ end
@@ -0,0 +1,82 @@
1
+ module Orgmode
2
+ class BabelOutputBuffer < OutputBuffer
3
+ attr_reader :tangle
4
+ attr_reader :scripts
5
+
6
+ def initialize(output)
7
+ super(output)
8
+
9
+ # ~@tangle~ files are put in the right path
10
+ # : @tangle['/path'] = [Lines]
11
+ @tangle = Hash.new {|h,k| h[k] = []}
12
+
13
+ # ~@scripts~ are tangled in order and ran
14
+ # : @scripts = [text, text, ...]
15
+ @scripts = []
16
+
17
+ @buffer = ''
18
+ end
19
+
20
+ def push_mode(mode, indent)
21
+ super(mode, indent)
22
+ end
23
+
24
+ def pop_mode(mode = nil)
25
+ m = super(mode)
26
+ @list_indent_stack.pop
27
+ m
28
+ end
29
+
30
+ def insert(line)
31
+ # We try to get the lang from #+BEGIN_SRC blocks
32
+ if line.begin_block?
33
+ @block_lang = line.block_lang
34
+ if line.block_header_arguments[':tangle']
35
+ @current_tangle = line.block_header_arguments[':tangle']
36
+ else
37
+ @shebang = line.block_header_arguments[':shebang']
38
+ @current_tangle = nil
39
+ @buffer = ''
40
+ end
41
+ end
42
+
43
+ case
44
+ when (line.assigned_paragraph_type == :code and @current_tangle)
45
+ # Need to keep track of the current tangle to buffer its lines
46
+ @tangle[@current_tangle] << line
47
+ when (line.assigned_paragraph_type == :code)
48
+ # When a tangle is not going on, it means that the lines would go
49
+ # into a runnable script
50
+ @buffer << line.output_text << "\n"
51
+ when (!@buffer.empty? and not (line.begin_block? or line.assigned_paragraph_type == :code))
52
+ # Fix indentation and remove pre fix commas from Org mode before flushing
53
+ strip_code_block!
54
+ @scripts << @buffer
55
+ @buffer = ''
56
+ end
57
+
58
+ @output_type = line.assigned_paragraph_type || line.paragraph_type
59
+ end
60
+
61
+ # Flushing is a bit different since we still need the metadata
62
+ # from lines in order to flush to correct tangle buffer
63
+ # TODO: Should be in the parent class as well...
64
+ def flush!; false; end
65
+
66
+ # TODO: This should be in the parent class....
67
+ def output_footnotes!; false; end
68
+
69
+ def strip_code_block!
70
+ if @code_block_indent and @code_block_indent > 0
71
+ strip_regexp = Regexp.new("^" + " " * @code_block_indent)
72
+ @buffer.gsub!(strip_regexp, "")
73
+ end
74
+ @code_block_indent = nil
75
+
76
+ # Strip proctective commas generated by Org mode (C-c ')
77
+ @buffer.gsub! /^(\s*)(,)(\s*)([*]|#\+)/ do |match|
78
+ "#{$1}#{$3}#{$4}"
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,58 @@
1
+ module OrgConverge
2
+ class Command
3
+ attr_reader :dotorg
4
+ attr_reader :logger
5
+ attr_reader :ob
6
+
7
+ def initialize(options)
8
+ @options = options
9
+ @dotorg = options['<org_file>']
10
+ @logger = Logger.new(options['--log'] || STDOUT)
11
+ @root_dir = options['--root-dir']
12
+ @ob = Orgmode::Parser.new(File.read(dotorg)).babelize
13
+ end
14
+
15
+ def execute!
16
+ case
17
+ when @options['--showfiles']
18
+
19
+ showfiles
20
+ when @options['--tangle']
21
+ tangle!
22
+ else
23
+ converge!
24
+ end
25
+
26
+ true
27
+ rescue => e
28
+ false
29
+ end
30
+
31
+ def converge!
32
+ tangle!
33
+ end
34
+
35
+ def tangle!
36
+ begin
37
+ babel = Orgmode::Babel.new(ob, { :logger => logger, :root_dir => @root_dir })
38
+ results = babel.tangle!
39
+ rescue Orgmode::Babel::TangleError
40
+ logger.error "Cannot converge because there were errors during tangle step".red
41
+ end
42
+ end
43
+
44
+ def showfiles
45
+ ob.tangle.each do |file, lines|
46
+ puts "---------- #{file} --------------".green
47
+ lines.each do |line|
48
+ puts line
49
+ end
50
+ end
51
+
52
+ ob.scripts.each_with_index do |script, index|
53
+ puts "---------- script: #{index} --------------".green
54
+ puts script
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,3 @@
1
+ module OrgConverge
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,37 @@
1
+ require 'org-ruby'
2
+ require 'org-converge/babel_output_buffer'
3
+ require 'org-converge/babel'
4
+ require 'org-converge/command'
5
+ require 'org-converge/version'
6
+
7
+ module Orgmode
8
+ class Parser
9
+
10
+ # This would return a babel output buffer which has the methods
11
+ # needed in order to be able to tangle the files
12
+ def babelize
13
+ # Feed the parsed contens and create the necessary internal structures
14
+ # for doing babel like features
15
+ output = ''
16
+ ob = BabelOutputBuffer.new(output)
17
+ translate(@header_lines, ob)
18
+ @headlines.each do |headline|
19
+ translate(headline.body_lines, ob)
20
+ end
21
+
22
+ ob
23
+ end
24
+ end
25
+ end
26
+
27
+ module StringWithColors
28
+ def red; colorize("\e[0m\e[31m"); end
29
+ def green; colorize("\e[0m\e[32m"); end
30
+ def yellow; colorize("\e[0m\e[33m"); end
31
+ def bold; colorize("\e[0m\e[1m"); end
32
+ def colorize(color_code); "#{color_code}#{self}\e[0m"; end
33
+ end
34
+
35
+ class String
36
+ include StringWithColors
37
+ end
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/org-converge/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Waldemar Quevedo"]
6
+ gem.email = ["waldemar.quevedo@gmail.com"]
7
+ gem.description = %q{A light configuration management tool for Org mode}
8
+ gem.summary = %q{Provides an 'org-converge' command which can be used for tangling and running Org mode code blocks}
9
+ gem.homepage = "https://github.com/wallyqs/org-converge"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "org-converge"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = OrgConverge::VERSION
17
+ gem.add_runtime_dependency('docopt', '0.5.0')
18
+ gem.add_runtime_dependency('org-ruby', '~> 0.9.2')
19
+ end
@@ -0,0 +1,7 @@
1
+ bind: 0.0.0.0
2
+ port: 2442
3
+
4
+ mysql:
5
+ db: users
6
+ host: somewhere-example.local
7
+ password: 111111111
@@ -0,0 +1,18 @@
1
+ #+TITLE: Relative Tangle
2
+
3
+ In this test, tangles files will exist relative to this file.
4
+
5
+ #+begin_src yaml :tangle conf.yml
6
+ bind: 0.0.0.0
7
+ port: 2442
8
+ #+end_src
9
+
10
+ e.g. including the connections to the database in the same file:
11
+
12
+ #+begin_src yaml :tangle conf.yml
13
+
14
+ mysql:
15
+ db: users
16
+ host: somewhere-example.local
17
+ password: 111111111
18
+ #+end_src
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ describe OrgConverge::Command do
4
+ context "when converging 'basic_tangle'" do
5
+ example_dir = File.join(EXAMPLES_DIR, 'basic_tangle')
6
+
7
+ it "should tangle a 'conf.yml' file" do
8
+ setup_file = File.join(example_dir, 'setup.org')
9
+ o = OrgConverge::Command.new({
10
+ '<org_file>' => setup_file,
11
+ '--root-dir' => example_dir
12
+ })
13
+ success = o.execute!
14
+ success.should == true
15
+
16
+ expected_contents = File.read(File.join(example_dir, 'conf.yml.expected'))
17
+
18
+ resulting_file = File.join(example_dir, 'conf.yml')
19
+ File.exists?(resulting_file).should == true
20
+
21
+ result = File.read(resulting_file)
22
+
23
+ result.should == expected_contents
24
+ end
25
+ end
26
+ end
27
+
28
+
@@ -0,0 +1,6 @@
1
+ require 'org-converge'
2
+ require 'fileutils'
3
+
4
+ RESULTS_DIR = File.expand_path("tmp/#{Time.now.strftime("test_%s")}", File.dirname(__FILE__))
5
+ SPEC_DIR = File.dirname(File.expand_path('.', __FILE__))
6
+ EXAMPLES_DIR = File.join(SPEC_DIR, 'converge_examples')
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: org-converge
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Waldemar Quevedo
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-03-23 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: docopt
16
+ requirement: &70317759431040 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - =
20
+ - !ruby/object:Gem::Version
21
+ version: 0.5.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70317759431040
25
+ - !ruby/object:Gem::Dependency
26
+ name: org-ruby
27
+ requirement: &70317759430520 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 0.9.2
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70317759430520
36
+ description: A light configuration management tool for Org mode
37
+ email:
38
+ - waldemar.quevedo@gmail.com
39
+ executables:
40
+ - org-converge
41
+ extensions: []
42
+ extra_rdoc_files: []
43
+ files:
44
+ - .gitmodules
45
+ - Gemfile
46
+ - LICENSE
47
+ - README.org
48
+ - Rakefile
49
+ - TODO
50
+ - bin/org-converge
51
+ - examples/apt-get-install/setup.org
52
+ - examples/fluentd/setup.org
53
+ - examples/macro-config/setup.org
54
+ - examples/simple/setup.org
55
+ - lib/org-converge.rb
56
+ - lib/org-converge/babel.rb
57
+ - lib/org-converge/babel_output_buffer.rb
58
+ - lib/org-converge/command.rb
59
+ - lib/org-converge/version.rb
60
+ - org-converge.gemspec
61
+ - spec/converge_examples/basic_tangle/conf.yml.expected
62
+ - spec/converge_examples/basic_tangle/setup.org
63
+ - spec/converge_spec.rb
64
+ - spec/spec_helper.rb
65
+ homepage: https://github.com/wallyqs/org-converge
66
+ licenses: []
67
+ post_install_message:
68
+ rdoc_options: []
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ none: false
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ requirements: []
84
+ rubyforge_project:
85
+ rubygems_version: 1.8.10
86
+ signing_key:
87
+ specification_version: 3
88
+ summary: Provides an 'org-converge' command which can be used for tangling and running
89
+ Org mode code blocks
90
+ test_files:
91
+ - spec/converge_examples/basic_tangle/conf.yml.expected
92
+ - spec/converge_examples/basic_tangle/setup.org
93
+ - spec/converge_spec.rb
94
+ - spec/spec_helper.rb