lad 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in lad.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 James Hughes
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,68 @@
1
+ # Strapping Young Lad (or just Lad for short)
2
+
3
+ __Strapping Young Lad__ is a tokenised solution template substitution engine. A bit of a mouthful I know but it actually much simpler than it sounds (and hopefully much more useful that you'd think). So what does it do? Well running
4
+
5
+ lad /path/to/git/repo MyNewProject
6
+
7
+ Will do the following things,
8
+
9
+ 1. Clone the repo at `path/to/git/repo` into a temporary folder
10
+ 2. Remove the `.git` folder from the repo
11
+ 3. Check for the existence of a `.ladconfig` in the freshly cloned repo
12
+ - If one exists it loads the config setting
13
+ - Otherwise it falls back to the defaults
14
+ 4. Replace all instances of the configured token (eg. `__NAME__`) in all files, directories and file contents with the project name (in our case `MyNewProject`)
15
+ 5. Copy the new folder over to your current working directory (`./MyNewProject`)
16
+
17
+ What this allows you to do is have a standard project template for pretty much anything (.NET, Ruby, Scala - listen I mean anything - if it a collection of folders and files in a git repo then you set) and create a new instance with a few keystrokes - saving you time and potential RSI.
18
+
19
+ SYL was inspired by [WarmuP](https://github.com/chucknorris/warmup) which is itself a gem but it requires you to be running .NET which for a lot of my requirement isn't going to cut it.
20
+
21
+ ## Installation
22
+
23
+ Add this line to your application's Gemfile:
24
+
25
+ gem 'lad'
26
+
27
+ And then execute:
28
+
29
+ $ bundle
30
+
31
+ Or install it yourself as:
32
+
33
+ $ gem install lad
34
+
35
+ ## Usage
36
+
37
+ The example above shows you how to use the gem,
38
+
39
+ lad <PathToRepo> <ProjectName>
40
+
41
+ - `PathToRepo` is the git repository url that will be cloned
42
+ - `ProjectName` is the name of the project. This will replace the `__NAME__` token in the repository directories, files and contents
43
+
44
+ ## Configuring the engine via `.ladconfig`
45
+
46
+ SYL, once the repository has been cloned will check for the existence of file with the name `.ladconfig` from which it will load the settings. If it doesn't exist the default setting will be applied.
47
+
48
+ ### Configuration Options
49
+
50
+ - `token` - this is the token/indetifier that will be replaced in the template with the name of the project (defaults to `__NAME__`)
51
+ - `ignore` - a list of extensions that SYL will ignore when it comes to replacing CONTENTS. It will still RENAME the file if the file name includes the token. This allows us to ignore binary files whose contents should not change.
52
+
53
+ ## Contributing
54
+
55
+ 1. Fork it
56
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
57
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
58
+ 4. Push to the branch (`git push origin my-new-feature`)
59
+ 5. Create new Pull Request
60
+
61
+ ## Changes
62
+
63
+ 17 Apr 2012 - Version 0.0.1 released.
64
+
65
+ ## Roadmap
66
+
67
+ - __accept multiple tokens via command line or via interactive shell__
68
+ - zip support (generate project from zip file)
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
data/bin/lad ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+
3
+
4
+ require 'git'
5
+ require 'fileutils'
6
+ require 'colorize'
7
+ require 'tmpdir'
8
+
9
+ require 'console'
10
+ require 'parser'
11
+ require 'config'
12
+ require 'files'
13
+ require 'lad'
14
+
15
+ Lad::Bootstrapper.execute
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/lad/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["James Hughes"]
6
+ gem.email = ["james@yobriefca.se"]
7
+ gem.description = %q{Strapping Young Lad: Project Template Bootstrapper}
8
+ gem.summary = %q{Template generator and token switcher}
9
+ gem.homepage = ""
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "lad"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Lad::VERSION
17
+
18
+ gem.add_dependency('git')
19
+ gem.add_dependency('colorize')
20
+
21
+ gem.add_development_dependency('minitest')
22
+ end
@@ -0,0 +1,13 @@
1
+ module Lad
2
+ require 'yaml'
3
+ class Config
4
+ def self.load(dir, default_config)
5
+ config_file = File.join dir, '.ladconfig'
6
+ if File.exists?(config_file)
7
+ YAML.load_file config_file
8
+ else
9
+ default_config
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,30 @@
1
+ module Lad
2
+ class Console
3
+ def self.log msg
4
+ puts msg
5
+ end
6
+
7
+ def self.warn msg
8
+ puts msg.yellow
9
+ end
10
+
11
+ def self.error msg
12
+ puts msg.red
13
+ end
14
+
15
+ def self.success msg
16
+ puts msg.green
17
+ end
18
+
19
+ def self.task msg, &block
20
+ print " #{msg}".ljust(40)
21
+ begin
22
+ block.call
23
+ puts "OK".green
24
+ rescue Exception => e
25
+ puts "XX".red
26
+ raise e
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,28 @@
1
+ module Lad
2
+ class Files
3
+ def self.new_filename(item, token, name)
4
+ item_dir = File.dirname item
5
+ item_name = File.basename(item).gsub(token, name)
6
+
7
+ File.join item_dir, item_name
8
+ end
9
+
10
+ def self.delete_temporary_files(dir)
11
+ FileUtils.rm_rf dir if Dir.exists? dir
12
+ end
13
+
14
+ def self.clone_and_orphan(url, dir)
15
+ Git.clone url, dir
16
+ FileUtils.rm_rf File.join(dir, '.git')
17
+ end
18
+
19
+ def self.replace_token_in_file(exclusions, file, token, name)
20
+ if !exclusions.member?(File.extname file)
21
+ contents = File.read(file).gsub!(token, name)
22
+ File.open(file, 'w') { |f|
23
+ f.puts contents
24
+ }
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,57 @@
1
+ module Lad
2
+ class Bootstrapper
3
+ def self.execute
4
+ files_processed = 0
5
+ dirs_processed = 0
6
+ options = Arguments.extract
7
+ dir = File.join(Dir.tmpdir, options[:name])
8
+ config = {}
9
+
10
+ puts '' # insert new line padding
11
+
12
+ Console.task 'Cloning git repository' do
13
+ Files.delete_temporary_files(dir)
14
+ Files.clone_and_orphan(options[:git_url], dir)
15
+ end
16
+
17
+ Console.task 'Loading configuration' do
18
+ config = Config.load dir, {
19
+ token: '__NAME__', # we should support multiple tokens as well, but that appears to be more work
20
+ ignore: [
21
+ '.png', '.jpg', '.gif', '.cache', '.suo',
22
+ '.dll', '.zip', '.nupkg', '.pdb', '.exe'
23
+ ]
24
+ }
25
+ end
26
+
27
+ Console.task 'Processing files' do
28
+ Dir.glob(File.join dir, '**/*').each do |item|
29
+ if !File.directory?(item)
30
+ files_processed += 1
31
+ new_item = Files.new_filename item, config[:token], options[:name]
32
+ File.rename(item, new_item) if item != new_item
33
+
34
+ Files.replace_token_in_file config[:ignore], new_item, config[:token], options[:name]
35
+ end
36
+ end
37
+ end
38
+
39
+ Console.task 'Processing directories' do
40
+ Dir.glob(File.join dir, '**/*').each do |item|
41
+ if File.directory?(item)
42
+ dirs_processed += 1
43
+ new_item = Files.new_filename item, config[:token], options[:name]
44
+ File.rename(item, new_item) if item != new_item
45
+ end
46
+ end
47
+ end
48
+
49
+ Console.task 'Moving project files' do
50
+ File.rename dir, File.join(Dir.pwd, options[:name])
51
+ end
52
+
53
+ Console.success "\n Done processing #{files_processed} file(s)"
54
+ Console.success " Done processing #{dirs_processed} directories(s)"
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,3 @@
1
+ module Lad
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,10 @@
1
+ module Lad
2
+ class Arguments
3
+ def self.extract
4
+ return {
5
+ git_url: ARGV.first,
6
+ name: ARGV.last
7
+ }
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,45 @@
1
+ require 'minitest/autorun'
2
+ require 'tmpdir'
3
+ require 'fileutils'
4
+
5
+ require './lib/config' # SUT
6
+
7
+ describe Lad::Config do
8
+ before do
9
+ @dir = File.join Dir.tmpdir, (0..16).to_a.map{|a| rand(16).to_s(16)}.join
10
+ @file = File.join @dir, '.ladconfig'
11
+ @cfg = {
12
+ 'a_property' => 'property_value'
13
+ }
14
+
15
+ FileUtils.rm_rf @dir if Dir.exists? @dir
16
+ FileUtils.mkdir @dir
17
+ end
18
+
19
+ after do
20
+ FileUtils.rm_rf @dir
21
+ end
22
+
23
+ describe 'when loading a file that does not exist' do
24
+
25
+ before do
26
+ File.delete @file if File.exists? @file
27
+ end
28
+
29
+ it 'returns the default values' do
30
+ Lad::Config.load(@dir, @cfg)['a_property'].must_equal @cfg['a_property']
31
+ end
32
+ end
33
+
34
+ describe 'when loading a file that does exist' do
35
+ before do
36
+ File.open(@file, 'w') do |f|
37
+ f.puts '''a_property: file_value'''
38
+ end
39
+ end
40
+
41
+ it 'returns the values from that file' do
42
+ Lad::Config.load(@dir, @cfg)['a_property'].must_equal 'file_value'
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,63 @@
1
+ require 'minitest/autorun'
2
+ require 'tmpdir'
3
+
4
+ require './lib/files' # SUT
5
+
6
+ describe Lad::Files do
7
+ describe 'resolving the new file name' do
8
+ it 'replaces the token with the name in the filename only' do
9
+ Lad::Files.new_filename( '/var/tmp/__NAME__/__NAME__.sln', '__NAME__', 'Assertion').must_match '/var/tmp/__NAME__/Assertion.sln'
10
+ end
11
+
12
+ it 'will also replace tokens in the bottom most directory of a directory is passed' do
13
+ Lad::Files.new_filename('/var/tmp/__NAME__/__NAME__', '__NAME__', 'Assertion').must_match '/var/tmp/__NAME__/Assertion'
14
+ end
15
+
16
+ it 'will disregard a trailing slash on directory token replacement' do
17
+ Lad::Files.new_filename('/var/tmp/__NAME__/__NAME__/', '__NAME__', 'Assertion').must_match '/var/tmp/__NAME__/Assertion'
18
+ end
19
+
20
+ it 'will do nothing if the bottom most item hasn;t got the token' do
21
+ Lad::Files.new_filename('/var/tmp/__NAME__/__NAME__/Test.sln', '__NAME__', 'Assertion').must_match '/var/tmp/__NAME__/__NAME__/Test.sln'
22
+ end
23
+ end
24
+
25
+ describe 'replacing token in files' do
26
+
27
+ before do
28
+ @dir = File.join Dir.tmpdir, (0..16).to_a.map{|a| rand(16).to_s(16)}.join
29
+ @file = File.join @dir, 'targetfile.txt'
30
+ @cfg = {
31
+ 'a_property' => 'property_value'
32
+ }
33
+
34
+ FileUtils.rm_rf @dir if Dir.exists? @dir
35
+ FileUtils.mkdir @dir
36
+
37
+ @original = '''
38
+ lorem lorem __NAME__ lorem lorem
39
+ lorem __NAME__ lorem lorem lorem
40
+ '''
41
+ @expected = '''
42
+ lorem lorem Assertion lorem lorem
43
+ lorem Assertion lorem lorem lorem
44
+ '''
45
+
46
+ File.open(@file, 'w') { |f| f.puts @original }
47
+ end
48
+
49
+ after do
50
+ FileUtils.rm_rf @dir
51
+ end
52
+
53
+ it 'will replace all instances of the token in a file' do
54
+ Lad::Files.replace_token_in_file [], @file, '__NAME__', 'Assertion'
55
+ File.open(@file).read.must_match @expected
56
+ end
57
+
58
+ it 'will not replace any tokens if the files extension is excluded' do
59
+ Lad::Files.replace_token_in_file ['.txt'], @file, '__NAME__', 'Assertion'
60
+ File.open(@file).read.must_match @original
61
+ end
62
+ end
63
+ end
metadata ADDED
@@ -0,0 +1,96 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lad
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - James Hughes
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-04-17 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: git
16
+ requirement: &70226633976000 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70226633976000
25
+ - !ruby/object:Gem::Dependency
26
+ name: colorize
27
+ requirement: &70226633975380 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70226633975380
36
+ - !ruby/object:Gem::Dependency
37
+ name: minitest
38
+ requirement: &70226633974940 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70226633974940
47
+ description: ! 'Strapping Young Lad: Project Template Bootstrapper'
48
+ email:
49
+ - james@yobriefca.se
50
+ executables:
51
+ - lad
52
+ extensions: []
53
+ extra_rdoc_files: []
54
+ files:
55
+ - .gitignore
56
+ - Gemfile
57
+ - LICENSE
58
+ - README.md
59
+ - Rakefile
60
+ - bin/lad
61
+ - lad.gemspec
62
+ - lib/config.rb
63
+ - lib/console.rb
64
+ - lib/files.rb
65
+ - lib/lad.rb
66
+ - lib/lad/version.rb
67
+ - lib/parser.rb
68
+ - test/test_config.rb
69
+ - test/test_files.rb
70
+ homepage: ''
71
+ licenses: []
72
+ post_install_message:
73
+ rdoc_options: []
74
+ require_paths:
75
+ - lib
76
+ required_ruby_version: !ruby/object:Gem::Requirement
77
+ none: false
78
+ requirements:
79
+ - - ! '>='
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ requirements: []
89
+ rubyforge_project:
90
+ rubygems_version: 1.8.11
91
+ signing_key:
92
+ specification_version: 3
93
+ summary: Template generator and token switcher
94
+ test_files:
95
+ - test/test_config.rb
96
+ - test/test_files.rb