grundstein 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.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.rubocop.yml +46 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.Development.md +179 -0
- data/README.md +47 -0
- data/Rakefile +20 -0
- data/Vagrantfile +28 -0
- data/bin/grundstein +5 -0
- data/generators/#vagrant/ask_for_ubuntu_or_fedora +0 -0
- data/generators/rubocop/.rubocop.yml +52 -0
- data/generators/rubocop/Gemfile +7 -0
- data/generators/rubocop/README.Development.md +15 -0
- data/generators/rubocop/Rakefile +6 -0
- data/generators/rubocop/_generator.rb +27 -0
- data/generators/sdoc/.gitignore +1 -0
- data/generators/sdoc/Gemfile +5 -0
- data/generators/sdoc/README.Development.md +40 -0
- data/generators/sdoc/README.md +3 -0
- data/generators/sdoc/Rakefile +12 -0
- data/generators/sdoc/_generator.rb +25 -0
- data/generators/sdoc/doc/.keep +0 -0
- data/grundstein.gemspec +29 -0
- data/lib/grundstein.rb +11 -0
- data/lib/grundstein/generator.rb +9 -0
- data/lib/grundstein/generator/environment.rb +104 -0
- data/lib/grundstein/generator/errors.rb +12 -0
- data/lib/grundstein/generator/loader.rb +89 -0
- data/lib/grundstein/generator/repository.rb +82 -0
- data/lib/grundstein/refinements.rb +1 -0
- data/lib/grundstein/refinements/colored_strings.rb +26 -0
- data/lib/grundstein/runner.rb +29 -0
- data/lib/grundstein/version.rb +3 -0
- metadata +191 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4417958b338d6b06e0c0e6fa6a60785705341f27
|
4
|
+
data.tar.gz: 9ac05330efb49ec5e851fba82e59dd546b940abb
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 24f6b4cc484a02fc65b9cbbcd7782617cb14d1043c2ad8eb3fec07e808f916c5ee329a57a9a9aa0eef9b86d5fdeedb95427b5cb4979094cc5267495d1f0163f4
|
7
|
+
data.tar.gz: ccd5d10005905732a05324ac6ce8b6b608fe83388ebc062d37abf1c47adcfed5b50e22aa747c5fec6b7b47ce5bef5f662392f2af3752d6888613086a224c028e
|
data/.gitignore
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# See a complete description of the checks (named "cops") here: https://github.com/bbatsov/rubocop/blob/master/config/default.yml
|
2
|
+
AllCops:
|
3
|
+
DisplayCopNames: true
|
4
|
+
DisplayStyleGuide: true
|
5
|
+
Exclude:
|
6
|
+
- 'generators/**/*'
|
7
|
+
|
8
|
+
Metrics/LineLength:
|
9
|
+
Enabled: false
|
10
|
+
|
11
|
+
Style/StringLiterals:
|
12
|
+
Enabled: false
|
13
|
+
|
14
|
+
Style/SpaceAroundEqualsInParameterDefault:
|
15
|
+
Enabled: false
|
16
|
+
|
17
|
+
Style/RedundantReturn:
|
18
|
+
Enabled: false
|
19
|
+
|
20
|
+
Style/BracesAroundHashParameters:
|
21
|
+
Enabled: false
|
22
|
+
|
23
|
+
Style/RedundantSelf:
|
24
|
+
Enabled: false
|
25
|
+
|
26
|
+
Style/SignalException:
|
27
|
+
Enabled: false
|
28
|
+
|
29
|
+
Style/EachWithObject:
|
30
|
+
Enabled: false
|
31
|
+
|
32
|
+
Style/RegexpLiteral:
|
33
|
+
Enabled: false
|
34
|
+
|
35
|
+
Metrics/AbcSize:
|
36
|
+
Enabled: false
|
37
|
+
|
38
|
+
Style/TrailingUnderscoreVariable:
|
39
|
+
Enabled: false
|
40
|
+
|
41
|
+
Style/NegatedWhile:
|
42
|
+
Enabled: false
|
43
|
+
|
44
|
+
Style/WordArray:
|
45
|
+
Enabled: false
|
46
|
+
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2016 TODO: Write your name
|
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.
|
@@ -0,0 +1,179 @@
|
|
1
|
+
# Development
|
2
|
+
|
3
|
+
## How generators work
|
4
|
+
|
5
|
+
Each generator has a directory in the `generators` folder. The generator's name is determined by the directory's name.
|
6
|
+
Directories starting with `.` or `#` are ignored. All others must have a `_generator.rb` file.
|
7
|
+
In there...
|
8
|
+
|
9
|
+
- ...must be a `def run` method.
|
10
|
+
- ...must be a `def spec` method which returns a hash with at least `{desc: '....'}`.
|
11
|
+
- ...may be a `def caveats` method which returns a string to be displayed after the generator has run.
|
12
|
+
- ...can be arbitrary other methods or declarations.
|
13
|
+
|
14
|
+
Example:
|
15
|
+
|
16
|
+
```ruby
|
17
|
+
# file: generators/fancy/_generator.rb
|
18
|
+
def run
|
19
|
+
doc_existed = directory('doc') # ensure doc folder is there
|
20
|
+
template('newfile') # finds `newfile` in the generator folder and copies it to the project
|
21
|
+
template('doc/.keep') unless doc_existed # and that there is a .keep if needed
|
22
|
+
template('probably_existing_file', assume_append: true)
|
23
|
+
|
24
|
+
info("EXIST", "YEEY") if File.exists?(File.join(@project_path, 'yeey')) # use Ruby methods
|
25
|
+
answer = ask("You? ") # use HighLine methods
|
26
|
+
end
|
27
|
+
|
28
|
+
def caveats
|
29
|
+
res = <<CAVEATS
|
30
|
+
Please run `bundle install` in your project.
|
31
|
+
CAVEATS
|
32
|
+
return res
|
33
|
+
end
|
34
|
+
|
35
|
+
def spec
|
36
|
+
return { desc: 'does some fancy stuff' }
|
37
|
+
end
|
38
|
+
```
|
39
|
+
|
40
|
+
### Generator context
|
41
|
+
|
42
|
+
The generator script is guaranteed to include:
|
43
|
+
|
44
|
+
- Ruby's standard methods (standard library)
|
45
|
+
- [HighLine](https://github.com/JEG2/highline) gem (`require 'highline/import'` was run)
|
46
|
+
- [Thor](https://github.com/erikhuda/thor) gem loaded.
|
47
|
+
- The following helpers:
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
@generator_path # root path of the generator e.g. `.../generators/sdoc/`
|
51
|
+
@working_path # path of the current working directory (may be != to @project_path)
|
52
|
+
@project_path # root path of the project (with the .git in it)
|
53
|
+
|
54
|
+
# Ensures that the project has the directory given.
|
55
|
+
# This method returns if the directory already existed.
|
56
|
+
def directory(relative_project_path)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Processes the template found at `relative_project_path` and copies it to the project.
|
60
|
+
# Relative_template_path determines the path of the template relative to the generator's root.
|
61
|
+
# If `destination_path` is nil, the destination path will be determined by appending `relative_template_path` to `@project_path`.
|
62
|
+
# If `destination_path` is given, it may be an absolute path or a relative path (to `@project_path`).
|
63
|
+
# In case the destination file already exists, the user will be queried what to do (append, overwrite, skip or print).
|
64
|
+
# If `assume_append` is true, the user is not queried and the template will be appended.
|
65
|
+
def template(relative_template_path, destination_path: nil, assume_append: false) # rubocop:disable Metrics/CyclomaticComplexity,
|
66
|
+
end
|
67
|
+
|
68
|
+
# Prints out a message.
|
69
|
+
def info(action, message)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Sets a variable with the given `name` and `value` to be available for all future templates.
|
73
|
+
def template_context(name, value)
|
74
|
+
end
|
75
|
+
```
|
76
|
+
|
77
|
+
Please see `lib/grundstein/generator/environment.rb` for more.
|
78
|
+
|
79
|
+
## Templates
|
80
|
+
|
81
|
+
Grundstein uses [mustache](https://mustache.github.io/) as template engine.
|
82
|
+
Please see an extensive description [here](https://mustache.github.io/mustache.5.html).
|
83
|
+
|
84
|
+
There are a few variables guaranteed to be present:
|
85
|
+
|
86
|
+
- `existed?` and `new_file?` as boolean values determining if a new file has just been created.
|
87
|
+
- `project_path`, `generator_path` and `working_path`. Description, please see above
|
88
|
+
- You can also use `template_context(name, value)` in your generator's run method to add other variables.
|
89
|
+
(use a question mark at the end of the name for boolean values).
|
90
|
+
|
91
|
+
Example:
|
92
|
+
|
93
|
+
```ruby
|
94
|
+
def run
|
95
|
+
template_context("rails?", agree("Do you intend to use Rails? ")) # note the two spaces at the end
|
96
|
+
template_context("name", ask("You name? "))
|
97
|
+
end
|
98
|
+
# ...
|
99
|
+
```
|
100
|
+
|
101
|
+
```ruby
|
102
|
+
# Author: {{name}}
|
103
|
+
|
104
|
+
{{#new_file?}}
|
105
|
+
source 'https://rubygems.org'
|
106
|
+
{{/new_file?}}
|
107
|
+
|
108
|
+
gem 'sdoc'
|
109
|
+
{{#rails?}}
|
110
|
+
gem 'rails'
|
111
|
+
{{/rails?}}
|
112
|
+
```
|
113
|
+
|
114
|
+
## Testing
|
115
|
+
|
116
|
+
```bash
|
117
|
+
# you should test your generators in a new project
|
118
|
+
cd /tmp/
|
119
|
+
git init myproject
|
120
|
+
cd myproject/
|
121
|
+
RUBYLIB='/vagrant/lib:$RUBYLIB' bin/grundstein add rubocop
|
122
|
+
```
|
123
|
+
|
124
|
+
## API documentation
|
125
|
+
|
126
|
+
We are using the [sdoc](https://github.com/voloko/sdoc) generator which is based on [rdoc](https://github.com/rdoc/rdoc).
|
127
|
+
You may generate the documentation via `rake rdoc` and then find it in `doc/api`.
|
128
|
+
|
129
|
+
For documenting methods and classes we use [markdown](https://daringfireball.net/projects/markdown/). Just add a comment above a class, method or attribute.
|
130
|
+
If you are not familiar with markdown, please see this [cheat sheet](http://nestacms.com/docs/creating-content/markdown-cheat-sheet).
|
131
|
+
Here a quick example:
|
132
|
+
|
133
|
+
```ruby
|
134
|
+
# This is a mountain in the landscape.
|
135
|
+
# It has seasons and simulates weather.
|
136
|
+
class Mountain
|
137
|
+
# The hight of the mountain [meter].
|
138
|
+
attr_accessor :height
|
139
|
+
|
140
|
+
# Constructor.
|
141
|
+
# The `height` is measured in meters.
|
142
|
+
# If snow is true, we can build ski lifts.
|
143
|
+
def initialize(height, snow=false)
|
144
|
+
end
|
145
|
+
|
146
|
+
# Changes the weather on the mountain and sends a letter to the weather god.
|
147
|
+
# `season` can be either `:summer`, `:spring`, `:fall` or `:winter`.
|
148
|
+
# The letter to the weather god will include the desired `min_temp` or `max_temp`.
|
149
|
+
#
|
150
|
+
# m = Mountain.new(1000) # this is some example code
|
151
|
+
# m.change_season(:summer)
|
152
|
+
def change_season(season, min_temp: -10, max_temp: 30)
|
153
|
+
end
|
154
|
+
|
155
|
+
# Whenever rain occures, the block will be executed.
|
156
|
+
# **WARNING**: Will be called from another thread.
|
157
|
+
#
|
158
|
+
# _yields_ temperature, rain_amount
|
159
|
+
def rain_handler(&block)
|
160
|
+
yield 1, 2
|
161
|
+
end
|
162
|
+
end
|
163
|
+
```
|
164
|
+
|
165
|
+
## Code Style
|
166
|
+
|
167
|
+
We are using this [Rubocop](https://github.com/bbatsov/rubocop) to enforce coding style.
|
168
|
+
|
169
|
+
```bash
|
170
|
+
rake rubocop # Run before each commit/push
|
171
|
+
rake rubocop:auto_correct # auto-corrects issues where it can
|
172
|
+
|
173
|
+
rubocop --only Style/TrailingBlankLines --auto-correct # correct only a single offense type
|
174
|
+
```
|
175
|
+
|
176
|
+
If you are a hundred percent sure you are doing the right thing, you can disable checking. Either
|
177
|
+
|
178
|
+
- disable them for a particular line/method/class with: `# rubocop:disable Metrics/LineLength, Style/StringLiterals`
|
179
|
+
- or disable rubocop for the full file: `# rubocop:disable all`
|
data/README.md
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# Grundstein
|
2
|
+
|
3
|
+
[]()
|
4
|
+
[]()
|
5
|
+
|
6
|
+
I was annoyed to do the same work over and over.
|
7
|
+
Often, I found myself to create the same `Vagrantfile`, `.gitignore` or `Gemfile` for each new project.
|
8
|
+
Grundstein automates this step in a very simple way: We have (smart) templates which are copied to your repo.
|
9
|
+
These templates are (in Rails fashion) called generators.
|
10
|
+
|
11
|
+
**Examples**
|
12
|
+
|
13
|
+
- You can call something like `grundstein vagrant` and you get a Vagrantfile and a little note in your README.
|
14
|
+
- When you call `grundstein rubocop` you get a .rubocop file with some defaults and a few lines in your Rakefile.
|
15
|
+
|
16
|
+
**Principles**
|
17
|
+
|
18
|
+
- Don't be smart detecting stuff, ask! (some stuff might not have been created by the developer yet)
|
19
|
+
- Generate rather more useful stuff than too few: A user can delete quicker than adding new stuff.
|
20
|
+
- Show the user what is happening and what needs to be done next.
|
21
|
+
- If in doubt, append.
|
22
|
+
|
23
|
+
**Pro Tip**: Commit before running generators. Then review the changes via `git diff` or a [visual git tool](https://desktop.github.com/).
|
24
|
+
|
25
|
+
## Installation
|
26
|
+
|
27
|
+
Please make sure you have `git >= 1.7` installed. Then run:
|
28
|
+
|
29
|
+
```bash
|
30
|
+
gem install grundstein
|
31
|
+
```
|
32
|
+
|
33
|
+
## Usage
|
34
|
+
|
35
|
+
The project's root folder is determined based on the current working directory.
|
36
|
+
If there is no `.git` directory in the current directory, the script will try to move up until it finds a `.git`.
|
37
|
+
Hence, **the project must be a git repository**.
|
38
|
+
|
39
|
+
```bash
|
40
|
+
grundstein list # see all generators
|
41
|
+
cd myproject
|
42
|
+
grundstein add rubocop
|
43
|
+
```
|
44
|
+
|
45
|
+
## Contribute & Development
|
46
|
+
|
47
|
+
Please see `README.Development.md`.
|
data/Rakefile
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rdoc/task"
|
3
|
+
require 'sdoc'
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'rubocop/rake_task'
|
7
|
+
RuboCop::RakeTask.new
|
8
|
+
rescue LoadError => _
|
9
|
+
STDERR.puts "Rubocop rake tasks not added, because gem not available." # you can remove this note if you want
|
10
|
+
end
|
11
|
+
|
12
|
+
Rake::RDocTask.new do |rdoc| # options are documented here: http://ruby-doc.org/stdlib-2.0.0/libdoc/rdoc/rdoc/RDoc/Task.html
|
13
|
+
rdoc.rdoc_dir = 'doc/api'
|
14
|
+
rdoc.generator = 'sdoc'
|
15
|
+
rdoc.markup = 'markdown'
|
16
|
+
rdoc.main = 'README.md'
|
17
|
+
rdoc.rdoc_files.include("README.md", "bin/*", "lib/**/*.rb")
|
18
|
+
rdoc.template = 'rails' # change default from 'sdoc' to 'rails' style
|
19
|
+
# rdoc.options.push('--quiet') # see more options here: http://ruby-doc.org/stdlib-2.0.0/libdoc/rdoc/rdoc/RDoc/Options.html
|
20
|
+
end
|
data/Vagrantfile
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- mode: ruby -*-
|
2
|
+
|
3
|
+
NAME = 'grundstein'.freeze
|
4
|
+
|
5
|
+
DEPS = <<SCRIPT.freeze
|
6
|
+
dnf -y install git vim-enhanced
|
7
|
+
dnf -y install ruby ruby-devel rubygem-bundler
|
8
|
+
SCRIPT
|
9
|
+
|
10
|
+
BUNDLE = <<SCRIPT.freeze
|
11
|
+
pushd /vagrant
|
12
|
+
bundle install
|
13
|
+
SCRIPT
|
14
|
+
|
15
|
+
Vagrant.configure("2") do |config|
|
16
|
+
config.vm.hostname = NAME
|
17
|
+
|
18
|
+
config.vm.box = "fedora/23-cloud-base" # see below for virtual box
|
19
|
+
config.vm.provision :shell, inline: DEPS
|
20
|
+
config.vm.provision :shell, inline: BUNDLE, privileged: false
|
21
|
+
|
22
|
+
config.vm.provider "virtualbox" do |vb, override|
|
23
|
+
override.vm.synced_folder ".", "/vagrant", type: "virtualbox"
|
24
|
+
vb.name = NAME
|
25
|
+
vb.memory = 2048
|
26
|
+
vb.cpus = 2
|
27
|
+
end
|
28
|
+
end
|
data/bin/grundstein
ADDED
File without changes
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# See a complete description of the checks (named "cops") here: https://github.com/bbatsov/rubocop/blob/master/config/default.yml
|
2
|
+
AllCops:
|
3
|
+
DisplayCopNames: true
|
4
|
+
DisplayStyleGuide: true
|
5
|
+
|
6
|
+
{{#rails?}}
|
7
|
+
Rails:
|
8
|
+
Enabled: true
|
9
|
+
|
10
|
+
# Style/Documentation:
|
11
|
+
# Enabled: false
|
12
|
+
{{/rails?}}
|
13
|
+
|
14
|
+
# Metrics/LineLength:
|
15
|
+
# Enabled: false
|
16
|
+
#
|
17
|
+
# Style/StringLiterals:
|
18
|
+
# Enabled: false
|
19
|
+
#
|
20
|
+
# Style/SpaceAroundEqualsInParameterDefault:
|
21
|
+
# Enabled: false
|
22
|
+
#
|
23
|
+
# Style/RedundantReturn:
|
24
|
+
# Enabled: false
|
25
|
+
#
|
26
|
+
# Style/BracesAroundHashParameters:
|
27
|
+
# Enabled: false
|
28
|
+
#
|
29
|
+
# Style/RedundantSelf:
|
30
|
+
# Enabled: false
|
31
|
+
#
|
32
|
+
# Style/SignalException:
|
33
|
+
# Enabled: false
|
34
|
+
#
|
35
|
+
# Style/EachWithObject:
|
36
|
+
# Enabled: false
|
37
|
+
#
|
38
|
+
# Style/RegexpLiteral:
|
39
|
+
# Enabled: false
|
40
|
+
#
|
41
|
+
# Metrics/AbcSize:
|
42
|
+
# Enabled: false
|
43
|
+
#
|
44
|
+
# Style/TrailingUnderscoreVariable:
|
45
|
+
# Enabled: false
|
46
|
+
#
|
47
|
+
# Style/NegatedWhile:
|
48
|
+
# Enabled: false
|
49
|
+
#
|
50
|
+
# Style/WordArray:
|
51
|
+
# Enabled: false
|
52
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
## Code Style
|
2
|
+
|
3
|
+
We are using this [Rubocop](https://github.com/bbatsov/rubocop) to enforce coding style.
|
4
|
+
|
5
|
+
```bash
|
6
|
+
rake rubocop # Run before each commit/push
|
7
|
+
rake rubocop:auto_correct # auto-corrects issues where it can
|
8
|
+
|
9
|
+
rubocop --only Style/TrailingBlankLines --auto-correct # correct only a single offense type
|
10
|
+
```
|
11
|
+
|
12
|
+
If you are a hundred percent sure you are doing the right thing, you can disable checking. Either
|
13
|
+
|
14
|
+
- disable them for a particular line/method/class with: `# rubocop:disable Metrics/LineLength, Style/StringLiterals`
|
15
|
+
- or disable rubocop for the full file: `# rubocop:disable all`
|
@@ -0,0 +1,27 @@
|
|
1
|
+
def run
|
2
|
+
template_context("rails?", agree("Do you intend to use Rails? "))
|
3
|
+
template('.rubocop.yml')
|
4
|
+
template('Gemfile', assume_append: true)
|
5
|
+
template('Rakefile', assume_append: true)
|
6
|
+
template('README.Development.md', assume_append: true)
|
7
|
+
end
|
8
|
+
|
9
|
+
def caveats
|
10
|
+
res = <<CAVEATS
|
11
|
+
Please run `bundle install` in your project.
|
12
|
+
|
13
|
+
You can use `rubocop --auto-gen-config` to automatically create `.rubocop_todo.yml`.
|
14
|
+
In your `.rubocop.yml` you can then add `inherit_from: .rubocop_todo.yml` to include it.
|
15
|
+
More info: https://github.com/bbatsov/rubocop#automatically-generated-configuration
|
16
|
+
|
17
|
+
|
18
|
+
If you are using a CI, you may want to include something like `bundle exec rubocop`.
|
19
|
+
CAVEATS
|
20
|
+
return res
|
21
|
+
end
|
22
|
+
|
23
|
+
def spec
|
24
|
+
return {
|
25
|
+
desc: 'rubocop style checker'
|
26
|
+
}
|
27
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
doc/api
|
@@ -0,0 +1,40 @@
|
|
1
|
+
## API documentation
|
2
|
+
|
3
|
+
We are using the [sdoc](https://github.com/voloko/sdoc) generator which is based on [rdoc](https://github.com/rdoc/rdoc).
|
4
|
+
You may generate the documentation via `rake rdoc` and then find it in `doc/api`.
|
5
|
+
|
6
|
+
For documenting methods and classes we use [markdown](https://daringfireball.net/projects/markdown/). Just add a comment above a class, method or attribute.
|
7
|
+
If you are not familiar with markdown, please see this [cheat sheet](http://nestacms.com/docs/creating-content/markdown-cheat-sheet).
|
8
|
+
Here a quick example:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
# This is a mountain in the landscape.
|
12
|
+
# It has seasons and simulates weather.
|
13
|
+
class Mountain
|
14
|
+
# The hight of the mountain [meter].
|
15
|
+
attr_accessor :height
|
16
|
+
|
17
|
+
# Constructor.
|
18
|
+
# The `height` is measured in meters.
|
19
|
+
# If snow is true, we can build ski lifts.
|
20
|
+
def initialize(height, snow=false)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Changes the weather on the mountain and sends a letter to the weather god.
|
24
|
+
# `season` can be either `:summer`, `:spring`, `:fall` or `:winter`.
|
25
|
+
# The letter to the weather god will include the desired `min_temp` or `max_temp`.
|
26
|
+
#
|
27
|
+
# m = Mountain.new(1000) # this is some example code
|
28
|
+
# m.change_season(:summer)
|
29
|
+
def change_season(season, min_temp: -10, max_temp: 30)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Whenever rain occures, the block will be executed.
|
33
|
+
# **WARNING**: Will be called from another thread.
|
34
|
+
#
|
35
|
+
# _yields_ temperature, rain_amount
|
36
|
+
def rain_handler(&block)
|
37
|
+
yield 1, 2
|
38
|
+
end
|
39
|
+
end
|
40
|
+
```
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require "rdoc/task"
|
2
|
+
require 'sdoc'
|
3
|
+
|
4
|
+
Rake::RDocTask.new do |rdoc| # options are documented here: http://ruby-doc.org/stdlib-2.0.0/libdoc/rdoc/rdoc/RDoc/Task.html
|
5
|
+
rdoc.rdoc_dir = 'doc/api'
|
6
|
+
rdoc.generator = 'sdoc'
|
7
|
+
rdoc.markup = 'markdown'
|
8
|
+
rdoc.main = 'README.md'
|
9
|
+
rdoc.rdoc_files.include("README.md", "bin/*", "lib/**/*.rb")
|
10
|
+
rdoc.template = 'rails' # change default from 'sdoc' to 'rails' style
|
11
|
+
# rdoc.options.push('--quiet') # see more options here: http://ruby-doc.org/stdlib-2.0.0/libdoc/rdoc/rdoc/RDoc/Options.html
|
12
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
def run
|
2
|
+
doc_existed = directory('doc') # ensure doc folder is there
|
3
|
+
template('doc/.keep') unless doc_existed # and that there is a .keep if needed
|
4
|
+
template('.gitignore', assume_append: true)
|
5
|
+
template('Gemfile', assume_append: true)
|
6
|
+
template('Rakefile', assume_append: true)
|
7
|
+
template('README.Development.md', assume_append: true)
|
8
|
+
template('README.md', assume_append: true)
|
9
|
+
end
|
10
|
+
|
11
|
+
def caveats
|
12
|
+
res = <<CAVEATS
|
13
|
+
Please run `bundle install` in your project.
|
14
|
+
|
15
|
+
Rdoc is very free-form.
|
16
|
+
If you prefer a stricter way for documenting you code, please take a look at yardoc.org.
|
17
|
+
Especially in larger projects, a stricter style may be better suited.
|
18
|
+
|
19
|
+
CAVEATS
|
20
|
+
return res
|
21
|
+
end
|
22
|
+
|
23
|
+
def spec
|
24
|
+
return { desc: 'rdoc rake task using sdoc template' }
|
25
|
+
end
|
File without changes
|
data/grundstein.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'grundstein/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'grundstein'
|
8
|
+
spec.version = Grundstein::VERSION
|
9
|
+
spec.authors = ['Tom Rothe']
|
10
|
+
spec.email = ['info@tomrothe.de']
|
11
|
+
spec.summary = 'Automates adding common files to your project.'
|
12
|
+
spec.description = 'Grundstein automates adding common files by we adding (smart) templates. E.g. add a Vagrantfile, a .gitignore, or a sinatra app.'
|
13
|
+
spec.homepage = 'https://github.com/motine/grundstein'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_runtime_dependency 'thor', '~> 0.19.1'
|
22
|
+
spec.add_runtime_dependency 'highline', '~> 1.7'
|
23
|
+
spec.add_runtime_dependency 'mustache', '~> 1.0'
|
24
|
+
spec.add_runtime_dependency 'git', '~> 1.3'
|
25
|
+
spec.add_development_dependency 'bundler', '~> 1.7'
|
26
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
27
|
+
spec.add_development_dependency 'rubocop', '~> 0.37.2'
|
28
|
+
spec.add_development_dependency 'sdoc', '~> 0.4.1'
|
29
|
+
end
|
data/lib/grundstein.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require_relative 'grundstein/version'
|
2
|
+
|
3
|
+
module Grundstein # rubocop:disable Style/Documentation
|
4
|
+
def self.lib_path
|
5
|
+
File.expand_path('..', __FILE__)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
require_relative 'grundstein/refinements'
|
10
|
+
require_relative 'grundstein/generator'
|
11
|
+
require_relative 'grundstein/runner'
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'mustache'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
module Grundstein
|
5
|
+
module Generator
|
6
|
+
# This class is used to create the envrionment for the generator file.
|
7
|
+
# This class is instanciated by the Generator::Loader.
|
8
|
+
# Then `extend_from_file` is called. This will then load all methods available in that file into this object.
|
9
|
+
# From there on the Loader can interact with the generator (e.g. call `run`)
|
10
|
+
class Environment
|
11
|
+
using Grundstein::Refinements::ColoredStrings
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@template_vars = {}
|
15
|
+
end
|
16
|
+
|
17
|
+
# Takes a kwargs and sets instance variables in the environment and makes them available as template variables.
|
18
|
+
# Called by Generator::Loader.
|
19
|
+
def set_context(**vars) # rubocop:disable Style/AccessorMethodName
|
20
|
+
vars.each do |var, value|
|
21
|
+
self.instance_variable_set("@#{var}".to_sym, value)
|
22
|
+
@template_vars[var] = value
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Loads the script from the given path and adds the methods to this class.
|
27
|
+
# Called by Generator::Loader.
|
28
|
+
def extend_from_file(path)
|
29
|
+
self.instance_eval(File.read(path))
|
30
|
+
end
|
31
|
+
|
32
|
+
# This may be overridden by the `_generator.rb`.
|
33
|
+
def caveats
|
34
|
+
return ''
|
35
|
+
end
|
36
|
+
|
37
|
+
# Prints out a message.
|
38
|
+
def info(action, message)
|
39
|
+
puts " #{action.ljust(10).c_info} #{message}"
|
40
|
+
end
|
41
|
+
|
42
|
+
# Sets a variable with the given `name` and `value` to be available for all future templates.
|
43
|
+
def template_context(name, value)
|
44
|
+
@template_vars[name] = value
|
45
|
+
end
|
46
|
+
|
47
|
+
# Ensures that the project has the directory given.
|
48
|
+
# This method returns if the directory already existed.
|
49
|
+
def directory(relative_project_path)
|
50
|
+
path = File.expand_path(relative_project_path, @project_path)
|
51
|
+
exists = Dir.exist?(path)
|
52
|
+
if exists
|
53
|
+
info("EXIST", path)
|
54
|
+
else
|
55
|
+
info("CREATE", path)
|
56
|
+
FileUtils.mkdir_p(path)
|
57
|
+
end
|
58
|
+
return exists
|
59
|
+
end
|
60
|
+
|
61
|
+
# Convenience method for the generator
|
62
|
+
# Processes the template found at `relative_project_path` and copies it to the project.
|
63
|
+
# Relative_template_path determines the path of the template relative to the generator's root
|
64
|
+
# If `destination_path` is nil, the destination path will be determined by appending `relative_template_path` to `@project_path`.
|
65
|
+
# If `destination_path` is given, it may be an absolute path or a relative path (to `@project_path`).
|
66
|
+
# In case the destination file already exists, the user will be queried what to do (append, overwrite, skip or print).
|
67
|
+
# If `assume_append` is true, the user is not queried and the template will be appended.
|
68
|
+
def template(relative_template_path, destination_path: nil, assume_append: false) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
69
|
+
template_path = File.join(@generator_path, relative_template_path)
|
70
|
+
raise GeneratorRunError, "Could not find template '#{relative_template_path}'." unless File.exist?(template_path)
|
71
|
+
|
72
|
+
destination_path = File.expand_path(relative_template_path, @project_path) if destination_path.nil?
|
73
|
+
exists = File.exist?(destination_path)
|
74
|
+
|
75
|
+
rendered_template = Mustache.render(File.read(template_path), @template_vars.merge(new_file?: !exists))
|
76
|
+
|
77
|
+
append = true
|
78
|
+
if exists && !assume_append
|
79
|
+
choose do |menu|
|
80
|
+
menu.prompt = "#{destination_path.c_warning} already exists. "
|
81
|
+
menu.layout = :one_line
|
82
|
+
menu.choice(:append) {}
|
83
|
+
menu.choice(:overwrite) { append = false }
|
84
|
+
menu.choice(:skip) do
|
85
|
+
info("SKIP", destination_path)
|
86
|
+
return
|
87
|
+
end
|
88
|
+
menu.choice(:print) do
|
89
|
+
puts ">>>" * 20 + destination_path
|
90
|
+
puts rendered_template
|
91
|
+
puts "<<<" * 20 + destination_path
|
92
|
+
return
|
93
|
+
end
|
94
|
+
end
|
95
|
+
puts
|
96
|
+
end
|
97
|
+
File.open(destination_path, append ? 'a' : 'w') do |f|
|
98
|
+
f.puts(rendered_template)
|
99
|
+
end
|
100
|
+
info((exists && append) ? "APPEND" : "CREATE", destination_path)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module Grundstein
|
2
|
+
module Generator
|
3
|
+
# This class encapsulates the logic to load a generator.
|
4
|
+
# It sets up a Generator::Envrionment and interacts with it.
|
5
|
+
# It is also responsible to determine paths.
|
6
|
+
class Loader
|
7
|
+
using Grundstein::Refinements::ColoredStrings
|
8
|
+
|
9
|
+
SCRIPT_NAME = '_generator.rb'.freeze
|
10
|
+
DIR_EXPECTED_IN_PROJECT_ROOT = '.git'.freeze
|
11
|
+
|
12
|
+
# Loads the generator.
|
13
|
+
def initialize(generator_name)
|
14
|
+
@generator_name = generator_name
|
15
|
+
@env = load_environment
|
16
|
+
@env.set_context(generator_path: generator_path, working_path: working_path, project_path: project_root_path)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Executes the generator's run method.
|
20
|
+
def run # rubocop:disable Metrics/MethodLength
|
21
|
+
raise GeneratorMalformedError, "Generator script '#{@generator_name}' does not have a 'run' method." unless @env.respond_to?(:run)
|
22
|
+
begin
|
23
|
+
puts "Running #{@generator_name.c_gen}"
|
24
|
+
puts "Working path: #{working_path}"
|
25
|
+
puts "Project path: #{project_root_path}"
|
26
|
+
puts
|
27
|
+
@env.run
|
28
|
+
puts
|
29
|
+
puts @env.caveats.c_warning
|
30
|
+
rescue => e
|
31
|
+
raise GeneratorRunError, "[#{@generator_name}] #{e.message}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def name
|
36
|
+
return @generator_name
|
37
|
+
end
|
38
|
+
|
39
|
+
def info
|
40
|
+
raise GeneratorMalformedError, "Generator script '#{@generator_name}' does not have an 'info' method." unless @env.respond_to?(:spec)
|
41
|
+
spec = @env.spec
|
42
|
+
raise GeneratorMalformedError, "Generator script '#{@generator_name}' does include :desc in the 'info' result." unless spec.is_a?(Hash) && spec[:desc].is_a?(String)
|
43
|
+
return spec
|
44
|
+
end
|
45
|
+
|
46
|
+
# short hand for info[:desc]
|
47
|
+
def desc
|
48
|
+
return info[:desc]
|
49
|
+
end
|
50
|
+
|
51
|
+
protected
|
52
|
+
|
53
|
+
# Creates a Generator::Environment for the generator_name given in the constructor.
|
54
|
+
def load_environment
|
55
|
+
env = Grundstein::Generator::Environment.new
|
56
|
+
path = self.generator_script_path
|
57
|
+
raise GeneratorNotFoundError, "Generator named '#{@generator_name}' could not be found." unless Dir.exist?(File.dirname(path))
|
58
|
+
raise GeneratorNotFoundError, "Generator named '#{@generator_name}' has no #{SCRIPT_NAME} script." unless File.exist?(path)
|
59
|
+
env.extend_from_file(path)
|
60
|
+
return env
|
61
|
+
end
|
62
|
+
|
63
|
+
def working_path
|
64
|
+
return Dir.pwd
|
65
|
+
end
|
66
|
+
|
67
|
+
def generator_path
|
68
|
+
return Generator::Repository.instance.generator_path(@generator_name)
|
69
|
+
end
|
70
|
+
|
71
|
+
def generator_script_path
|
72
|
+
return File.join(self.generator_path, SCRIPT_NAME)
|
73
|
+
end
|
74
|
+
|
75
|
+
def project_root_path
|
76
|
+
return @project_root_path unless @project_root_path.nil?
|
77
|
+
dir = Dir.pwd
|
78
|
+
loop do
|
79
|
+
raise GeneratorRunError, "Could not determine project path (no .git found here or above)." if dir == '/'
|
80
|
+
if Dir.exist?(File.join(dir, DIR_EXPECTED_IN_PROJECT_ROOT))
|
81
|
+
@project_root_path = dir
|
82
|
+
return dir
|
83
|
+
end
|
84
|
+
dir = File.dirname(dir)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'git'
|
2
|
+
|
3
|
+
module Grundstein
|
4
|
+
module Generator
|
5
|
+
# Manages the generator repository. Implemented as a singleton (see `instance` method).
|
6
|
+
# It uses git to keep the repository up to date.
|
7
|
+
# It will check the repo out to '~/.grundstein'.
|
8
|
+
# It also creates a file in this directory named 'last_update' where the timestamp of the last update is kept.
|
9
|
+
# If this time stamp is too long ago, it will update the repo.
|
10
|
+
#
|
11
|
+
# Use this class by using the instance method: `Generator::Repository.instance`
|
12
|
+
class Repository
|
13
|
+
OUTDATED_THRESHOLD = 1 # day(s)
|
14
|
+
|
15
|
+
using Grundstein::Refinements::ColoredStrings
|
16
|
+
|
17
|
+
def self.instance
|
18
|
+
@instance ||= Repository.new(File.expand_path("~/.grundstein"))
|
19
|
+
return @instance
|
20
|
+
end
|
21
|
+
|
22
|
+
# Iteratates through all generators and yields the block with the |name, desc|.
|
23
|
+
def generators
|
24
|
+
result = []
|
25
|
+
Dir.foreach(generators_path) do |dir|
|
26
|
+
next if dir.start_with?('.', '#')
|
27
|
+
result << dir
|
28
|
+
end
|
29
|
+
return result
|
30
|
+
end
|
31
|
+
|
32
|
+
def generators_path
|
33
|
+
return File.join(@path, 'generators')
|
34
|
+
end
|
35
|
+
|
36
|
+
def generator_path(name)
|
37
|
+
return File.join(generators_path, name)
|
38
|
+
end
|
39
|
+
|
40
|
+
protected
|
41
|
+
|
42
|
+
# The constructor will check if the repository is there and create it if necessary.
|
43
|
+
# If the repo is outdated, it will update it.
|
44
|
+
def initialize(path)
|
45
|
+
@path = path
|
46
|
+
@git = Git.open(@path) # , :log => Logger.new(STDOUT))
|
47
|
+
update if outdated?
|
48
|
+
rescue ArgumentError => _
|
49
|
+
setup
|
50
|
+
retry
|
51
|
+
end
|
52
|
+
|
53
|
+
def outdated?
|
54
|
+
return DateTime.parse(File.read(last_update_file_path)) < (DateTime.now - OUTDATED_THRESHOLD)
|
55
|
+
rescue => _
|
56
|
+
return true
|
57
|
+
end
|
58
|
+
|
59
|
+
def update
|
60
|
+
puts "Updating generator repository..."
|
61
|
+
@git.pull
|
62
|
+
File.write(last_update_file_path, DateTime.now.to_s)
|
63
|
+
end
|
64
|
+
|
65
|
+
def setup
|
66
|
+
puts "Initializing generator repository...".c_warning
|
67
|
+
@git = Git.init(@path)
|
68
|
+
@git.add_remote('origin', 'https://github.com/motine/grundstein.git')
|
69
|
+
|
70
|
+
# TODO: make sure git > 1.7
|
71
|
+
# let's only checkout the generators
|
72
|
+
@git.config('core.sparsecheckout', true)
|
73
|
+
File.write(File.join(@git.repo.path, 'info', 'sparse-checkout'), 'generators')
|
74
|
+
update
|
75
|
+
end
|
76
|
+
|
77
|
+
def last_update_file_path
|
78
|
+
return File.join(@path, 'last_update')
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require_relative 'refinements/colored_strings'
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'highline'
|
2
|
+
|
3
|
+
module Grundstein
|
4
|
+
module Refinements
|
5
|
+
# Add namespaced refinement for the color scheme (we are not using HighLine's stuff like `ColorScheme` or `HighLine.colorize_strings`).
|
6
|
+
module ColoredStrings
|
7
|
+
refine String do
|
8
|
+
def c_gen
|
9
|
+
HighLine.color(self, :blue, :bold)
|
10
|
+
end
|
11
|
+
|
12
|
+
def c_info
|
13
|
+
HighLine.color(self, :green, :bold)
|
14
|
+
end
|
15
|
+
|
16
|
+
def c_warning
|
17
|
+
HighLine.color(self, :yellow, :bold)
|
18
|
+
end
|
19
|
+
|
20
|
+
def c_error
|
21
|
+
HighLine.color(self, :red, :bold)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'highline/import'
|
3
|
+
|
4
|
+
module Grundstein
|
5
|
+
# Entry point for the command line interface.
|
6
|
+
class Runner < Thor
|
7
|
+
using Grundstein::Refinements::ColoredStrings
|
8
|
+
|
9
|
+
desc :list, 'Lists all available generators.'
|
10
|
+
def list
|
11
|
+
Generator::Repository.instance.generators.each do |name|
|
12
|
+
gen = Generator::Loader.new(name)
|
13
|
+
puts " #{gen.name.ljust(20).c_gen} #{gen.desc}"
|
14
|
+
end
|
15
|
+
rescue Generator::GeneratorError => e
|
16
|
+
puts "ERROR: #{e.to_s.c_error}"
|
17
|
+
end
|
18
|
+
|
19
|
+
desc 'add NAME', 'Runs the given generator in the current directory.'
|
20
|
+
def add(generator_name)
|
21
|
+
generator = Generator::Loader.new(generator_name)
|
22
|
+
generator.run
|
23
|
+
rescue Generator::GeneratorError => e
|
24
|
+
puts "ERROR: #{e.to_s.c_error}"
|
25
|
+
# TODO: ask stuff (https://github.com/JEG2/highline)
|
26
|
+
# e.g.: gitignore will ask you if your intend to use Vagrant or Ruby or C...
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
metadata
ADDED
@@ -0,0 +1,191 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: grundstein
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tom Rothe
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-03-11 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: thor
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.19.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.19.1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: highline
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.7'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.7'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: mustache
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: git
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.3'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.3'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: bundler
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.7'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.7'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '10.0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '10.0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rubocop
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 0.37.2
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 0.37.2
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: sdoc
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 0.4.1
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 0.4.1
|
125
|
+
description: Grundstein automates adding common files by we adding (smart) templates.
|
126
|
+
E.g. add a Vagrantfile, a .gitignore, or a sinatra app.
|
127
|
+
email:
|
128
|
+
- info@tomrothe.de
|
129
|
+
executables:
|
130
|
+
- grundstein
|
131
|
+
extensions: []
|
132
|
+
extra_rdoc_files: []
|
133
|
+
files:
|
134
|
+
- ".gitignore"
|
135
|
+
- ".rubocop.yml"
|
136
|
+
- Gemfile
|
137
|
+
- LICENSE.txt
|
138
|
+
- README.Development.md
|
139
|
+
- README.md
|
140
|
+
- Rakefile
|
141
|
+
- Vagrantfile
|
142
|
+
- bin/grundstein
|
143
|
+
- generators/#vagrant/ask_for_ubuntu_or_fedora
|
144
|
+
- generators/rubocop/.rubocop.yml
|
145
|
+
- generators/rubocop/Gemfile
|
146
|
+
- generators/rubocop/README.Development.md
|
147
|
+
- generators/rubocop/Rakefile
|
148
|
+
- generators/rubocop/_generator.rb
|
149
|
+
- generators/sdoc/.gitignore
|
150
|
+
- generators/sdoc/Gemfile
|
151
|
+
- generators/sdoc/README.Development.md
|
152
|
+
- generators/sdoc/README.md
|
153
|
+
- generators/sdoc/Rakefile
|
154
|
+
- generators/sdoc/_generator.rb
|
155
|
+
- generators/sdoc/doc/.keep
|
156
|
+
- grundstein.gemspec
|
157
|
+
- lib/grundstein.rb
|
158
|
+
- lib/grundstein/generator.rb
|
159
|
+
- lib/grundstein/generator/environment.rb
|
160
|
+
- lib/grundstein/generator/errors.rb
|
161
|
+
- lib/grundstein/generator/loader.rb
|
162
|
+
- lib/grundstein/generator/repository.rb
|
163
|
+
- lib/grundstein/refinements.rb
|
164
|
+
- lib/grundstein/refinements/colored_strings.rb
|
165
|
+
- lib/grundstein/runner.rb
|
166
|
+
- lib/grundstein/version.rb
|
167
|
+
homepage: https://github.com/motine/grundstein
|
168
|
+
licenses:
|
169
|
+
- MIT
|
170
|
+
metadata: {}
|
171
|
+
post_install_message:
|
172
|
+
rdoc_options: []
|
173
|
+
require_paths:
|
174
|
+
- lib
|
175
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
176
|
+
requirements:
|
177
|
+
- - ">="
|
178
|
+
- !ruby/object:Gem::Version
|
179
|
+
version: '0'
|
180
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
181
|
+
requirements:
|
182
|
+
- - ">="
|
183
|
+
- !ruby/object:Gem::Version
|
184
|
+
version: '0'
|
185
|
+
requirements: []
|
186
|
+
rubyforge_project:
|
187
|
+
rubygems_version: 2.4.8
|
188
|
+
signing_key:
|
189
|
+
specification_version: 4
|
190
|
+
summary: Automates adding common files to your project.
|
191
|
+
test_files: []
|