core_x 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gemspec.gemspec +31 -0
- data/.gemspec_utils.rb +82 -0
- data/.gitignore +20 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSES/MIT +20 -0
- data/README.md +94 -0
- data/Rakefile +120 -0
- data/TESTING.md +28 -0
- data/VERSIONING.md +18 -0
- data/bin/camelCase +16 -0
- data/bin/snake_case +16 -0
- data/exe/bash_import.sh +3 -0
- data/exe/console +13 -0
- data/exe/find_root +51 -0
- data/exe/pty_run +14 -0
- data/exe/setup +7 -0
- data/exe/test_stats_collector.sh +19 -0
- data/exe/version.rb +3 -0
- data/exe/watch +4 -0
- data/gemspec.gemspec +31 -0
- data/gemspec_boilerplate.rb +32 -0
- data/lib/core_x.rb +5 -0
- data/lib/core_x/string.rb +71 -0
- data/lib/core_x/string/import.rb +5 -0
- data/lib/core_x/version.rb +4 -0
- data/spec/.rspec +2 -0
- data/spec/spec_helper.rb +4 -0
- metadata +185 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 495a1c900bf2e6d381a75fcf117991bab1b3d879
|
4
|
+
data.tar.gz: 1e74e863880e70b29b2eda4fbb13955dd7cbac8a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e4ac0b748c7ffa1b271d52ec6d4563cd44cc0013b1b873c2e5bddbbc59a56d6ea2588936306b95d92e0eeb81ff5392f5601ab060cabaf398b3bc90e428170226
|
7
|
+
data.tar.gz: 5bcf0f33be2c16b14cc2d87b02d7b1fabb8e7796ff9f269107599b730d5fb0e532ac24d3778c6b2378a6e01e56b239ef0fea176648e44e939bb25b7dbbd4e4c3
|
data/.gemspec.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require_relative 'gemspec_boilerplate'
|
4
|
+
|
5
|
+
spec = Gem::Specification.new do |s|
|
6
|
+
|
7
|
+
GemspecBoilerplate.boilerplate(s)
|
8
|
+
|
9
|
+
#s.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com' to prevent pushes to rubygems.org, or delete to allow pushes to any server."
|
10
|
+
|
11
|
+
#####Must change
|
12
|
+
s.summary = %q{Mixins to extend the core with}
|
13
|
+
s.description = s.summary
|
14
|
+
s.licenses = %w[mit]
|
15
|
+
|
16
|
+
|
17
|
+
#####Unlikely to change
|
18
|
+
s.email = [ `git config user.email` ]
|
19
|
+
s.homepage = "https://github.com/#{`git config github.username`.chomp}/#{s.name}"
|
20
|
+
###################################
|
21
|
+
|
22
|
+
s.add_dependency 'i18n', '~> 0.7'
|
23
|
+
s.add_dependency 'json', '~> 1.7', '>= 1.7.7'
|
24
|
+
s.add_dependency 'tzinfo', '~> 1.1'
|
25
|
+
s.add_dependency 'attach_function'
|
26
|
+
|
27
|
+
s.add_development_dependency "rake", "~> 10.0"
|
28
|
+
s.add_development_dependency "pry"
|
29
|
+
s.add_development_dependency "rspec"
|
30
|
+
|
31
|
+
end
|
data/.gemspec_utils.rb
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
require 'yaml'
|
4
|
+
require 'erb'
|
5
|
+
|
6
|
+
module GemspecBoilerplate
|
7
|
+
module_function
|
8
|
+
def camelize(string, uppercase_first_letter = true)
|
9
|
+
string = string.to_s
|
10
|
+
if uppercase_first_letter
|
11
|
+
string = string.sub(/^[a-z\d]*/) { $&.capitalize }
|
12
|
+
else
|
13
|
+
string = string.sub(/^(?:(?=\b|[A-Z_])|\w)/) { $&.downcase }
|
14
|
+
end
|
15
|
+
string.gsub!(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{$2.capitalize}" }
|
16
|
+
string.gsub!(/\//, '::')
|
17
|
+
string
|
18
|
+
end
|
19
|
+
|
20
|
+
def add_naming_metadata!(spec)
|
21
|
+
metadata = spec.metadata
|
22
|
+
metadata.merge!({
|
23
|
+
"name" => spec.name,
|
24
|
+
"underscored_name" => spec.name.tr('-', '_'),
|
25
|
+
"namespaced_path" => spec.name.tr('-', '/')
|
26
|
+
|
27
|
+
})
|
28
|
+
metadata["constant_name"] = camelize(metadata["namespaced_path"])
|
29
|
+
end
|
30
|
+
|
31
|
+
def templates
|
32
|
+
return @templates if @templates
|
33
|
+
File.open(__FILE__) do |this_file|
|
34
|
+
this_file.find { |line| line =~ /^__END__ *$/ }
|
35
|
+
@templates = YAML.load(this_file.read)
|
36
|
+
end
|
37
|
+
@templates
|
38
|
+
end
|
39
|
+
|
40
|
+
def template_write(filename, config, template_str)
|
41
|
+
File.write(filename, ERB.new(template_str, nil,'-').result(binding))
|
42
|
+
end
|
43
|
+
|
44
|
+
def bootstrap_lib!(spec)
|
45
|
+
Dir.exist?('.git') || system(*%w[git init .])
|
46
|
+
m = spec.metadata
|
47
|
+
namespaced_path = m["namespaced_path"]
|
48
|
+
versionfile = "lib/#{namespaced_path}/version.rb"
|
49
|
+
rbfile = "lib/#{namespaced_path}.rb"
|
50
|
+
FileUtils.mkdir_p File.dirname(versionfile)
|
51
|
+
config = m.dup
|
52
|
+
config["constant_array"] = m["constant_name"].split("::")
|
53
|
+
|
54
|
+
template_write(rbfile, config, templates["newgem.tt"]) unless File.exist?(rbfile)
|
55
|
+
template_write(versionfile, config, templates["version.rb.tt"]) unless File.exist?(versionfile)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
__END__
|
60
|
+
---
|
61
|
+
newgem.tt: |
|
62
|
+
require "<%=config["namespaced_path"]%>/version"
|
63
|
+
<%- if config[:ext] -%>
|
64
|
+
require "<%=config["namespaced_path"]%>/<%=config[:underscored_name]%>"
|
65
|
+
<%- end -%>
|
66
|
+
|
67
|
+
<%- config["constant_array"].each_with_index do |c,i| -%>
|
68
|
+
<%= ' '*i %>module <%= c %>
|
69
|
+
<%- end -%>
|
70
|
+
<%= ' '*config["constant_array"].size %>
|
71
|
+
<%- (config["constant_array"].size-1).downto(0) do |i| -%>
|
72
|
+
<%= ' '*i %>end
|
73
|
+
<%- end -%>
|
74
|
+
version.rb.tt: |
|
75
|
+
<%- config["constant_array"].each_with_index do |c,i| -%>
|
76
|
+
<%= ' '*i %>module <%= c %>
|
77
|
+
<%- end -%>
|
78
|
+
<%= ' '*config["constant_array"].size %>VERSION = "0.1.0"
|
79
|
+
HUMAN_VERSION = "1.0.0"
|
80
|
+
<%- (config["constant_array"].size-1).downto(0) do |i| -%>
|
81
|
+
<%= ' '*i %>end
|
82
|
+
<%- end -%>
|
data/.gitignore
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
/.bundle/
|
2
|
+
/.yardoc
|
3
|
+
/Gemfile.lock
|
4
|
+
/_yardoc/
|
5
|
+
/coverage/
|
6
|
+
/doc/
|
7
|
+
/pkg/
|
8
|
+
/spec/reports/
|
9
|
+
/tmp/
|
10
|
+
/.tup/
|
11
|
+
/tupinfo
|
12
|
+
/spec/failing_specs.txt
|
13
|
+
/test/failing_tests.txt
|
14
|
+
/test/succeeding_tests.txt
|
15
|
+
/test/test_hypertdd.rb
|
16
|
+
*.rb.txt
|
17
|
+
Tupfile
|
18
|
+
.bundle
|
19
|
+
spec/succeeding_specs.txt
|
20
|
+
spec/failing_specs.txt
|
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSES/MIT
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2005-2015 David Heinemeier Hansson
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
# CoreX
|
2
|
+
|
3
|
+
My collection of essential (and possibly nonessential) core extensions/mixins (mixins that are intended to
|
4
|
+
be mixed into core classes).
|
5
|
+
|
6
|
+
I may add more as I need more, using RubyOnRail's ActiveSupport as my main source (hey, it's MIT licensed),
|
7
|
+
|
8
|
+
## Selection Strategy
|
9
|
+
My strategy for adding extensions is as follows:
|
10
|
+
|
11
|
+
- if it can be a mixin, make it a mixin instead of modifying the core class directly
|
12
|
+
- only essential stuff in the modules that map to to core classes
|
13
|
+
|
14
|
+
Each extension that takes the form of a mixin shall have the following form:
|
15
|
+
|
16
|
+
```ruby
|
17
|
+
CoreX::`TargetClassOrModule`
|
18
|
+
#- contains the function version of the new functionality
|
19
|
+
CoreX::`TargetClassOrModule`::MethodVersions
|
20
|
+
#- is intended to be `include`d into the `TargetClassOrModule`
|
21
|
+
```
|
22
|
+
|
23
|
+
#### Examples
|
24
|
+
##### (Module) Function version
|
25
|
+
```ruby
|
26
|
+
CoreX::String.camelize('string_argument') #=> 'StringArgument'
|
27
|
+
CoreX::String.undescore('StringArgument') #=> 'string_argument'
|
28
|
+
```
|
29
|
+
|
30
|
+
##### Method version
|
31
|
+
```ruby
|
32
|
+
String.include(CoreX::String::MethodVersions)
|
33
|
+
|
34
|
+
'StringArgument'.underscore #=> 'string_argument'
|
35
|
+
'string_argument'.camelize #=> 'StringArgument'
|
36
|
+
```
|
37
|
+
## Specialized Functionality
|
38
|
+
I either won't be adding specialized functionality (e.g., web-related stuff, linguistic functions) or such functionality will be separated into its own optional modules.
|
39
|
+
|
40
|
+
I may simplify some of the functionality as in the case of (e.g., my version of `camelize` IS the oppossite of underscore -- no special treatment for predefined acronyms) or expand it, if it fits my philosophy.
|
41
|
+
|
42
|
+
## Unincluding Mixins
|
43
|
+
I highly recommend using the `uninclude` plugin. With it, you can for example, decorate your library's entry methods to include a mixin in to a core class before it starts and uniclude it at the end. That will allow you to use a modified core class in the context of your library without polluting the outside world.
|
44
|
+
|
45
|
+
## Executables
|
46
|
+
I might expose some functionality in the form of executables to support your UNIX workflow. Check out the `camelCase' and `snake_case` executables.
|
47
|
+
|
48
|
+
## Installation
|
49
|
+
|
50
|
+
Add this line to your application's Gemfile:
|
51
|
+
|
52
|
+
```ruby
|
53
|
+
gem 'core_x'
|
54
|
+
```
|
55
|
+
|
56
|
+
And then execute:
|
57
|
+
|
58
|
+
$ bundle
|
59
|
+
|
60
|
+
Or install it yourself as:
|
61
|
+
|
62
|
+
$ gem install core_x
|
63
|
+
|
64
|
+
## Usage
|
65
|
+
|
66
|
+
Use it in any way you like.
|
67
|
+
|
68
|
+
## Contributing
|
69
|
+
|
70
|
+
1. Fork it ( https://github.com/[my-github-username]/core_xt/fork )
|
71
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
72
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
73
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
74
|
+
5. Create a new Pull Request
|
75
|
+
|
76
|
+
## Versioning
|
77
|
+
### Version Number for Machines
|
78
|
+
|
79
|
+
This gem uses a slightly modified version of the **SemVer** specification, namely:
|
80
|
+
```ruby
|
81
|
+
spec.version = "BREAKING.PATCHES.NONBREAKING"
|
82
|
+
```
|
83
|
+
You can use this versioning with your dependency tools, only you have a somewhat stronger guarantee that your
|
84
|
+
code won't break if you limit yourself to the third number, but you need to allow second level updates in order to
|
85
|
+
get (security and other) patches.
|
86
|
+
|
87
|
+
### Version Number for Humans
|
88
|
+
Since the above-described type of versioning doesn't tell you anything about the functional state of the gem (you can go from a "hello world" to a full blown operating system
|
89
|
+
without making a breaking change, as long as your operating system prints "hello world" to the screen) (SemVer, when used correctly, doesn't tell anything about the functional state of a software package either), a second, human-friendly version number can be found in `spec.metadata[:human_version]`.
|
90
|
+
|
91
|
+
The magnitude of this version number shall be made to correspond to actual functional changes in the software. If I've worked a lot on the package, I'll make it move a lot, but unless I've made breaking changes, I'll stick to only moving the third number in the `spec.version` version.
|
92
|
+
|
93
|
+
This number is for you. If you see it increase a lot, it probably means much more new goodies, but is less strictly defined then the version number for the machine. (I reserve the right to later change the way I change this number).
|
94
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
|
3
|
+
def gemspec
|
4
|
+
@gemspec ||= Gem::Specification.load('gemspec.gemspec')
|
5
|
+
end
|
6
|
+
|
7
|
+
def repo_exists?(url)
|
8
|
+
@status ||= `curl --head #{Shellwords.escape(url)} 2>/dev/null | head -n1`.split(" ")[1].to_i
|
9
|
+
@status < 400
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
task "release" => :github_repo
|
14
|
+
|
15
|
+
task :github_repo do
|
16
|
+
unless repo_exists?(gemspec.homepage)
|
17
|
+
sh %Q{curl -X POST https://api.github.com/user/repos -H "Authorization: token `git config github.token`" -d ' { "name": "#{gemspec.name}" } '}
|
18
|
+
end
|
19
|
+
sh *%w[git remote add origin], "git@github.com:#{`git config github.user`.chomp}/#{gemspec.name}"
|
20
|
+
sh *%w[git push --set-upstream origin master]
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
task :default => :test
|
26
|
+
|
27
|
+
namespace :tup do
|
28
|
+
directory 'bin'
|
29
|
+
file "Tupfile" => ['Rakefile', 'bin/test_stats_collector.sh'] do |t|
|
30
|
+
|
31
|
+
#ruby_env = " GEM_HOME=#{ENV['GEM_HOME']} GEM_PATH=#{ENV['GEM_PATH']} PATH=#{ENV['PATH']} "
|
32
|
+
|
33
|
+
bundler_path = `bundle show bundle`.chomp
|
34
|
+
bundle_exec = " ruby -I #{bundler_path}/lib #{bundler_path}/bin/bundle exec "
|
35
|
+
|
36
|
+
mkdir_p 'tupinfo'
|
37
|
+
|
38
|
+
string = <<-EOF.gsub(/^ {6}/,'')
|
39
|
+
include tupinfo/tests.tup
|
40
|
+
include tupinfo/specs.tup
|
41
|
+
export GEM_HOME
|
42
|
+
export GEM_PATH
|
43
|
+
export PATH
|
44
|
+
BUNDLE_EXEC = #{bundle_exec}
|
45
|
+
TEST_CMD = ruby -Ilib:test
|
46
|
+
SPEC_CMD = rspec --color --tty
|
47
|
+
: foreach $(TESTS) |> $(BUNDLE_EXEC) $(TEST_CMD) %f >| %o || echo "Failed with: $?" >> %o; cat %o |> %f.txt {test_outputs}
|
48
|
+
: foreach $(SPECS) |> $(BUNDLE_EXEC) $(SPEC_CMD) %f >| %o || echo "Failed with: $?" >> %o; cat %o |> %f.txt {spec_outputs}
|
49
|
+
: {test_outputs} |> exe/test_stats_collector.sh test/succeeding_tests.txt test/failing_tests.txt %f |> test/succeeding_tests.txt test/failing_tests.txt
|
50
|
+
: {spec_outputs} |> exe/test_stats_collector.sh spec/succeeding_specs.txt spec/failing_specs.txt %f |> spec/succeeding_specs.txt spec/failing_specs.txt
|
51
|
+
EOF
|
52
|
+
File.write(t.name, string)
|
53
|
+
end
|
54
|
+
file "exe/test_stats_collector.sh" => ['bin', 'Rakefile'] do |t|
|
55
|
+
File.write(t.name, <<-EOF.gsub(/^ {6}/,'')
|
56
|
+
#!/bin/bash
|
57
|
+
|
58
|
+
#Usage: collect_test_results success_heap.txt failing_heap.txt [result1 result2 ... ]
|
59
|
+
|
60
|
+
success_heap=$1
|
61
|
+
failing_heap=$2
|
62
|
+
touch "$1" "$2"
|
63
|
+
|
64
|
+
shift; shift
|
65
|
+
|
66
|
+
for arg in "$@"
|
67
|
+
do
|
68
|
+
if tail -1 "$arg" | grep -q "^Failed"
|
69
|
+
then
|
70
|
+
cat "$arg" >> "$failing_heap"
|
71
|
+
else
|
72
|
+
cat "$arg" >> "$success_heap"
|
73
|
+
fi
|
74
|
+
done
|
75
|
+
EOF
|
76
|
+
)
|
77
|
+
chmod "u+x", t.name
|
78
|
+
end
|
79
|
+
|
80
|
+
file '.tup' do
|
81
|
+
sh "tup init"
|
82
|
+
end
|
83
|
+
|
84
|
+
desc 'Initialize tup'
|
85
|
+
task :init => ['.tup','Tupfile', 'tupfiles']
|
86
|
+
|
87
|
+
task "find_tests" do
|
88
|
+
sh "find test -name '*_test.rb' -o -name 'test_*.rb' > tupinfo/tests.lst"
|
89
|
+
sh "find spec -name '*_spec.rb' > tupinfo/specs.lst"
|
90
|
+
end
|
91
|
+
|
92
|
+
task "tupfiles" => "find_tests" do
|
93
|
+
sh "sed 's/^/TESTS += /' < tupinfo/tests.lst > tupinfo/tests.tup"
|
94
|
+
sh "sed 's/^/SPECS += /' < tupinfo/specs.lst > tupinfo/specs.tup"
|
95
|
+
end
|
96
|
+
|
97
|
+
|
98
|
+
task "test" => %w[init tupfiles] do
|
99
|
+
sh "tup test --quiet"
|
100
|
+
mkdir_p "test"
|
101
|
+
touch "test/succeeding_tests.txt"
|
102
|
+
touch "test/failing_tests.txt"
|
103
|
+
sh "cat test/succeeding_tests.txt"
|
104
|
+
sh "cat test/failing_tests.txt"
|
105
|
+
end
|
106
|
+
task "spec" => %w[init tupinfo/specs.tup] do
|
107
|
+
sh "tup spec --quiet"
|
108
|
+
mkdir_p "spec"
|
109
|
+
touch "spec/succeeding_specs.txt"
|
110
|
+
touch "spec/failing_specs.txt"
|
111
|
+
sh "cat spec/succeeding_specs.txt"
|
112
|
+
sh "cat spec/failing_specs.txt"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
file '.bundle' => '.gemspec.gemspec' do |t|
|
117
|
+
sh "bundle | tee > #{t.name}"
|
118
|
+
end
|
119
|
+
|
120
|
+
task 'test' => ['tup:test', 'tup:spec', '.bundle']
|
data/TESTING.md
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# TESTING
|
2
|
+
|
3
|
+
This repo currently depends on `tup` for testing.
|
4
|
+
|
5
|
+
Tests are treated as file tasks that map a test file to a test output.
|
6
|
+
`Rake` is used to invoke `tup` to run these test tasks.
|
7
|
+
`Tup`'s role is that of a dependency tracker.
|
8
|
+
|
9
|
+
`Tup` keeps track of file reads issued during each test. A particular test will not be invoked again unless some of the files it read during its last run are newer than the last test output.
|
10
|
+
|
11
|
+
This saves time wasted on useless test runs as long as your tests are deterministic. Fortunately most unit tests are.
|
12
|
+
|
13
|
+
# Deterministicness
|
14
|
+
|
15
|
+
For this work, your tests must be deterministic. That means:
|
16
|
+
- no random input
|
17
|
+
- no testing against real-world net (static mocks only)
|
18
|
+
- no error-fraught C-extensions
|
19
|
+
- no dependence on dynamic stuff such as the current time
|
20
|
+
|
21
|
+
Most unit tests abide by these rules.
|
22
|
+
|
23
|
+
# Bundler
|
24
|
+
You need a patched bundler that supports the `glob` option to `gemspec` or else `bundle exec` will issue reads to every file in the repo, rendering the `tup` setup useless.
|
25
|
+
|
26
|
+
# Dark Corners of Tup
|
27
|
+
|
28
|
+
Unfortunately, tup brings in a couple of somewhat arbitrary (for testing purposes anyway) rules of its own. Mainly that tests must not tread on each other's output. (that means no shared testing databases, for example -- each test must have its own). I hope to fix this by adding dependency tracking to Rake instead, when I have time.
|
data/VERSIONING.md
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
## Versioning
|
2
|
+
### Version Number for Machines
|
3
|
+
|
4
|
+
This gem uses a slightly modified version of the **SemVer** specification, namely:
|
5
|
+
```ruby
|
6
|
+
spec.version = "BREAKING.PATCHES.NONBREAKING"
|
7
|
+
```
|
8
|
+
You can use this versioning with your dependency tools, only you have a somewhat stronger guarantee that your
|
9
|
+
code won't break if you limit yourself to the third number, but you need to allow second level updates in order to
|
10
|
+
get (security and other) patches.
|
11
|
+
|
12
|
+
### Version Number for Humans
|
13
|
+
Since the above-described type of versioning doesn't tell you anything about the functional state of the gem (you can go from a "hello world" to a full blown operating system
|
14
|
+
without making a breaking change, as long as your operating system prints "hello world" to the screen) (SemVer, when used correctly, doesn't tell anything about the functional state of a software package either), a second, human-friendly version number can be found in `spec.metadata[:human_version]`.
|
15
|
+
|
16
|
+
The magnitude of this version number shall be made to correspond to actual functional changes in the software. If I've worked a lot on the package, I'll make it move a lot, but unless I've made breaking changes, I'll stick to only moving the third number in the `spec.version` version.
|
17
|
+
|
18
|
+
This number is for you. If you see it increase a lot, it probably means much more new goodies, but is less strictly defined then the version number for the machine. (I reserve the right to later change the way I change this number).
|
data/bin/camelCase
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
#Read input from params or stding
|
5
|
+
#Snake_case each item
|
6
|
+
|
7
|
+
require 'core_x/string/import'
|
8
|
+
|
9
|
+
input = ARGV.empty? ? STDIN.lazy.map(&:chomp) : ARGV
|
10
|
+
|
11
|
+
input.each do |item|
|
12
|
+
puts item.camelize
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
|
data/bin/snake_case
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
#Read input from params or stding
|
5
|
+
#Snake_case each item
|
6
|
+
|
7
|
+
require 'core_x/string/import'
|
8
|
+
|
9
|
+
input = ARGV.empty? ? STDIN.lazy.map(&:chomp) : ARGV
|
10
|
+
|
11
|
+
input.each do |item|
|
12
|
+
puts item.snakecase
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
|
data/exe/bash_import.sh
ADDED
data/exe/console
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
__DIR__ = File.expand_path(File.dirname(__FILE__))
|
3
|
+
gem_name = File.basename(File.expand_path(File.join(__DIR__,'..')))
|
4
|
+
|
5
|
+
require "bundler/setup"
|
6
|
+
require gem_name
|
7
|
+
|
8
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
9
|
+
# with your gem easier. You can also use a different console, if you like.
|
10
|
+
|
11
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
12
|
+
require "pry"
|
13
|
+
Pry.start
|
data/exe/find_root
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
=begin
|
4
|
+
Ascend the current directory until you find $root_marker
|
5
|
+
© Petr Skočík, 2015
|
6
|
+
|
7
|
+
This program is free software; you can redistribute it and/or modify
|
8
|
+
it under the terms of the GNU General Public License as published by
|
9
|
+
the Free Software Foundation; either version 2 of the License, or
|
10
|
+
(at your option) any later version.
|
11
|
+
|
12
|
+
This program is distributed in the hope that it will be useful,
|
13
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
GNU General Public License for more details.
|
16
|
+
|
17
|
+
You should have received a copy of the GNU General Public License
|
18
|
+
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
19
|
+
=end
|
20
|
+
|
21
|
+
require 'shellwords'
|
22
|
+
require 'pathname'
|
23
|
+
|
24
|
+
$root_marker = ARGV[0] || ".git"
|
25
|
+
$cross_filesystems = ARGV[1] || false
|
26
|
+
$show_relative = ( ARGV[2].nil? && true ) || ARGV[2]
|
27
|
+
|
28
|
+
dir = Pathname.pwd
|
29
|
+
|
30
|
+
unless $cross_filesystems
|
31
|
+
child = dir
|
32
|
+
end
|
33
|
+
|
34
|
+
class BoundaryCrossedError < RuntimeError
|
35
|
+
end
|
36
|
+
begin
|
37
|
+
root = dir.ascend do |cdir|
|
38
|
+
unless $cross_filesystems
|
39
|
+
if cdir.stat.dev != child.stat.dev
|
40
|
+
raise BoundaryCrossedError, "BoundaryCrossedError: File system boundary reached at #{Shellwords.escape(child)}"
|
41
|
+
end
|
42
|
+
child = cdir
|
43
|
+
end
|
44
|
+
break cdir if cdir.join($root_marker).exist?
|
45
|
+
end
|
46
|
+
puts root.relative_path_from(Pathname.pwd)
|
47
|
+
exit 0
|
48
|
+
rescue BoundaryCrossedError => boundary_error
|
49
|
+
warn boundary_error
|
50
|
+
exit 1
|
51
|
+
end
|
data/exe/pty_run
ADDED
data/exe/setup
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
#Usage: collect_test_results success_heap.txt failing_heap.txt [result1 result2 ... ]
|
4
|
+
|
5
|
+
success_heap=$1
|
6
|
+
failing_heap=$2
|
7
|
+
touch "$1" "$2"
|
8
|
+
|
9
|
+
shift; shift
|
10
|
+
|
11
|
+
for arg in "$@"
|
12
|
+
do
|
13
|
+
if tail -1 "$arg" | grep -q "^Failed"
|
14
|
+
then
|
15
|
+
cat "$arg" >> "$failing_heap"
|
16
|
+
else
|
17
|
+
cat "$arg" >> "$success_heap"
|
18
|
+
fi
|
19
|
+
done
|
data/exe/version.rb
ADDED
data/exe/watch
ADDED
data/gemspec.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require_relative 'gemspec_boilerplate'
|
4
|
+
|
5
|
+
spec = Gem::Specification.new do |s|
|
6
|
+
|
7
|
+
GemspecBoilerplate.boilerplate(s)
|
8
|
+
|
9
|
+
#s.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com' to prevent pushes to rubygems.org, or delete to allow pushes to any server."
|
10
|
+
|
11
|
+
#####Must change
|
12
|
+
s.summary = %q{Mixins to extend the core with}
|
13
|
+
s.description = s.summary
|
14
|
+
s.licenses = %w[mit]
|
15
|
+
|
16
|
+
|
17
|
+
#####Unlikely to change
|
18
|
+
s.email = [ `git config user.email` ]
|
19
|
+
s.homepage = "https://github.com/#{`git config github.username`.chomp}/#{s.name}"
|
20
|
+
###################################
|
21
|
+
|
22
|
+
s.add_dependency 'i18n', '~> 0.7'
|
23
|
+
s.add_dependency 'json', '~> 1.7', '>= 1.7.7'
|
24
|
+
s.add_dependency 'tzinfo', '~> 1.1'
|
25
|
+
s.add_dependency 'attach_function'
|
26
|
+
|
27
|
+
s.add_development_dependency "rake", "~> 10.0"
|
28
|
+
s.add_development_dependency "pry"
|
29
|
+
s.add_development_dependency "rspec"
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
require 'fileutils'
|
4
|
+
require 'erb'
|
5
|
+
require_relative '.gemspec_utils'
|
6
|
+
|
7
|
+
$__DIR__ = File.expand_path(File.dirname(__FILE__))
|
8
|
+
lib = File.expand_path('lib', $__DIR__)
|
9
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
10
|
+
|
11
|
+
module GemspecBoilerplate
|
12
|
+
module_function
|
13
|
+
def boilerplate(s)
|
14
|
+
#####Won't change as long as you follow conventions
|
15
|
+
s.name = File.basename($__DIR__)
|
16
|
+
add_naming_metadata!(s)
|
17
|
+
bootstrap_lib!(s)
|
18
|
+
metadata = s.metadata
|
19
|
+
|
20
|
+
require "#{metadata["namespaced_path"]}/version"
|
21
|
+
spec_module = Object.const_get(metadata["constant_name"])
|
22
|
+
s.version = spec_module::VERSION
|
23
|
+
s.metadata["human_version"] = spec_module::HUMAN_VERSION
|
24
|
+
s.files = `git ls-files -z`.split("\x0")
|
25
|
+
s.test_files = s.files.grep(%r{^(test|s|features)/})
|
26
|
+
s.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|s|features)/}) }
|
27
|
+
s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
28
|
+
s.require_paths = ["lib"]
|
29
|
+
s.authors = `git log > /dev/null 2>&1 && git shortlog -sn`.split("\n").map {|a| a.sub(/^[\d\s]*/, '') }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
data/lib/core_x.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'attach_function'
|
2
|
+
|
3
|
+
#These are stolen from active_support (Ruby on Rails, (TM)) and modified (no acronyms in case of camelize; made into a mixin instead of
|
4
|
+
#monkey peatching core classes directly.
|
5
|
+
|
6
|
+
module CoreX
|
7
|
+
module String
|
8
|
+
|
9
|
+
|
10
|
+
# Converts strings to UpperCamelCase.
|
11
|
+
# If the +uppercase_first_letter+ parameter is set to false, then produces
|
12
|
+
# lowerCamelCase.
|
13
|
+
#
|
14
|
+
# Also converts '/' to '::' which is useful for converting
|
15
|
+
# paths to namespaces.
|
16
|
+
#
|
17
|
+
# camelize('active_model') # => "ActiveModel"
|
18
|
+
# camelize('active_model', false) # => "activeModel"
|
19
|
+
# camelize('active_model/errors') # => "ActiveModel::Errors"
|
20
|
+
# camelize('active_model/errors', false) # => "activeModel::Errors"
|
21
|
+
#
|
22
|
+
# As a rule of thumb you can think of +camelize+ as the inverse of
|
23
|
+
# underscore.
|
24
|
+
#
|
25
|
+
# (This is a mechanical method that doesn't understand human stuff like acronyms.)
|
26
|
+
def camelize(string, first_letter_small = false)
|
27
|
+
string = string.to_s
|
28
|
+
if !first_letter_small
|
29
|
+
string = string.sub(/^[a-z\d]*/) { $&.capitalize }
|
30
|
+
else
|
31
|
+
string = string.sub(/^(?:(?=\b|[A-Z_])|\w)/) { $&.downcase }
|
32
|
+
end
|
33
|
+
string.gsub!(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{$2.capitalize}" }
|
34
|
+
string.gsub!(/\//, '::')
|
35
|
+
string
|
36
|
+
end
|
37
|
+
|
38
|
+
alias_method :camelcase, :camelize
|
39
|
+
module_function :camelize, :camelcase
|
40
|
+
|
41
|
+
# Makes an underscored, lowercase form from the expression in the string.
|
42
|
+
#
|
43
|
+
# Changes '::' to '/' to convert namespaces to paths.
|
44
|
+
#
|
45
|
+
# underscore('ActiveModel') # => "active_model"
|
46
|
+
# underscore('ActiveModel::Errors') # => "active_model/errors"
|
47
|
+
#
|
48
|
+
# As a rule of thumb you can think of +underscore+ as the inverse of
|
49
|
+
# #camelize
|
50
|
+
#
|
51
|
+
# camelize(underscore('SSLError')) # => "SslError"
|
52
|
+
#
|
53
|
+
def underscore(camel_cased_word)
|
54
|
+
return camel_cased_word unless camel_cased_word =~ /[A-Z-]|::/
|
55
|
+
word = camel_cased_word.to_s.gsub(/::/, '/')
|
56
|
+
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
|
57
|
+
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
58
|
+
word.tr!("-", "_")
|
59
|
+
word.downcase!
|
60
|
+
word
|
61
|
+
end
|
62
|
+
alias_method :snakecase, :underscore
|
63
|
+
module_function :underscore, :snakecase
|
64
|
+
|
65
|
+
module MethodVersions
|
66
|
+
extend AttachFunction
|
67
|
+
attach_outer_class_methods!
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
data/spec/.rspec
ADDED
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,185 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: core_x
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Petr Skocik
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-04-13 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: i18n
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.7'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: json
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.7'
|
34
|
+
- - ">="
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: 1.7.7
|
37
|
+
type: :runtime
|
38
|
+
prerelease: false
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - "~>"
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '1.7'
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 1.7.7
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: tzinfo
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '1.1'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '1.1'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: attach_function
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
type: :runtime
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: rake
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - "~>"
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '10.0'
|
82
|
+
type: :development
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - "~>"
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '10.0'
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: pry
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
type: :development
|
97
|
+
prerelease: false
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
- !ruby/object:Gem::Dependency
|
104
|
+
name: rspec
|
105
|
+
requirement: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
type: :development
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
117
|
+
description: Mixins to extend the core with
|
118
|
+
email:
|
119
|
+
- |
|
120
|
+
pskocik@gmail.com
|
121
|
+
executables:
|
122
|
+
- camelCase
|
123
|
+
- snake_case
|
124
|
+
extensions: []
|
125
|
+
extra_rdoc_files: []
|
126
|
+
files:
|
127
|
+
- ".gemspec.gemspec"
|
128
|
+
- ".gemspec_utils.rb"
|
129
|
+
- ".gitignore"
|
130
|
+
- ".rspec"
|
131
|
+
- Gemfile
|
132
|
+
- LICENSES/MIT
|
133
|
+
- README.md
|
134
|
+
- Rakefile
|
135
|
+
- TESTING.md
|
136
|
+
- VERSIONING.md
|
137
|
+
- bin/camelCase
|
138
|
+
- bin/snake_case
|
139
|
+
- exe/bash_import.sh
|
140
|
+
- exe/console
|
141
|
+
- exe/find_root
|
142
|
+
- exe/pty_run
|
143
|
+
- exe/setup
|
144
|
+
- exe/test_stats_collector.sh
|
145
|
+
- exe/version.rb
|
146
|
+
- exe/watch
|
147
|
+
- gemspec.gemspec
|
148
|
+
- gemspec_boilerplate.rb
|
149
|
+
- lib/core_x.rb
|
150
|
+
- lib/core_x/string.rb
|
151
|
+
- lib/core_x/string/import.rb
|
152
|
+
- lib/core_x/version.rb
|
153
|
+
- spec/.rspec
|
154
|
+
- spec/spec_helper.rb
|
155
|
+
homepage: https://github.com/pjump/core_x
|
156
|
+
licenses:
|
157
|
+
- mit
|
158
|
+
metadata:
|
159
|
+
name: core_x
|
160
|
+
underscored_name: core_x
|
161
|
+
namespaced_path: core_x
|
162
|
+
constant_name: CoreX
|
163
|
+
human_version: 0.1.0
|
164
|
+
post_install_message:
|
165
|
+
rdoc_options: []
|
166
|
+
require_paths:
|
167
|
+
- lib
|
168
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
169
|
+
requirements:
|
170
|
+
- - ">="
|
171
|
+
- !ruby/object:Gem::Version
|
172
|
+
version: '0'
|
173
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
174
|
+
requirements:
|
175
|
+
- - ">="
|
176
|
+
- !ruby/object:Gem::Version
|
177
|
+
version: '0'
|
178
|
+
requirements: []
|
179
|
+
rubyforge_project:
|
180
|
+
rubygems_version: 2.2.2
|
181
|
+
signing_key:
|
182
|
+
specification_version: 4
|
183
|
+
summary: Mixins to extend the core with
|
184
|
+
test_files: []
|
185
|
+
has_rdoc:
|