exctl 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.
@@ -0,0 +1,245 @@
1
+ #include <stdio.h>
2
+ #include <unistd.h>
3
+ #include <stdlib.h>
4
+ #include <string.h>
5
+ #include <sys/param.h>
6
+ #include <sys/stat.h>
7
+ #include <sys/types.h>
8
+ #include <fcntl.h>
9
+ #include <time.h>
10
+ #include <sys/time.h>
11
+ #include <errno.h>
12
+ #define GCC_VERSION (__GNUC__ * 10000 \
13
+ + __GNUC_MINOR__ * 100 \
14
+ + __GNUC_PATCHLEVEL__)
15
+ #if GCC_VERSION >= 40500
16
+ #define _unreachable() __builtin_unreachable()
17
+ #else
18
+ #define _unreachable() do { abort(); } while(0)
19
+ #endif
20
+ #define xstr(N) #N
21
+ #define str(N) xstr(N)
22
+ #define perr() perror("ERROR [line " str(__LINE__) "]")
23
+ #define snap() {perr(); exit(1);}
24
+ #define $(EXPR) if((EXPR) == -1) snap()
25
+ #define $j(EXPR) if((EXPR) == -1) {perr(); goto err;}
26
+
27
+ size_t quick_run(char **argv, char *buf, size_t max_len) {
28
+ int pfildes[2];
29
+ $( pipe(pfildes) );
30
+ int pid = vfork();
31
+ if(!pid) {
32
+ close (pfildes[0]);
33
+ dup2 (pfildes[1],1);
34
+ close (pfildes[1]);
35
+ execvp(argv[0], argv);
36
+ perr();
37
+ _exit(1);
38
+ } else $( pid );
39
+ close(pfildes[1]);
40
+ ssize_t size = read(pfildes[0], buf, max_len - 1);
41
+ $( size );
42
+ buf[size] = '\0';
43
+ close(pfildes[0]);
44
+ return (size_t)size;
45
+ }
46
+ #if 0
47
+ // Safer version of quick_run if I ever run into trouble...
48
+ size_t quick_run(const char *cmd) {
49
+ FILE *proc = popen(cmd, "r");
50
+ size_t size = fread(proc_output, sizeof(proc_output)-1, sizeof(char), proc);
51
+ proc_output[size-1] = '\0';
52
+ pclose(proc);
53
+ return size;
54
+ }
55
+ #endif
56
+
57
+
58
+ void get_last_dirty_modification_stamp(char *buf, size_t max_size) {
59
+ int cwd;
60
+ cwd = 0;
61
+ char *cmd_gitroot [] = {"git", "rev-parse", "--show-toplevel", NULL};
62
+ char *cmd_gitdirty[] = {"git", "status", "--porcelain", "-uno", "-z", NULL};
63
+ int pfildes[2];
64
+ $j( pipe(pfildes) );
65
+ int pid = fork();
66
+ if(!pid) {
67
+ close (pfildes[0]);
68
+ dup2 (pfildes[1],1);
69
+ close (pfildes[1]);
70
+ execvp(cmd_gitdirty[0], cmd_gitdirty);
71
+ perr ( );
72
+ _exit (1);
73
+ _unreachable();
74
+ } else $j( pid );
75
+ close(pfildes[1]);
76
+
77
+ char pathbuf[MAXPATHLEN + 5];
78
+ $j(cwd = open(".", O_RDONLY));
79
+ size_t pathlen = quick_run(cmd_gitroot, pathbuf, sizeof(pathbuf));
80
+ pathbuf[pathlen - 1] = '\0'; // chomp
81
+ $j(chdir(pathbuf));
82
+
83
+ FILE *cmd_res = fdopen(pfildes[0], "r");
84
+ if(cmd_res == NULL) $j(-1);
85
+
86
+ char *line = pathbuf;
87
+ size_t linecap = MAXPATHLEN + 5;
88
+ ssize_t linelen;
89
+ int ignore_one = 0;
90
+ time_t newest_change = 0;
91
+ while( (linelen = getdelim(&line, &linecap, 0, cmd_res)) > 0) {
92
+ if(ignore_one) {
93
+ ignore_one = 0;
94
+ continue;
95
+ }
96
+ if(linelen > 3) {
97
+ if (line[1] == 'M' || line[0] == 'M' ||
98
+ line[1] == 'A' || line[0] == 'A' ||
99
+ line[1] == 'R' || line[0] == 'R' ||
100
+ line[1] == 'C' || line[0] == 'C' ||
101
+ line[1] == 'U' || line[0] == 'U' ||
102
+ line[1] == 'S' || line[0] == 'S' ||
103
+ line[1] == '?' || line[0] == '?') {
104
+ // git never uses 'S'- but without it there is no... Marcus?
105
+ ignore_one = (line[1] == 'R' || line[0] == 'R');
106
+ struct stat fst;
107
+ if(stat(&(line[3]), &fst) == -1) {
108
+ if(errno == ENOENT) continue;
109
+ $j(-1);
110
+ }
111
+ #ifdef __linux__
112
+ if(fst.st_mtime > newest_change) newest_change = fst.st_mtime;
113
+ #else
114
+ if(fst.st_mtimespec.tv_sec > newest_change) newest_change = fst.st_mtimespec.tv_sec;
115
+ #endif
116
+ }
117
+ }
118
+ }
119
+
120
+ if(newest_change < 0) {
121
+ struct timeval tp;
122
+ gettimeofday(&tp, NULL);
123
+ newest_change = tp.tv_sec;
124
+ }
125
+ struct tm tmval;
126
+ gmtime_r(&(newest_change), &tmval);
127
+ strftime(buf, max_size-1, "d.%Y%m%d.%H%M%S",&tmval);
128
+
129
+ if(fchdir(cwd)){};
130
+ close(cwd);
131
+ fclose(cmd_res);
132
+ return;
133
+
134
+ err:
135
+ if(cwd) {
136
+ if(fchdir(cwd)){}
137
+ close(cwd);
138
+ }
139
+ exit(1);
140
+ }
141
+
142
+
143
+ #define adv(PCHR) while(*(PCHR) != '\0' && *(PCHR) != '-' && *(PCHR) != '\n'){(PCHR)++;} (PCHR)[0]='\0';(PCHR)++
144
+ #define pr(CONSTR) $(write(STDOUT_FILENO, CONSTR, sizeof(CONSTR)-1))
145
+ #define prs(BUF) $(write(STDOUT_FILENO, BUF, strnlen(BUF, 256)))
146
+ #define prl(BUF,LEN) $(write(STDOUT_FILENO, BUF, LEN))
147
+
148
+ int main(int argc, char **argv) {
149
+ int i;
150
+ int is_dirty;
151
+
152
+ // Commands
153
+ char *cmd_gitdesc[] = {"git","describe", "--match", "v[0-9.]*", "--dirty", "--long", "--always", NULL};
154
+
155
+ // Some constants and buffers
156
+ char describe_res [256] = {0};
157
+ char default_vmajor[] = "v0.0.0";
158
+ char default_vnumc [] = "0";
159
+ char unknown_vnumc [] = "u";
160
+ char dirty_is_true [32] = {0};
161
+ char dirty_is_false[] = "c";
162
+
163
+ // Destination strings for various pieces.
164
+ char *vhash = NULL;
165
+ char *vmajor = NULL;
166
+ char *vdirty = dirty_is_false;
167
+ char *vnum_commits = unknown_vnumc;
168
+
169
+ quick_run(cmd_gitdesc, describe_res, sizeof(describe_res) - 5); // -5 for padding for parser below
170
+ char *p = describe_res;
171
+ if(*p == 'v') {
172
+ vmajor = p++; // Got git tag w/ version
173
+ adv(p); // Advance past & terminate vmajor
174
+ // Next will be either num_commits or hash
175
+ char *pstart = p;
176
+ while(1) {
177
+ if(*p == '-') {
178
+ vnum_commits = pstart;
179
+ adv(p);
180
+ vhash = p++;
181
+ break;
182
+ } else if(*p < '0' || *p > '9') {
183
+ vhash = pstart;
184
+ vnum_commits = default_vnumc;
185
+ break;
186
+ }
187
+ p++;
188
+ }
189
+ } else {
190
+ vmajor = default_vmajor; // No git tag with a version
191
+ vhash = describe_res; // But we've got the vhash- skip to dirty-check
192
+ // TODO: calculate vnum_commits. In Ruby I was doing it like this:
193
+ // > plus_commits = `git shortlog -s`.scan(/\d+/) # should cut name off first
194
+ // > plus_commits = plus_commits.map{|p| p.to_i}.reduce(:+)
195
+ }
196
+
197
+ adv(p); // Advance to the end of and terminate the vhash
198
+ is_dirty = p[1] == 'i';
199
+
200
+ if(is_dirty) {
201
+ vdirty = dirty_is_true;
202
+ get_last_dirty_modification_stamp(vdirty, sizeof(dirty_is_true));
203
+ }
204
+
205
+ if(argc == 1) {
206
+ // Strictly the version
207
+ prs(vmajor);
208
+ if(is_dirty || vnum_commits[0]!='0') {
209
+ //pr ("+build.");
210
+ pr ("+");
211
+ prs(vnum_commits); pr (".");
212
+ prs(vdirty); pr (".");
213
+ if(vhash[0] != 'g') pr ("g");
214
+ prs(vhash);
215
+ }
216
+ pr("\n");
217
+ } else {
218
+ char *cmd_gitbranch[] = {"git", "rev-parse", "--abbrev-ref", "HEAD", NULL};
219
+ char gitbr[256];
220
+ size_t gitbr_size = quick_run(cmd_gitbranch, gitbr, sizeof(gitbr));
221
+ gitbr[gitbr_size - 1] = '\0'; // chomp
222
+ for(i=1; i<argc; i++) {
223
+ int j=0;
224
+ while(argv[i][j] != 0) {
225
+ if(argv[i][j] > 0x60 && argv[i][j] < 0x7B) argv[i][j] -= 0x20;
226
+ j++;
227
+ }
228
+ // Define statements
229
+ pr("#define "); prl(argv[i],j); pr("_VERSION_MAJOR_STR \""); prs(vmajor); pr("\"\n");
230
+ pr("#define "); prl(argv[i],j); pr("_VERSION_BUILD_STR \"");
231
+ if(is_dirty || vnum_commits[0]!='0') {
232
+ //pr("+build.");
233
+ pr("+"); prs(vnum_commits); pr("."); prs(vdirty); pr(".");
234
+ if(vhash[0] != 'g') pr("g"); prs(vhash);
235
+ }
236
+ pr("\"\n");
237
+ pr("#define "); prl(argv[i],j); pr("_VERSION_DETAILS_STR_BRANCH \""); prs(gitbr); pr("\"\n");
238
+ pr("#define "); prl(argv[i],j); pr("_VERSION_DETAILS_STR_COMMIT \"");
239
+ (vhash[0] == 'g') ? ({prs(&(vhash[1]))}) : ({prs(vhash)});
240
+ pr("\"\n");
241
+ }
242
+ }
243
+
244
+ return 0;
245
+ }
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ # Add dependencies to develop your gem here.
7
+ # Include everything needed to run rake, tests, features, etc.
8
+ group :development do
9
+ gem "shoulda", ">= 0"
10
+ gem "rdoc", "~> 3.12"
11
+ gem "bundler", "~> 1.0"
12
+ gem "jeweler", "~> 1.8.7"
13
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,72 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ activesupport (4.0.1)
5
+ i18n (~> 0.6, >= 0.6.4)
6
+ minitest (~> 4.2)
7
+ multi_json (~> 1.3)
8
+ thread_safe (~> 0.1)
9
+ tzinfo (~> 0.3.37)
10
+ addressable (2.3.5)
11
+ atomic (1.1.14)
12
+ builder (3.2.2)
13
+ faraday (0.8.8)
14
+ multipart-post (~> 1.2.0)
15
+ git (1.2.6)
16
+ github_api (0.10.1)
17
+ addressable
18
+ faraday (~> 0.8.1)
19
+ hashie (>= 1.2)
20
+ multi_json (~> 1.4)
21
+ nokogiri (~> 1.5.2)
22
+ oauth2
23
+ hashie (2.0.5)
24
+ highline (1.6.20)
25
+ httpauth (0.2.0)
26
+ i18n (0.6.5)
27
+ jeweler (1.8.8)
28
+ builder
29
+ bundler (~> 1.0)
30
+ git (>= 1.2.5)
31
+ github_api (= 0.10.1)
32
+ highline (>= 1.6.15)
33
+ nokogiri (= 1.5.10)
34
+ rake
35
+ rdoc
36
+ json (1.8.1)
37
+ jwt (0.1.8)
38
+ multi_json (>= 1.5)
39
+ minitest (4.7.5)
40
+ multi_json (1.8.2)
41
+ multi_xml (0.5.5)
42
+ multipart-post (1.2.0)
43
+ nokogiri (1.5.10)
44
+ oauth2 (0.9.2)
45
+ faraday (~> 0.8)
46
+ httpauth (~> 0.2)
47
+ jwt (~> 0.1.4)
48
+ multi_json (~> 1.0)
49
+ multi_xml (~> 0.5)
50
+ rack (~> 1.2)
51
+ rack (1.5.2)
52
+ rake (10.1.0)
53
+ rdoc (3.12.2)
54
+ json (~> 1.4)
55
+ shoulda (3.5.0)
56
+ shoulda-context (~> 1.0, >= 1.0.1)
57
+ shoulda-matchers (>= 1.4.1, < 3.0)
58
+ shoulda-context (1.1.5)
59
+ shoulda-matchers (2.4.0)
60
+ activesupport (>= 3.0.0)
61
+ thread_safe (0.1.3)
62
+ atomic
63
+ tzinfo (0.3.38)
64
+
65
+ PLATFORMS
66
+ ruby
67
+
68
+ DEPENDENCIES
69
+ bundler (~> 1.0)
70
+ jeweler (~> 1.8.7)
71
+ rdoc (~> 3.12)
72
+ shoulda
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013 Joseph Wecker
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/OPERUM.md ADDED
@@ -0,0 +1,17 @@
1
+ - () for simplicity, just quickly gcc get-version if required when running
2
+ - () default tasks
3
+ - () (project)
4
+ - () version
5
+ - () version.bump {.major|.minor|.patch} # Defaults to patch
6
+ - ()
7
+
8
+ - () (iterate)
9
+ - () test
10
+ - ()
11
+
12
+ - () (deploy)
13
+ - () hotfix (... ?)
14
+ - () release
15
+ - () git tag with verion (or do that with bump instead and use '-...' build info until it's released?)
16
+ - () Also generates the reltools release etc.?
17
+ - ()
data/README.md ADDED
@@ -0,0 +1,17 @@
1
+ exctl
2
+ =====
3
+
4
+ Project-specific command dispatcher using DRY and convention-over-configuration principles as much as possible.
5
+
6
+ So for a given project you will be able to create a command heirarchy (think `git *` or `gem *`- now you can make
7
+ `my-project *`) with the ability to detect and document (for command-line help as well as manpages) new tasks etc.
8
+
9
+ This allows you to have development-related tasks, packaging/installing/deployment-related tasks, and of course
10
+ runtime tasks (such as running the application).
11
+
12
+ Why? Because I've reimplemented this so many times for specific projects that I'm finally abstracting it.
13
+
14
+ Copyright
15
+ ---------
16
+
17
+ Copyright (c) 2013 Joseph Wecker. See LICENSE for further details.
data/Rakefile ADDED
@@ -0,0 +1,45 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "exctl"
18
+ gem.homepage = "http://github.com/josephwecker/exctl"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{Project-specific command-line task dispatcher generator.}
21
+ gem.description = %Q{Allows you to create a command-line dispatcher for a project to consolidate dev, release, and runtime workflows.}
22
+ gem.email = "joseph.wecker@gmail.com"
23
+ gem.authors = ["Joseph Wecker"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ require 'rake/testtask'
29
+ Rake::TestTask.new(:test) do |test|
30
+ test.libs << 'lib' << 'test'
31
+ test.pattern = 'test/**/test_*.rb'
32
+ test.verbose = true
33
+ end
34
+
35
+ task :default => :test
36
+
37
+ require 'rdoc/task'
38
+ Rake::RDocTask.new do |rdoc|
39
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
40
+
41
+ rdoc.rdoc_dir = 'rdoc'
42
+ rdoc.title = "exctl #{version}"
43
+ rdoc.rdoc_files.include('README*')
44
+ rdoc.rdoc_files.include('lib/**/*.rb')
45
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
data/lib/exctl.rb ADDED
File without changes
data/notes.md ADDED
@@ -0,0 +1,107 @@
1
+
2
+
3
+ why?
4
+ ----
5
+
6
+ because I've done this over and over again:
7
+
8
+ - rake wrapper I did for jtv-web project (probably prettiest)
9
+ - imb- earlier metacon-like, then current dispatcher (most complete)
10
+ - quick command wrapper I did for fxsig
11
+ - metacon- bash version and start of C version
12
+ - some Proj stuff in shorthand
13
+ - lots of custom vim stuff that started to be a lot more project-aware
14
+ - I believe I might have even done one for zerl back in the day...
15
+ - not by me: rake, make, git, rebar, rvm, reltools output ctl script, most init.d type scripts...
16
+
17
+
18
+
19
+ meta-exctl
20
+ ---------
21
+ - initiate project
22
+ - set up initial directory structure
23
+ - eventually different depending on various templates (e.g., erlang-apps, ruby gem, etc.)
24
+ - local version of exctl files
25
+ - create shell wrapper that has project-specific invocation name etc.
26
+ - command for dumping information about the project - including known tasks etc.
27
+
28
+
29
+ aggregate features
30
+ ------------------
31
+
32
+ - (convention over configuration)
33
+ - quickly add and document external commands, scripts, code...
34
+ - wrap around and delegate to rake, rebar, mix, custom code, and/or standalone scripts/shell-commands
35
+ - dev/build tools integrated with / blended into server name
36
+ - families of (high-level) commands (ala git)
37
+ - families of commands (hierarchies- deps.get, db:create, ...)
38
+ - execute sequential commands
39
+ - default command (possibly contextual)
40
+ - commands with automatically triggered precondition commands
41
+ - semantic- explains itself, including most common / necessary commands (possibly contextual- i.e., build commands if it hasn't been built yet, run commands if it has, etc.)
42
+ - automatic manpage generation from same definitions?
43
+ - bash/zsh completion (automatically refreshed as necessary)
44
+ - very fast
45
+ - colored output
46
+ - default help, man, version (semantic & w/ git) commands
47
+ - allows for older style commandline args- at least expected gnu standards like -h, --help, -v, --version, etc.
48
+ - correctly manipulates environment variables before delegating
49
+ - @<env> environment shorthand
50
+ - always show environment except for possibly --version etc...
51
+ - default values
52
+ - post-format entered values
53
+ - allow for a configuration / environment / commandline-option option hierarchy
54
+ - multiple instances / servers / daemons running simultaneously and potentially aware of each other
55
+ - for compiled languages- make sure each environment has an isolated build target directory (including rel nodes for erlang, etc.)
56
+ - usually a fallback build method that is going to be expected by a maintainer
57
+
58
+ - tasks done "in the background" as much as possible- e.g., simply try to run the program and it will realize it needs
59
+ to compile the dev version first.
60
+
61
+ (and some new features)
62
+
63
+ - default 'status' command (long and short [for ps1 integration or something]) possibly plugin-able - git-state, build-state, coverage-state, running-instances, ...
64
+ - automatic environment detection- e.g., via hostname, cwd, whoami, etc.
65
+ - certain commands only allowed in certain environments
66
+ - good synchronity between git version / tags and erlang (etc.) releases
67
+
68
+
69
+ task families
70
+ --------------
71
+ interact with the project (bump, package, conformance-test, ...)
72
+ interact with the system / environment (deploy, start, stat, stop, ...)
73
+ interact with an instance of the application (upgrade, attach, test, ... environment-sensitive)
74
+
75
+ (
76
+ - local control (run, stop, attach, upgrade, downgrade, etc.- up/downgrade prefered to reload/restart)
77
+ - local testing, profiling, benchmarking, analyzing
78
+ - releasing, including integration, deployment, packaging, and release management
79
+ - project management (dependencies and submodules, ...)
80
+ )
81
+
82
+ (older misc notes)
83
+ -------------------
84
+
85
+
86
+
87
+ - Ability to have some kind of mock historical files for downloading during most tests
88
+ - test, dev, and prod all running on same machine without interfering with each other
89
+ -
90
+
91
+ - app-ctl tasks:
92
+ - init.d compatible:
93
+ - start
94
+ - stop
95
+ - restart
96
+ - try-restart (only restart if already running)
97
+ - reload
98
+ - force-reload
99
+ - status information on currently running app - maybe list showing available versions as well
100
+
101
+ - node controller:
102
+
103
+ - custom:
104
+ - help
105
+ - queued
106
+ -
107
+
data/test/helper.rb ADDED
@@ -0,0 +1,18 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'test/unit'
11
+ require 'shoulda'
12
+
13
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
15
+ require 'exctl'
16
+
17
+ class Test::Unit::TestCase
18
+ end
@@ -0,0 +1,7 @@
1
+ require 'helper'
2
+
3
+ class TestExctl < Test::Unit::TestCase
4
+ should "get some tests written" do
5
+ flunk "need to write some tests."
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,128 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: exctl
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Joseph Wecker
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-11-11 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: shoulda
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rdoc
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '3.12'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '3.12'
46
+ - !ruby/object:Gem::Dependency
47
+ name: bundler
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: '1.0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1.0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: jeweler
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: 1.8.7
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 1.8.7
78
+ description: Allows you to create a command-line dispatcher for a project to consolidate
79
+ dev, release, and runtime workflows.
80
+ email: joseph.wecker@gmail.com
81
+ executables: []
82
+ extensions: []
83
+ extra_rdoc_files:
84
+ - LICENSE
85
+ - README.md
86
+ files:
87
+ - .attic/c_src/get-version.c
88
+ - .document
89
+ - Gemfile
90
+ - Gemfile.lock
91
+ - LICENSE
92
+ - OPERUM.md
93
+ - README.md
94
+ - Rakefile
95
+ - VERSION
96
+ - lib/exctl.rb
97
+ - notes.md
98
+ - test/helper.rb
99
+ - test/test_exctl.rb
100
+ homepage: http://github.com/josephwecker/exctl
101
+ licenses:
102
+ - MIT
103
+ post_install_message:
104
+ rdoc_options: []
105
+ require_paths:
106
+ - lib
107
+ required_ruby_version: !ruby/object:Gem::Requirement
108
+ none: false
109
+ requirements:
110
+ - - ! '>='
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ segments:
114
+ - 0
115
+ hash: -3627039586448779554
116
+ required_rubygems_version: !ruby/object:Gem::Requirement
117
+ none: false
118
+ requirements:
119
+ - - ! '>='
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ requirements: []
123
+ rubyforge_project:
124
+ rubygems_version: 1.8.25
125
+ signing_key:
126
+ specification_version: 3
127
+ summary: Project-specific command-line task dispatcher generator.
128
+ test_files: []