basis 1.0.0 → 1.1.0

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.
@@ -1,3 +1,18 @@
1
+ === 1.1.0 / 2011-01-03
2
+
3
+ * Add 1.x rationale.
4
+ * Store original git URL and SHA in rendered projects.
5
+ * Add ill-conceived stab at hooks.
6
+ * Fix pattern matching on update and list.
7
+ * 'Improve' error handling.
8
+ * Don't require RubyGems.
9
+ * Use open4.
10
+ * Require Ruby >= 1.8.7.
11
+ * Update examples in --help.
12
+ * Add rename/mv.
13
+ * Remove useless colonification.
14
+ * Ignore coverage info.
15
+
1
16
  === 1.0.0 / 2010-07-21
2
17
 
3
18
  * Birthday!
@@ -6,6 +6,7 @@ Rakefile
6
6
  bin/basis
7
7
  lib/basis.rb
8
8
  lib/basis/context.rb
9
+ lib/basis/hooks.rb
9
10
  lib/basis/my.rb
10
11
  lib/basis/repo.rb
11
12
  lib/basis/template.rb
@@ -6,7 +6,8 @@
6
6
 
7
7
  Basis is a project skeleton generator.
8
8
 
9
- It'll have more docs at some point.
9
+ It'll have more docs at some point. 1.x releases of Basis are
10
+ primarily experiments in anticipation of a 2.0.
10
11
 
11
12
  == Examples
12
13
 
data/Rakefile CHANGED
@@ -1,14 +1,17 @@
1
1
  require "hoe"
2
2
 
3
- Hoe.plugin :doofus, :git
3
+ Hoe.plugin :doofus, :git, :isolate
4
4
 
5
5
  Hoe.spec "basis" do
6
6
  developer "John Barnette", "jbarnette@gmail.com"
7
7
 
8
+ require_ruby_version ">= 1.8.7"
9
+
8
10
  self.extra_rdoc_files = Dir["*.rdoc"]
9
11
  self.history_file = "CHANGELOG.rdoc"
10
12
  self.readme_file = "README.rdoc"
11
13
  self.testlib = :minitest
12
14
 
13
- extra_deps << ["erubis", ">= 2", "< 3"]
15
+ extra_deps << ["erubis", "~> 2.0"]
16
+ extra_deps << ["open4", "~> 1.0"]
14
17
  end
data/bin/basis CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "rubygems"
4
3
  require "basis"
5
4
  require "basis/context"
5
+ require "basis/hooks"
6
6
  require "basis/my"
7
7
  require "basis/repo"
8
8
  require "optparse"
@@ -17,13 +17,14 @@ require "optparse"
17
17
  add <git-url> [name] Register a template locally
18
18
  list, ls [pattern] List available templates
19
19
  remove, rm <name> Remove a template
20
+ rename, mv <old> <new> Rename a template
20
21
  update [pattern] Update local templates
21
22
 
22
- # add the 'gem:hoe' template
23
+ # add the 'gem-hoe' template
23
24
  $ basis add git://github.com/jbarnette/basis-gem-hoe.git
24
25
 
25
- # start a new project `foo' using the `gem:hoe' template
26
- $ basis gem:hoe foo
26
+ # start a new project `foo' using the `gem-hoe' template
27
+ $ basis gem-hoe foo
27
28
 
28
29
  Switches:
29
30
  END
@@ -36,7 +37,11 @@ def help
36
37
  end
37
38
 
38
39
  def help! message = nil
39
- warn "fatal: #{message}" if message
40
+ if message
41
+ message = "fatal: #{message}" if /^fatal/ !~ message
42
+ warn message
43
+ end
44
+
40
45
  abort @options.help
41
46
  end
42
47
 
@@ -61,34 +66,62 @@ rescue OptionParser::ParseError => e
61
66
  help! e.message
62
67
  end
63
68
 
69
+
70
+ if File.file?(hooks = File.expand_path("~/.basis/hooks.rb"))
71
+ Basis::Hooks.module_eval File.read(hooks), hooks, 1
72
+ end
73
+
64
74
  @repo = Basis::Repo.new
65
75
 
66
- # FIX: rescue
76
+ begin
77
+ case command = ARGV.shift
78
+ when "add" then
79
+ url, name = ARGV
80
+ help! "Need a url" unless url
81
+ @repo.add url, name
82
+
83
+ when "ls", "list" then
84
+ templates = @repo.templates ARGV.shift
85
+ width = templates.keys.map(&:length).max || 0
86
+ max = 80 - width - 5
87
+
88
+ templates.keys.sort.each do |name|
89
+ template = templates[name]
90
+ desc = template.description
91
+
92
+ if desc.length > max
93
+ desc = desc[0, max - 3] + "..."
94
+ end
67
95
 
68
- case command = ARGV.shift
69
- when "add" then
70
- url, name = ARGV
71
- help! "Need a url" unless url
72
- @repo.add url, name
96
+ printf "%-#{width}s # #{desc}\n", name
97
+ end
73
98
 
74
- when "ls", "list" then
75
- @repo.templates(ARGV.shift).each { |name, template| puts name }
99
+ when "mv", "rename" then
100
+ old, new = ARGV
76
101
 
77
- when "rm", "remove" then
78
- help! "Need a name" unless name = ARGV.shift
79
- @repo.remove name
102
+ help! "Need names!" unless old && new
103
+ @repo.rename old, new
80
104
 
81
- when "update" then
82
- @repo.update ARGV.shift
105
+ when "rm", "remove" then
106
+ help! "Need a name" unless name = ARGV.shift
107
+ @repo.remove name
83
108
 
84
- else
85
- template = @repo.templates[command]
109
+ when "update" then
110
+ @repo.update ARGV.shift
86
111
 
87
- help! "Unknown command or template: #{command}" unless template
88
- help! "Need a destination directory" unless destdir = ARGV.shift
112
+ else
113
+ help! unless command
114
+ template = @repo.templates[command]
89
115
 
90
- my = Basis::My.new File.basename(destdir)
91
- ctx = Basis::Context.new my, @overrides
116
+ help! "Unknown command or template: #{command}" unless template
117
+ help! "Need a destination directory" unless destdir = ARGV.shift
92
118
 
93
- template.render destdir, ctx
119
+ my = Basis::My.new File.basename(destdir)
120
+ ctx = Basis::Context.new my, @overrides
121
+
122
+ template.render destdir, ctx
123
+ Basis::Hooks.fire :rendered, destdir
124
+ end
125
+ rescue Basis::Oops => e
126
+ help! e.message
94
127
  end
@@ -1,3 +1,4 @@
1
1
  module Basis
2
- VERSION = "1.0.0"
2
+ VERSION = "1.1.0"
3
+ class Oops < StandardError; end
3
4
  end
@@ -0,0 +1,15 @@
1
+ module Basis
2
+ module Hooks
3
+ def self.fire name, *args
4
+ hooks[name].each { |h| h.call *args }
5
+ end
6
+
7
+ def self.hooks
8
+ @hooks ||= Hash.new { |h, k| h[k] = [] }
9
+ end
10
+
11
+ def self.on name, &block
12
+ hooks[name] << block
13
+ end
14
+ end
15
+ end
@@ -1,5 +1,7 @@
1
+ require "basis"
1
2
  require "basis/template"
2
3
  require "fileutils"
4
+ require "open4"
3
5
 
4
6
  module Basis
5
7
  class Repo
@@ -10,11 +12,10 @@ module Basis
10
12
  end
11
13
 
12
14
  def add url, name = nil
13
- name ||= File.basename(url, ".git").
14
- downcase.sub(/^basis[-_]/, "").tr "-", ":"
15
+ name ||= File.basename(url, ".git").downcase.sub(/^basis[-_]/, "")
15
16
 
16
17
  if templates.keys.include? name
17
- raise "Template '#{name}' already exists!"
18
+ raise Basis::Oops, "Template '#{name}' already exists!"
18
19
  end
19
20
 
20
21
  FileUtils.mkdir_p template_path
@@ -29,6 +30,14 @@ module Basis
29
30
  @templates = nil
30
31
  end
31
32
 
33
+ def rename old, new
34
+ unless File.directory? template_path(old)
35
+ raise Basis::Oops, "Unknown template: #{old}"
36
+ end
37
+
38
+ FileUtils.mv template_path(old), template_path(new)
39
+ end
40
+
32
41
  def templates pattern = nil
33
42
  unless @templates
34
43
  @templates = {}
@@ -41,20 +50,27 @@ module Basis
41
50
  end
42
51
  end
43
52
 
44
- Hash[@templates.select { |n, t| pattern.nil? || pattern =~ n }]
53
+ Hash[@templates.select { |n, t| pattern.nil? || /#{pattern}/ =~ n }]
45
54
  end
46
55
 
47
56
  def update pattern = nil
48
57
  templates.each do |name, template|
49
- next unless pattern.nil? || pattern =~ name
58
+ next unless pattern.nil? || /#{pattern}/ =~ name
50
59
  Dir.chdir(template.srcdir) { git :pull }
51
60
  end
52
61
  end
53
62
 
54
63
  private
55
64
 
56
- def git *args # FIX
57
- system "git", *args.map(&:to_s)
65
+ def git *args
66
+ out, err = nil
67
+
68
+ status = Open4.popen4 "git", *args.map(&:to_s) do |pid, sin, sout, serr|
69
+ out = sout.read.chomp
70
+ err = serr.read.chomp
71
+ end
72
+
73
+ raise Basis::Oops, err if 0 != status.exitstatus
58
74
  end
59
75
 
60
76
  def template_path *args
@@ -4,12 +4,34 @@ require "fileutils"
4
4
  module Basis
5
5
  class Template
6
6
  attr_reader :srcdir
7
+ attr_reader :origin
7
8
 
8
9
  def initialize srcdir
9
10
  @srcdir = File.expand_path srcdir
11
+
12
+ Dir.chdir @srcdir do
13
+ remote = `git remote -v`.split(/\s/)[1]
14
+ rev = `git rev-parse HEAD`
15
+ @origin = "#{remote}@#{rev}"
16
+ end
17
+
18
+ if File.exist?(template = "#@srcdir/.basis/template.rb")
19
+ src = IO.read template
20
+ extend eval("Module.new do;#{src};end", nil, template, 1)
21
+ end
22
+ end
23
+
24
+ def description
25
+ "An awesome template."
10
26
  end
11
27
 
12
28
  def render destdir, context
29
+ FileUtils.mkdir_p File.join(destdir, ".basis")
30
+
31
+ File.open File.join(destdir, ".basis", "origin"), "wb" do |f|
32
+ f.puts origin
33
+ end
34
+
13
35
  Dir.glob("#{srcdir}/**/*", File::FNM_DOTMATCH).each do |src|
14
36
  next unless File.file? src
15
37
 
@@ -3,7 +3,7 @@ require "basis/template"
3
3
 
4
4
  class BasisTemplateTest < MiniTest::Unit::TestCase
5
5
  def test_initialize
6
- t = Basis::Template.new "foo/bar"
7
- assert_equal "#{File.expand_path '.'}/foo/bar", t.srcdir
6
+ t = Basis::Template.new "test/fixtures/empty"
7
+ assert_equal "#{File.expand_path '.'}/test/fixtures/empty", t.srcdir
8
8
  end
9
9
  end
metadata CHANGED
@@ -1,13 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: basis
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
5
4
  prerelease: false
6
5
  segments:
7
6
  - 1
7
+ - 1
8
8
  - 0
9
- - 0
10
- version: 1.0.0
9
+ version: 1.1.0
11
10
  platform: ruby
12
11
  authors:
13
12
  - John Barnette
@@ -15,7 +14,7 @@ autorequire:
15
14
  bindir: bin
16
15
  cert_chain: []
17
16
 
18
- date: 2010-07-21 00:00:00 -07:00
17
+ date: 2011-01-03 00:00:00 -08:00
19
18
  default_executable:
20
19
  dependencies:
21
20
  - !ruby/object:Gem::Dependency
@@ -24,35 +23,27 @@ dependencies:
24
23
  requirement: &id001 !ruby/object:Gem::Requirement
25
24
  none: false
26
25
  requirements:
27
- - - ">="
26
+ - - ~>
28
27
  - !ruby/object:Gem::Version
29
- hash: 7
30
28
  segments:
31
29
  - 2
32
- version: "2"
33
- - - <
34
- - !ruby/object:Gem::Version
35
- hash: 5
36
- segments:
37
- - 3
38
- version: "3"
30
+ - 0
31
+ version: "2.0"
39
32
  type: :runtime
40
33
  version_requirements: *id001
41
34
  - !ruby/object:Gem::Dependency
42
- name: rubyforge
35
+ name: open4
43
36
  prerelease: false
44
37
  requirement: &id002 !ruby/object:Gem::Requirement
45
38
  none: false
46
39
  requirements:
47
- - - ">="
40
+ - - ~>
48
41
  - !ruby/object:Gem::Version
49
- hash: 7
50
42
  segments:
51
- - 2
43
+ - 1
52
44
  - 0
53
- - 4
54
- version: 2.0.4
55
- type: :development
45
+ version: "1.0"
46
+ type: :runtime
56
47
  version_requirements: *id002
57
48
  - !ruby/object:Gem::Dependency
58
49
  name: hoe
@@ -62,18 +53,18 @@ dependencies:
62
53
  requirements:
63
54
  - - ">="
64
55
  - !ruby/object:Gem::Version
65
- hash: 21
66
56
  segments:
67
57
  - 2
68
- - 6
69
- - 1
70
- version: 2.6.1
58
+ - 8
59
+ - 0
60
+ version: 2.8.0
71
61
  type: :development
72
62
  version_requirements: *id003
73
63
  description: |-
74
64
  Basis is a project skeleton generator.
75
65
 
76
- It'll have more docs at some point.
66
+ It'll have more docs at some point. 1.x releases of Basis are
67
+ primarily experiments in anticipation of a 2.0.
77
68
  email:
78
69
  - jbarnette@gmail.com
79
70
  executables:
@@ -93,6 +84,7 @@ files:
93
84
  - bin/basis
94
85
  - lib/basis.rb
95
86
  - lib/basis/context.rb
87
+ - lib/basis/hooks.rb
96
88
  - lib/basis/my.rb
97
89
  - lib/basis/repo.rb
98
90
  - lib/basis/template.rb
@@ -114,16 +106,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
114
106
  requirements:
115
107
  - - ">="
116
108
  - !ruby/object:Gem::Version
117
- hash: 3
118
109
  segments:
119
- - 0
120
- version: "0"
110
+ - 1
111
+ - 8
112
+ - 7
113
+ version: 1.8.7
121
114
  required_rubygems_version: !ruby/object:Gem::Requirement
122
115
  none: false
123
116
  requirements:
124
117
  - - ">="
125
118
  - !ruby/object:Gem::Version
126
- hash: 3
127
119
  segments:
128
120
  - 0
129
121
  version: "0"