bundlegem 0.1.1 → 1.0.1.pre.rc.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 +4 -4
- data/README.md +53 -21
- data/bin/bundlegem +4 -5
- data/changelog +2 -22
- data/config/config +2 -2
- data/lib/bundlegem/cli/cli.rb +5 -0
- data/lib/bundlegem/cli/dir_to_template.rb +24 -0
- data/lib/bundlegem/cli/gem.rb +76 -38
- data/lib/bundlegem/cli.rb +1 -1
- data/lib/bundlegem/configurator.rb +9 -18
- data/lib/bundlegem/core/core.rb +9 -0
- data/lib/bundlegem/core/dir_to_template.rb +59 -0
- data/lib/bundlegem/strings.rb +6 -6
- data/lib/bundlegem/template_manager.rb +31 -25
- data/lib/bundlegem/templates/cli_gem/#{name}.gemspec.tt +23 -21
- data/lib/bundlegem/templates/template-test/#{name}/keep.tt +0 -0
- data/lib/bundlegem/templates/template-test/#{name}.rb.tt +19 -0
- data/lib/bundlegem/templates/template-test/#{underscored_name}/keep.tt +0 -0
- data/lib/bundlegem/templates/template-test/.vscode/launch.json.tt +0 -0
- data/lib/bundlegem/templates/template-test/bundlegem.yml +2 -0
- data/lib/bundlegem/templates/template-test/simple_dir/keep.tt +0 -0
- data/lib/bundlegem/templates/template-test/test_confirmed.tt +0 -0
- data/lib/bundlegem/templates/test_template/#{name}.rb.tt +8 -0
- data/lib/bundlegem/templates/test_template/bundlegem.yml +2 -0
- data/lib/bundlegem/version.rb +1 -1
- data/lib/bundlegem.rb +9 -27
- data/spec/bundlegem/core/dir_to_template_spec.rb +22 -0
- data/spec/bundlegem_spec.rb +57 -14
- data/spec/data/variable_manifest_test.rb +10 -2
- data/spec/spec_helper.rb +7 -5
- data/spec/template_manager_spec.rb +17 -0
- metadata +21 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4cfe0b3615f641b31c021924c843d79bf38bcde9c437620ff2469166be8a0e79
|
4
|
+
data.tar.gz: 3c530f05af2a8aa4aa89c99fa03590978d33d61b559437b5f9d78a74c52fe594
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2d7bb6ae37d62d13d0b4dd4e15fc0d916b39b00e1f9feaf520ceb4fcdf63159d221f648fd547fd63cb28b027c56cfc0bedeb46c60b132ae9d78d9a8d6c6fe9e8
|
7
|
+
data.tar.gz: 27b0d466cba63e6638547dc583645b411536068401658b9a27e106c60faf05fc922d3e3021f0d2158a987bc80f34f7fadad04d75e005ba643d7388c8e8a6d576
|
data/README.md
CHANGED
@@ -1,33 +1,45 @@
|
|
1
1
|
# BundleGem: A Gem Project Generator with User Defined Templates
|
2
|
-
|
3
|
-
Note: Alot of the code here was extracted from Bundler's `bundle gem` command, so credits to the Bundler folks. Originally I planned to make the new features accessible to the Bundler team and so tried to keep the code as similar to their project as possible, but ultimately discovered that they don't want to grow this feature because good tools should do a single thing very well (manage dependencies), not many things (manage dependencies and also do random other helpful stuff). Also it's a profoundly common dependency meaning every change is high stakes.
|
2
|
+
[](https://badge.fury.io/rb/bundlegem)
|
4
3
|
|
5
4
|
The goal of the project is to allow users to define templates in the most native form to all technologist: Directory Structures, short commands, and helpful commands which make the gem's usage completely visible!
|
6
5
|
|
7
|
-
The benefits of using this repo to create gems rather than bundler is that you can choose to create 'classes' of gems. By classes, I mean that there are different
|
6
|
+
The benefits of using this repo to create gems rather than bundler is that you can choose to create 'classes' of gems. By classes, I mean that there are different types of 'gems', there are basic library gems, that are just code and can only be used from other code, there are command line application gems, those are gems that are run on the command line and include a binary file, and there are also web interface gems, those are gems which spin up a simple web interface and request that the user connect to it's server on what ever port it has spun up on. Depending on your field of specialty, you may be able to imagine other classes of gems that will aid you in your work.
|
7
|
+
|
8
|
+
All of these 'classes of gems' as I refer to them, start out with a different code base, consistent with all other gems of the same class. This 'class based' approach to gem creation is different from the adaptive approach that other gem generators are based on.
|
8
9
|
|
9
|
-
|
10
|
+
The most beneficial aspect of this gem is that it allows you to specify exactly how you want your 'default starting gem' to look, rather than rely on what someone else thought would be generally helpful.
|
10
11
|
|
11
|
-
The most benificial aspect of this gem is that it allows users to specify exactly how they want their 'default starting gem' to look like, rather than rely on what someone else thought their default starting gem should look like.
|
12
12
|
|
13
|
-
### Installation
|
13
|
+
### Installation
|
14
14
|
|
15
15
|
First install it:
|
16
16
|
```
|
17
17
|
gem install bundlegem
|
18
18
|
```
|
19
19
|
|
20
|
-
|
20
|
+
### Configuration
|
21
|
+
|
22
|
+
Configuration comes from your gitconfig. At the user level, this is set at `~/.gitconfig`. These are the recommended minimal configurations to get the default templates to work ok:
|
23
|
+
|
21
24
|
```
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
Cloning base project structure into ~/.bundlegem/templates/my_service
|
27
|
-
...
|
28
|
-
Complete!
|
25
|
+
[user]
|
26
|
+
email = me@example.com
|
27
|
+
name = Me
|
28
|
+
repo-domain = github.com
|
29
29
|
```
|
30
|
-
|
30
|
+
|
31
|
+
|
32
|
+
### Usage
|
33
|
+
|
34
|
+
These commands will create a new gem named `project_name` in `/tmp/project_name`:
|
35
|
+
|
36
|
+
```
|
37
|
+
$ cd /tmp
|
38
|
+
$ bundlegem project_name -t arduino
|
39
|
+
```
|
40
|
+
|
41
|
+
|
42
|
+
### List Available Templates
|
31
43
|
|
32
44
|
```
|
33
45
|
$ bundlegem --list
|
@@ -40,26 +52,46 @@ MISC:
|
|
40
52
|
|
41
53
|
EMBEDDED:
|
42
54
|
arduino
|
43
|
-
|
44
55
|
```
|
45
56
|
|
46
|
-
You'll
|
57
|
+
You'll find a project skeleton in ~/.bundlegem/templates/my_service that you can customize to your liking.
|
58
|
+
|
47
59
|
|
60
|
+
### Create Your Own Template
|
61
|
+
|
62
|
+
You can create a new template for a project class you expect to use more than once:
|
48
63
|
|
49
|
-
Finally, create a new gem using your new gem template:
|
50
64
|
```
|
51
|
-
$
|
52
|
-
|
65
|
+
$ bundlegem --newtemplate
|
66
|
+
Specify a name for your gem template: my_service
|
67
|
+
Specify description:
|
68
|
+
Specify template tag name [MISC]:
|
69
|
+
Cloning base project structure into ~/.bundlegem/templates/my_service
|
70
|
+
...
|
71
|
+
Complete!
|
53
72
|
```
|
54
73
|
|
74
|
+
You can now get to work making changes to the my_service gem. All you need to know is that any file that ends in .tt in that folder will be copied into new projects when you create a new project based on that template, however the .tt extension will obviously be stripped out of the resulting file name.
|
75
|
+
|
76
|
+
## TODO: Did you actually implement this?
|
77
|
+
|
78
|
+
Also, you can specify the `category` of the gem by editing the .bundlegem file in each template's root. Categories are just used for organizing the output when you run `bundlegem --list`. Here, I'll show you an example:
|
79
|
+
|
80
|
+
|
55
81
|
## Customizing Your Own Templates
|
56
82
|
|
57
83
|
Place your own templates in `~/.bunglegem/templates`. You can populate it with examples by running `bundlegem --install-best-templates` which will effectively clone down a few sample git repos into the templates folder for you such as [Go-Cli](https://github.com/TheNotary/go-cli) for instance.
|
58
84
|
|
59
|
-
You'll get a good idea as to the possibilities by inspecting the files in [templates](https://github.com/TheNotary/bundlegem/tree/master/lib/bundlegem/templates/
|
85
|
+
You'll get a good idea as to the possibilities by inspecting the files in [templates](https://github.com/TheNotary/bundlegem/tree/master/lib/bundlegem/templates/cli_gem). Check out the [reference](/spec/data/variable_manifest_test.rb) test file to see what kind of interpolations are possible.
|
86
|
+
|
87
|
+
Quick Tips:
|
60
88
|
|
61
89
|
- Files ending with a `.tt` extension will by written to new projects
|
62
90
|
- File **names** containing `#{name}` will have that symbol replaced by the project name defined on the CLI
|
63
91
|
- Within files, use `<%=config[:namespaced_path]%>` to have that reinterpreted as just the file name with underscores
|
64
92
|
- Have a look [under the hood](https://github.com/TheNotary/bundlegem/blob/master/lib/bundlegem/cli/gem.rb#L30-L43) to see other options and the context where the ERB.new takes place.
|
65
93
|
|
94
|
+
|
95
|
+
### Gem Backstory
|
96
|
+
|
97
|
+
A lot of the code here was extracted from Bundler's `bundle gem` command, so credits to the Bundler folks. Originally I planned to make the new features accessible to the Bundler team and went out of my way to keep the code as similar to their project as possible, but ultimately realized two thing. First they don't want to grow the project creation feature because good tools should do a single thing very well (manage dependencies), not many things (manage dependencies and also do random other helpful stuff). And second Bundler is a profoundly common dependency meaning every change is enormously high stakes.
|
data/bin/bundlegem
CHANGED
@@ -28,14 +28,13 @@ if ARGV[0] == "--version" or ARGV[0] == "-v"
|
|
28
28
|
exit 0
|
29
29
|
end
|
30
30
|
|
31
|
-
if ARGV[0] == "--
|
32
|
-
|
31
|
+
if ARGV[0] == "--install-best-templates"
|
32
|
+
Bundlegem.install_best_templates
|
33
33
|
exit 0
|
34
|
-
Bundlegem.newtemplate(ARGV)
|
35
34
|
end
|
36
35
|
|
37
|
-
if ARGV[0] == "--
|
38
|
-
Bundlegem.
|
36
|
+
if ARGV[0] == "--to-template"
|
37
|
+
Bundlegem.dir_to_template
|
39
38
|
exit 0
|
40
39
|
end
|
41
40
|
|
data/changelog
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
** 0.0.x **
|
2
2
|
- Add prompt "Would you care to summarize your gem for documentation purposes? (y/[n])
|
3
3
|
- Add prompt for specifying java package org name
|
4
|
-
- CMD: --newtemplate to start new template
|
5
|
-
- I'll need to write a basic starter template that is educational
|
6
4
|
- Why have more than one built in template? Only one is needed for testing, the rest should
|
7
5
|
be pulled from the web and made easily customizable by the users.
|
6
|
+
- Is thor used in this project or not???
|
8
7
|
|
9
|
-
Completed on
|
8
|
+
Completed on main:
|
10
9
|
- Nothing yet
|
11
10
|
|
12
11
|
** 0.0.14 **
|
@@ -21,24 +20,16 @@ Completed on Master:
|
|
21
20
|
- Feature: java project template added to best templates
|
22
21
|
- Feature: python project template added to best templates
|
23
22
|
|
24
|
-
|
25
|
-
|
26
23
|
** 0.0.11 **
|
27
24
|
- Bugfix: config[:bundler_version] was listing the version of bundlegem not bundler
|
28
25
|
|
29
|
-
|
30
|
-
|
31
26
|
** 0.0.10 **
|
32
27
|
- Feature: tweaks built-in templates
|
33
28
|
|
34
|
-
|
35
|
-
|
36
29
|
** 0.0.9 **
|
37
30
|
- Bugfix: there were misconfigurations with the Rakefiles for cli_gems and c_ect gems that were corrected
|
38
31
|
- Feature: `--version` option added
|
39
32
|
|
40
|
-
|
41
|
-
|
42
33
|
** 0.0.8 **
|
43
34
|
|
44
35
|
- Bugfix: fixes bug where git clone was attempted even when the a clone
|
@@ -49,8 +40,6 @@ Completed on Master:
|
|
49
40
|
--install-best-templates
|
50
41
|
- Bugfix: fixes bug where require pry was left in
|
51
42
|
|
52
|
-
|
53
|
-
|
54
43
|
** 0.0.7 **
|
55
44
|
|
56
45
|
- Feature: Ability to load templates from github via --install-best-templates
|
@@ -64,8 +53,6 @@ Completed on Master:
|
|
64
53
|
- Bugfix: cli_gem and c_ext_gem now show up in the list
|
65
54
|
- Bugfix: cli_gem and c_ext_gem had typos fixed
|
66
55
|
|
67
|
-
|
68
|
-
|
69
56
|
** 0.0.6 **
|
70
57
|
- Feature: List now indicates default template
|
71
58
|
- CORE: Created TemplateManager for working with templates
|
@@ -73,8 +60,6 @@ Completed on Master:
|
|
73
60
|
change directory into a test area for creating new gems.
|
74
61
|
- BUG: newgem template didn't have a dot in .gitignore.tt
|
75
62
|
|
76
|
-
|
77
|
-
|
78
63
|
** 0.0.5 **
|
79
64
|
- Bug in 0.0.3 that broke building template gems fixed
|
80
65
|
* Template Directories part of code was being skipped for built in templates, but not all of it
|
@@ -82,26 +67,21 @@ Completed on Master:
|
|
82
67
|
- Added integration test just to make sure the built-in templates can be generated without problems
|
83
68
|
- Cleaned up internal API and how the binary works
|
84
69
|
|
85
|
-
|
86
70
|
** 0.0.4 **
|
87
71
|
- Tell the user what files are being created
|
88
72
|
- Created config['git_repo_url'] variable to be used in templates
|
89
73
|
|
90
|
-
|
91
74
|
** 0.0.3 **
|
92
75
|
- CMD: --list to list templates (with descriptions)
|
93
76
|
- Raise error when project name already exists, do not overwrite!
|
94
77
|
- Raises error if none of the files in the template directory end in .tt
|
95
78
|
- Create even empty folders
|
96
79
|
|
97
|
-
|
98
80
|
** 0.0.2 **
|
99
81
|
- Added default gem template 'service'
|
100
82
|
- Better syntax of bundlegem gem_name -t template_name
|
101
83
|
- CMD: --help to display a help message
|
102
84
|
|
103
|
-
|
104
85
|
** 0.0.1 **
|
105
86
|
- Very basic prototype that allows you to specify templates in
|
106
87
|
~/.bundlegem/templates
|
107
|
-
|
data/config/config
CHANGED
@@ -1,4 +1,4 @@
|
|
1
1
|
# Comments made to this file will not be preserved
|
2
2
|
---
|
3
|
-
default_template:
|
4
|
-
best_templates: https://github.com/TheNotary/
|
3
|
+
default_template: cli_gem
|
4
|
+
best_templates: https://github.com/TheNotary/template-ruby-cli-gem https://github.com/TheNotary/template-arduino.git https://github.com/TheNotary/template-raspberry-pi-c.git https://github.com/TheNotary/docker_repo.git https://github.com/TheNotary/template-html-css-js.git https://github.com/TheNotary/template-java-gradle-cli-app https://github.com/TheNotary/template-python-library
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'find'
|
2
|
+
|
3
|
+
|
4
|
+
module Bundlegem::Cli::DirToTemplate
|
5
|
+
class << self
|
6
|
+
|
7
|
+
def go
|
8
|
+
validate_working_directory!
|
9
|
+
file_enumerator = Find.find('.')
|
10
|
+
|
11
|
+
Bundlegem::Core::DirToTemplate.🧙🪄! file_enumerator
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def validate_working_directory!
|
17
|
+
# check for the existence of a .bundlegem file which won't ordinarily exist
|
18
|
+
if !File.exist?(".bundlegem")
|
19
|
+
raise "error: .bundlegem file not found in current directory. Create it or run this command in the folder you thought you were in."
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
data/lib/bundlegem/cli/gem.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'pathname'
|
2
|
+
require 'yaml'
|
2
3
|
|
3
4
|
module Bundlegem
|
4
5
|
class CLI::Gem
|
@@ -10,29 +11,57 @@ module Bundlegem
|
|
10
11
|
|
11
12
|
@name = @gem_name
|
12
13
|
@target = Pathname.pwd.join(gem_name)
|
14
|
+
@template_src = TemplateManager.get_template_src(options)
|
15
|
+
|
16
|
+
@tconf = load_template_configs
|
13
17
|
|
14
18
|
validate_ext_name if options[:ext]
|
15
19
|
end
|
16
20
|
|
17
21
|
def build_interpolation_config
|
22
|
+
pascal_name = name.tr('-', '_').split('_').map(&:capitalize).join
|
23
|
+
unprefixed_name = name.sub(/^#{@tconf[:prefix]}/, '')
|
18
24
|
underscored_name = name.tr('-', '_')
|
19
|
-
namespaced_path = name.tr('-', '/')
|
20
25
|
constant_name = name.split('_').map{|p| p[0..0].upcase + p[1..-1] unless p.empty?}.join
|
21
26
|
constant_name = constant_name.split('-').map{|q| q[0..0].upcase + q[1..-1] }.join('::') if constant_name =~ /-/
|
22
27
|
constant_array = constant_name.split('::')
|
23
28
|
git_user_name = `git config user.name`.chomp
|
24
29
|
git_user_email = `git config user.email`.chomp
|
25
30
|
|
31
|
+
# domain = provider.com
|
32
|
+
git_repo_domain = `git config user.repo-domain`.chomp
|
33
|
+
|
34
|
+
if git_repo_domain.empty?
|
35
|
+
git_repo_domain = "github.com"
|
36
|
+
end
|
37
|
+
|
38
|
+
if git_user_name.empty?
|
39
|
+
raise "git config user.name didn't return a value. Please double check your username configurations in ~/.gitconfig"
|
40
|
+
else
|
41
|
+
# path = provider.com/user/name
|
42
|
+
git_repo_path = "#{git_repo_domain}/#{git_user_name}/#{name}".downcase # downcasing for languages like go that are creative
|
43
|
+
end
|
44
|
+
|
45
|
+
# url = https://provider.com/user/name
|
46
|
+
git_repo_url = "https://#{git_repo_domain}/#{git_user_name}/#{name}"
|
47
|
+
|
26
48
|
config = {
|
27
49
|
:name => name,
|
50
|
+
:unprefixed_name => unprefixed_name,
|
51
|
+
:unprefixed_pascal=> unprefixed_name.tr('-', '_').split('_').map(&:capitalize).join,
|
28
52
|
:underscored_name => underscored_name,
|
29
|
-
:
|
53
|
+
:pascal_name => pascal_name,
|
54
|
+
:camel_name => pascal_name.sub(/^./, &:downcase),
|
55
|
+
:screamcase_name => name.tr('-', '_').upcase,
|
56
|
+
:namespaced_path => name.tr('-', '/'),
|
30
57
|
:makefile_path => "#{underscored_name}/#{underscored_name}",
|
31
58
|
:constant_name => constant_name,
|
32
59
|
:constant_array => constant_array,
|
33
60
|
:author => git_user_name.empty? ? "TODO: Write your name" : git_user_name,
|
34
61
|
:email => git_user_email.empty? ? "TODO: Write your email address" : git_user_email,
|
35
|
-
:
|
62
|
+
:git_repo_domain => git_repo_domain,
|
63
|
+
:git_repo_url => git_repo_url,
|
64
|
+
:git_repo_path => git_repo_path,
|
36
65
|
:template => options[:template],
|
37
66
|
:test => options[:test],
|
38
67
|
:ext => options[:ext],
|
@@ -52,7 +81,7 @@ module Bundlegem
|
|
52
81
|
|
53
82
|
template_src = match_template_src
|
54
83
|
template_directories = dynamically_generate_template_directories
|
55
|
-
templates =
|
84
|
+
templates = dynamically_generate_templates_files
|
56
85
|
|
57
86
|
puts "Creating new project folder '#{name}'\n\n"
|
58
87
|
create_template_directories(template_directories, target)
|
@@ -64,27 +93,38 @@ module Bundlegem
|
|
64
93
|
# Bundler.ui.info "Initializing git repo in #{target}"
|
65
94
|
Dir.chdir(target) { `git init`; `git add .` }
|
66
95
|
|
67
|
-
# Disabled thanks to removal of thor, might not be helpful...
|
68
|
-
#if options[:edit]
|
69
|
-
# # Open gemspec in editor
|
70
|
-
#
|
71
|
-
# # thor.run("#{options["edit"]} \"#{target.join("#{name}.gemspec")}\"")
|
72
|
-
#end
|
73
|
-
|
74
96
|
puts "\nComplete."
|
75
97
|
end
|
76
98
|
|
77
99
|
private
|
78
100
|
|
101
|
+
def load_template_configs
|
102
|
+
template_config_path = File.join(@template_src, "bundlegem.yml")
|
103
|
+
if File.exist?(template_config_path)
|
104
|
+
t_config = YAML.load_file(template_config_path, symbolize_names: true)
|
105
|
+
else
|
106
|
+
t_config = {
|
107
|
+
purpose: "tool",
|
108
|
+
language: "go"
|
109
|
+
}
|
110
|
+
end
|
111
|
+
|
112
|
+
if t_config[:prefix].nil?
|
113
|
+
t_config[:prefix] = t_config[:purpose] ? "#{t_config[:purpose]}-" : ""
|
114
|
+
t_config[:prefix] += t_config[:language] ? "#{t_config[:language]}-" : ""
|
115
|
+
end
|
116
|
+
|
117
|
+
t_config
|
118
|
+
end
|
119
|
+
|
79
120
|
# Returns a hash of source directory names and their destination mappings
|
80
121
|
def dynamically_generate_template_directories
|
81
|
-
template_src = TemplateManager.get_template_src(options)
|
82
|
-
|
83
122
|
template_dirs = {}
|
84
|
-
Dir.glob("#{template_src}/**/*").each do |f|
|
123
|
+
Dir.glob("#{@template_src}/**/*", File::FNM_DOTMATCH).each do |f|
|
124
|
+
next if f == "#{@template_src}/." || f == "#{@template_src}/.."
|
85
125
|
next unless File.directory? f
|
86
|
-
base_path = f[template_src.length+1..-1]
|
87
|
-
template_dirs.merge!(base_path => base_path
|
126
|
+
base_path = f[@template_src.length+1..-1]
|
127
|
+
template_dirs.merge!(base_path => substitute_template_values(base_path))
|
88
128
|
end
|
89
129
|
template_dirs
|
90
130
|
end
|
@@ -108,7 +148,6 @@ module Bundlegem
|
|
108
148
|
'bin/console.tt' => "bin/console"
|
109
149
|
}
|
110
150
|
|
111
|
-
|
112
151
|
prompt_coc!(templates)
|
113
152
|
prompt_mit!(templates, config)
|
114
153
|
prompt_test_framework!(templates, config)
|
@@ -125,19 +164,24 @@ module Bundlegem
|
|
125
164
|
templates
|
126
165
|
end
|
127
166
|
|
167
|
+
# Applies every possible substitution within config to the fs_obj_name
|
168
|
+
def substitute_template_values(fs_obj_name)
|
169
|
+
config.keys.inject(fs_obj_name) do |accu, key|
|
170
|
+
if config[key].class == String
|
171
|
+
accu.gsub(/\#\{#{key.to_s}\}/, config[key])
|
172
|
+
else
|
173
|
+
accu
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
128
178
|
# Figures out the translation between all the .tt file to their
|
129
179
|
# destination names
|
130
|
-
def
|
131
|
-
template_src = TemplateManager.get_template_src(options)
|
132
|
-
|
180
|
+
def dynamically_generate_templates_files
|
133
181
|
templates = {}
|
134
|
-
Dir.glob("#{template_src}
|
135
|
-
base_path = f[template_src.length+1..-1]
|
136
|
-
templates.merge!(base_path => base_path
|
137
|
-
.gsub(/\.tt$/, "")
|
138
|
-
.gsub('#{name}', "#{name}")
|
139
|
-
.gsub('#{underscored_name}', config[:underscored_name])
|
140
|
-
)
|
182
|
+
Dir.glob("#{@template_src}/**/*.tt", File::FNM_DOTMATCH).each do |f|
|
183
|
+
base_path = f[@template_src.length+1..-1]
|
184
|
+
templates.merge!( base_path => substitute_template_values(base_path).sub(/\.tt$/, "") )
|
141
185
|
end
|
142
186
|
|
143
187
|
raise_no_files_in_template_error! if templates.empty?
|
@@ -164,12 +208,10 @@ module Bundlegem
|
|
164
208
|
end
|
165
209
|
end
|
166
210
|
|
167
|
-
|
168
211
|
def resolve_name(name)
|
169
212
|
Pathname.pwd.join(name).basename.to_s
|
170
213
|
end
|
171
214
|
|
172
|
-
|
173
215
|
def validate_ext_name
|
174
216
|
return unless gem_name.index('-')
|
175
217
|
|
@@ -180,7 +222,6 @@ module Bundlegem
|
|
180
222
|
exit 1
|
181
223
|
end
|
182
224
|
|
183
|
-
|
184
225
|
def bundler_dependency_version
|
185
226
|
v = Gem::Version.new(Bundler::VERSION)
|
186
227
|
req = v.segments[0..1]
|
@@ -189,9 +230,6 @@ module Bundlegem
|
|
189
230
|
end
|
190
231
|
|
191
232
|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
233
|
#
|
196
234
|
# EDIT: Reworked from Thor to not rely on Thor (or do so much unneeded stuff)
|
197
235
|
#
|
@@ -247,7 +285,7 @@ but no files within it ended in .tt. Did you forget to rename the extensions of
|
|
247
285
|
Exiting...
|
248
286
|
HEREDOC
|
249
287
|
puts err_no_files_in_template
|
250
|
-
|
288
|
+
raise
|
251
289
|
end
|
252
290
|
|
253
291
|
def raise_project_with_that_name_already_exists!
|
@@ -258,14 +296,14 @@ Can't make project. Either delete that folder or choose a new project name
|
|
258
296
|
Exiting...
|
259
297
|
HEREDOC
|
260
298
|
puts err_project_with_that_name_exists
|
261
|
-
|
299
|
+
raise
|
262
300
|
end
|
263
301
|
|
264
302
|
def raise_template_not_found!
|
265
303
|
err_missing_template = "Could not find template folder '#{options["template"]}' in `~/.bundle/templates/`. Please check to make sure your desired template exists."
|
266
304
|
puts err_missing_template
|
267
305
|
Bundler.ui.error err_missing_template
|
268
|
-
|
306
|
+
raise
|
269
307
|
end
|
270
308
|
|
271
309
|
|
@@ -357,10 +395,10 @@ Exiting...
|
|
357
395
|
def ensure_safe_gem_name(name, constant_array)
|
358
396
|
if name =~ /^\d/
|
359
397
|
Bundler.ui.error "Invalid gem name #{name} Please give a name which does not start with numbers."
|
360
|
-
|
398
|
+
raise
|
361
399
|
elsif Object.const_defined?(constant_array.first)
|
362
400
|
Bundler.ui.error "Invalid gem name #{name} constant #{constant_array.join("::")} is already in use. Please choose another gem name."
|
363
|
-
|
401
|
+
raise
|
364
402
|
end
|
365
403
|
end
|
366
404
|
|
data/lib/bundlegem/cli.rb
CHANGED
@@ -113,7 +113,7 @@ module Bundlegem
|
|
113
113
|
method_option :mit, :type => :boolean, :desc => "Generate an MIT license file"
|
114
114
|
method_option :test, :type => :string, :lazy_default => 'rspec', :aliases => '-t', :banner => "rspec",
|
115
115
|
:desc => "Generate a test directory for your library, either rspec or minitest. Set a default with `bundle config gem.test rspec`."
|
116
|
-
method_option :template, :type => :string, :lazy_default => "
|
116
|
+
method_option :template, :type => :string, :lazy_default => "cli_gem", :aliases => '-u', :banner => "default", :desc => "Generate a gem based on the user's predefined template."
|
117
117
|
def gem(name)
|
118
118
|
# options = {"bin"=>false, "ext"=>false}
|
119
119
|
# name = "gem_name"
|
@@ -4,7 +4,7 @@ require 'yaml'
|
|
4
4
|
module Bundlegem
|
5
5
|
|
6
6
|
class Configurator
|
7
|
-
attr_accessor :
|
7
|
+
attr_accessor :config_file_data
|
8
8
|
|
9
9
|
def initialize
|
10
10
|
@config_directory_root = "#{ENV['HOME']}/.bundlegem"
|
@@ -13,9 +13,6 @@ module Bundlegem
|
|
13
13
|
|
14
14
|
create_config_file_if_needed!
|
15
15
|
|
16
|
-
@user_defined_templates = get_user_defined_templates
|
17
|
-
@user_downloaded_templates = get_user_downloaded_templates
|
18
|
-
|
19
16
|
# load configurations from config file
|
20
17
|
@config_file_data = YAML.load_file @config_file
|
21
18
|
end
|
@@ -29,16 +26,7 @@ module Bundlegem
|
|
29
26
|
File.write(@config_file, "# Comments made to this file will not be preserved\n#{YAML.dump(@config_file_data)}")
|
30
27
|
end
|
31
28
|
|
32
|
-
def
|
33
|
-
|
34
|
-
end
|
35
|
-
|
36
|
-
# not implemented yet
|
37
|
-
def get_user_downloaded_templates
|
38
|
-
[]
|
39
|
-
end
|
40
|
-
|
41
|
-
def get_user_defined_templates
|
29
|
+
def collect_user_defined_templates
|
42
30
|
user_definition_directory = @user_defined_templates_path
|
43
31
|
template_dirs = Dir.entries(user_definition_directory).select do |entry|
|
44
32
|
File.directory?(File.join(user_definition_directory, entry)) and !(entry =='.' || entry == '..')
|
@@ -51,20 +39,23 @@ module Bundlegem
|
|
51
39
|
|
52
40
|
begin
|
53
41
|
f = File.read("#{@user_defined_templates_path}/#{dir}/.bundlegem")
|
54
|
-
/category:\s*([\w\s]*$)/ =~ f
|
55
42
|
|
56
|
-
category =
|
43
|
+
category = parse_out(:category, f)
|
57
44
|
rescue
|
58
45
|
category = "MISC"
|
59
46
|
end
|
60
47
|
|
61
48
|
category = "MISC" if category.nil?
|
62
|
-
|
63
|
-
pairs << {category => dir }
|
49
|
+
pairs << {category => dir.sub(/^template-/, "") }
|
64
50
|
end
|
65
51
|
pairs
|
66
52
|
end
|
67
53
|
|
54
|
+
def parse_out(key, config_txt)
|
55
|
+
/#{key.to_s}:\s*([\w\s]*$)/ =~ config_txt
|
56
|
+
$1.chomp
|
57
|
+
end
|
58
|
+
|
68
59
|
def create_config_file_if_needed!
|
69
60
|
FileUtils.mkdir_p @user_defined_templates_path
|
70
61
|
FileUtils.cp("#{SOURCE_ROOT}/config/config", @config_file) unless File.exist? @config_file
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# This is the core logic for the app. CLI stuff should eventually get pulled
|
2
|
+
# out so the app is neat and the way I do CLI stuff lately.
|
3
|
+
module Bundlegem::Core
|
4
|
+
end
|
5
|
+
|
6
|
+
# I saw someone on the internet do requires this way so am giving it a spin :)
|
7
|
+
# It's a little odd, right? I'm not sure I like it yet but lets me go to
|
8
|
+
# town on namespaces and `class << self` definitions if I want...
|
9
|
+
require 'bundlegem/core/dir_to_template'
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'find'
|
2
|
+
require 'open3'
|
3
|
+
require 'shellwords'
|
4
|
+
|
5
|
+
|
6
|
+
module Bundlegem::Core::DirToTemplate
|
7
|
+
class << self
|
8
|
+
|
9
|
+
# Takes in a file_enumerator such as Find.find('.') and
|
10
|
+
# renames all the files
|
11
|
+
def 🧙🪄! file_enumerator, template_name: "asdf-pkg", dry_run: false
|
12
|
+
files_changed = []
|
13
|
+
file_enumerator.each do |path|
|
14
|
+
next if should_skip?(path)
|
15
|
+
|
16
|
+
conduct_pkg_name_to_template_variable_replacements!(path)
|
17
|
+
|
18
|
+
new_path = "#{path}.tt"
|
19
|
+
File.rename(path, new_path) unless dry_run
|
20
|
+
files_changed << "Renamed: #{path} -> #{new_path}"
|
21
|
+
end
|
22
|
+
files_changed
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def conduct_pkg_name_to_template_variable_replacements!(path)
|
28
|
+
# TODO: Conduct text replacements:
|
29
|
+
#
|
30
|
+
# 'asdf-pkg' -> '<%=config[:name]%>'
|
31
|
+
# 'asdf_pkg' -> '<%=config[:underscored_name]%>'
|
32
|
+
# 'ASDF_PKG' -> '<%=config[:screamcase_name]%>'
|
33
|
+
end
|
34
|
+
|
35
|
+
def should_skip?(path)
|
36
|
+
return false if path == "./.gitignore" && !File.exist?("#{path}.tt")
|
37
|
+
|
38
|
+
!File.file?(path) || # skip directories
|
39
|
+
path.end_with?('.tt') || # skip if the file is a .tt already
|
40
|
+
File.exist?("#{path}.tt") || # skip if a .tt variant of this file exists
|
41
|
+
path.start_with?('./.git') || # skip the .git directory
|
42
|
+
ignored_by_git?(path) || # skip things that are gitignored
|
43
|
+
path == "./.bundlegem" # skip the .bundlegem file
|
44
|
+
end
|
45
|
+
|
46
|
+
def validate_working_directory!
|
47
|
+
# check for the existence of a .bundlegem file which won't ordinarily exist
|
48
|
+
if !File.exist?(".bundlegem")
|
49
|
+
raise "error: .bundlegem file not found in current directory. Create it or run this command in the folder you thought you were in."
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def ignored_by_git?(path)
|
54
|
+
stdout, _, status = Open3.capture3("git check-ignore #{Shellwords.escape(path)}")
|
55
|
+
status.success? && !stdout.strip.empty?
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|