coherent 0.3.0 → 0.4.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.
Files changed (44) hide show
  1. data/LICENSE +7 -1
  2. data/VERSION +1 -1
  3. data/app_generators/coherent/templates/distil.yml.erb +1 -1
  4. data/app_generators/coherent/templates/src/css/@name@.css.erb +26 -26
  5. data/bin/coherent +4 -0
  6. data/coherent.gemspec +20 -16
  7. data/demo_generators/gallery/templates/distil.yml.erb +1 -1
  8. data/demo_generators/gallery/templates/src/css/@name@.css.erb +26 -26
  9. data/lib/distilery.rb +1 -1
  10. data/lib/distilery/bundle-task.rb +37 -0
  11. data/lib/distilery/coherent-asset-filter.rb +2 -2
  12. data/lib/distilery/nib-file.rb +1 -1
  13. data/lib/plugin.rb +83 -0
  14. data/lib/plugin/commands.rb +12 -0
  15. data/lib/plugin/commands/discover.rb +78 -0
  16. data/lib/plugin/commands/info.rb +29 -0
  17. data/lib/plugin/commands/install.rb +76 -0
  18. data/lib/plugin/commands/list.rb +55 -0
  19. data/lib/plugin/commands/plugin.rb +105 -0
  20. data/lib/plugin/commands/remove.rb +29 -0
  21. data/lib/plugin/commands/source.rb +34 -0
  22. data/lib/plugin/commands/sources.rb +33 -0
  23. data/lib/plugin/commands/unsource.rb +36 -0
  24. data/lib/plugin/commands/update.rb +42 -0
  25. data/lib/plugin/environment.rb +97 -0
  26. data/lib/plugin/plugin.rb +160 -0
  27. data/lib/plugin/recursive-http-fetcher.rb +71 -0
  28. data/lib/plugin/repositories.rb +92 -0
  29. data/lib/plugin/repository.rb +36 -0
  30. metadata +20 -16
  31. data/generators/gallery_sample/USAGE +0 -5
  32. data/generators/gallery_sample/gallery_sample_generator.rb +0 -48
  33. data/generators/gallery_sample/templates/src/nibs/@name@/@name@.css +0 -116
  34. data/generators/gallery_sample/templates/src/nibs/@name@/@name@.html +0 -6
  35. data/generators/gallery_sample/templates/src/nibs/@name@/@name@.jsnib.erb +0 -40
  36. data/generators/gallery_sample/templates/src/nibs/@name@/@name@.json +0 -25
  37. data/generators/gallery_sample/templates/src/nibs/@name@/images/next.gif +0 -0
  38. data/generators/gallery_sample/templates/src/nibs/@name@/images/prev.gif +0 -0
  39. data/generators/gallery_sample/templates/src/nibs/@name@/photos/molly-1.jpg +0 -0
  40. data/generators/gallery_sample/templates/src/nibs/@name@/photos/molly-2.jpg +0 -0
  41. data/generators/gallery_sample/templates/src/nibs/@name@/photos/molly-3.jpg +0 -0
  42. data/generators/gallery_sample/templates/src/nibs/@name@/photos/molly-4.jpg +0 -0
  43. data/generators/gallery_sample/templates/src/nibs/@name@/photos/molly-5.jpg +0 -0
  44. data/lib/distilery/nib-task.rb +0 -83
@@ -0,0 +1,29 @@
1
+ module Coherent
2
+ module Commands
3
+
4
+
5
+ class Remove
6
+ def initialize(base_command)
7
+ @base_command = base_command
8
+ end
9
+
10
+ def options
11
+ OptionParser.new do |o|
12
+ o.set_summary_indent(' ')
13
+ o.banner = "Usage: #{@base_command.script_name} remove name [name]..."
14
+ o.define_head "Remove plugins."
15
+ end
16
+ end
17
+
18
+ def parse!(args)
19
+ options.parse!(args)
20
+ root = @base_command.environment.root
21
+ args.each do |name|
22
+ Coherent::Plugin.new(name).uninstall
23
+ end
24
+ end
25
+ end
26
+
27
+
28
+ end
29
+ end
@@ -0,0 +1,34 @@
1
+ module Coherent
2
+ module Commands
3
+
4
+ class Source
5
+ def initialize(base_command)
6
+ @base_command = base_command
7
+ end
8
+
9
+ def options
10
+ OptionParser.new do |o|
11
+ o.set_summary_indent(' ')
12
+ o.banner = "Usage: #{@base_command.script_name} source REPOSITORY [REPOSITORY [REPOSITORY]...]"
13
+ o.define_head "Add new repositories to the default search list."
14
+ end
15
+ end
16
+
17
+ def parse!(args)
18
+ options.parse!(args)
19
+ count = 0
20
+ args.each do |uri|
21
+ if Repositories.instance.add(uri)
22
+ puts "added: #{uri.ljust(50)}" if $verbose
23
+ count += 1
24
+ else
25
+ puts "failed: #{uri.ljust(50)}"
26
+ end
27
+ end
28
+ Repositories.instance.save
29
+ puts "Added #{count} repositories."
30
+ end
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,33 @@
1
+ module Coherent
2
+ module Commands
3
+
4
+
5
+ class Sources
6
+ def initialize(base_command)
7
+ @base_command = base_command
8
+ end
9
+
10
+ def options
11
+ OptionParser.new do |o|
12
+ o.set_summary_indent(' ')
13
+ o.banner = "Usage: #{@base_command.script_name} sources [OPTIONS] [PATTERN]"
14
+ o.define_head "List configured plugin repositories."
15
+ o.separator ""
16
+ o.separator "Options:"
17
+ o.separator ""
18
+ o.on( "-c", "--check",
19
+ "Report status of repository.") { |sources| @sources = sources}
20
+ end
21
+ end
22
+
23
+ def parse!(args)
24
+ options.parse!(args)
25
+ Repositories.each do |repo|
26
+ puts repo.uri
27
+ end
28
+ end
29
+ end
30
+
31
+
32
+ end
33
+ end
@@ -0,0 +1,36 @@
1
+ module Coherent
2
+ module Commands
3
+
4
+ class Unsource
5
+ def initialize(base_command)
6
+ @base_command = base_command
7
+ end
8
+
9
+ def options
10
+ OptionParser.new do |o|
11
+ o.set_summary_indent(' ')
12
+ o.banner = "Usage: #{@base_command.script_name} unsource URI [URI [URI]...]"
13
+ o.define_head "Remove repositories from the default search list."
14
+ o.separator ""
15
+ o.on_tail("-h", "--help", "Show this help message.") { puts o; exit }
16
+ end
17
+ end
18
+
19
+ def parse!(args)
20
+ options.parse!(args)
21
+ count = 0
22
+ args.each do |uri|
23
+ if Repositories.instance.remove(uri)
24
+ count += 1
25
+ puts "removed: #{uri.ljust(50)}"
26
+ else
27
+ puts "failed: #{uri.ljust(50)}"
28
+ end
29
+ end
30
+ Repositories.instance.save
31
+ puts "Removed #{count} repositories."
32
+ end
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,42 @@
1
+ module Coherent
2
+ module Commands
3
+
4
+
5
+ class Update
6
+ def initialize(base_command)
7
+ @base_command = base_command
8
+ end
9
+
10
+ def options
11
+ OptionParser.new do |o|
12
+ o.set_summary_indent(' ')
13
+ o.banner = "Usage: #{@base_command.script_name} update [name [name]...]"
14
+ o.on( "-r REVISION", "--revision REVISION",
15
+ "Checks out the given revision from subversion.",
16
+ "Ignored if subversion is not used.") { |v| @revision = v }
17
+ o.define_head "Update plugins."
18
+ end
19
+ end
20
+
21
+ def parse!(args)
22
+ options.parse!(args)
23
+ root = @base_command.environment.root
24
+ cd root
25
+ args = Dir["vendor/plugins/*"].map do |f|
26
+ File.directory?("#{f}/.svn") ? File.basename(f) : nil
27
+ end.compact if args.empty?
28
+ cd "vendor/plugins"
29
+ args.each do |name|
30
+ if File.directory?(name)
31
+ puts "Updating plugin: #{name}"
32
+ system("svn #{$verbose ? '' : '-q'} up \"#{name}\" #{@revision ? "-r #{@revision}" : ''}")
33
+ else
34
+ puts "Plugin doesn't exist: #{name}"
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+
41
+ end
42
+ end
@@ -0,0 +1,97 @@
1
+ module Coherent
2
+
3
+ class Environment
4
+ attr_reader :root
5
+
6
+ def initialize(dir)
7
+ @root = dir
8
+ end
9
+
10
+ def self.find(dir=nil)
11
+ dir ||= pwd
12
+ while dir.length > 1
13
+ return new(dir) if File.exist?(File.join(dir, 'distil.yml'))
14
+ dir = File.dirname(dir)
15
+ end
16
+
17
+ puts "Unable to find environment"
18
+ exit 1
19
+ end
20
+
21
+ def self.default
22
+ @default ||= find
23
+ end
24
+
25
+ def self.default=(env)
26
+ @default = env
27
+ end
28
+
29
+ def install(name_uri_or_plugin)
30
+ if name_uri_or_plugin.is_a? String
31
+ if name_uri_or_plugin =~ /:\/\//
32
+ plugin = Plugin.new(name_uri_or_plugin)
33
+ else
34
+ plugin = Plugins[name_uri_or_plugin]
35
+ end
36
+ else
37
+ plugin = name_uri_or_plugin
38
+ end
39
+ unless plugin.nil?
40
+ plugin.install
41
+ else
42
+ puts "Plugin not found: #{name_uri_or_plugin}"
43
+ end
44
+ end
45
+
46
+ def use_svn?
47
+ require 'active_support/core_ext/kernel'
48
+ silence_stderr {`svn --version` rescue nil}
49
+ !$?.nil? && $?.success?
50
+ end
51
+
52
+ def use_externals?
53
+ use_svn? && File.directory?("#{root}/vendor/plugins/.svn")
54
+ end
55
+
56
+ def use_checkout?
57
+ # this is a bit of a guess. we assume that if the rails environment
58
+ # is under subversion then they probably want the plugin checked out
59
+ # instead of exported. This can be overridden on the command line
60
+ File.directory?("#{root}/.svn")
61
+ end
62
+
63
+ def best_install_method
64
+ return :http unless use_svn?
65
+ case
66
+ when use_externals? then :externals
67
+ when use_checkout? then :checkout
68
+ else :export
69
+ end
70
+ end
71
+
72
+ def externals
73
+ return [] unless use_externals?
74
+ ext = `svn propget svn:externals "#{root}/vendor/plugins"`
75
+ lines = ext.respond_to?(:lines) ? ext.lines : ext
76
+ lines.reject{ |line| line.strip == '' }.map do |line|
77
+ line.strip.split(/\s+/, 2)
78
+ end
79
+ end
80
+
81
+ def externals=(items)
82
+
83
+ return unless use_externals?
84
+
85
+ unless items.is_a? String
86
+ items = items.map{|name,uri| "#{name.ljust(29)} #{uri.chomp('/')}"}.join("\n")
87
+ end
88
+ Tempfile.open("svn-set-prop") do |file|
89
+ file.write(items)
90
+ file.flush
91
+ system("svn propset -q svn:externals -F \"#{file.path}\" \"#{root}/vendor/plugins\"")
92
+ end
93
+ end
94
+
95
+ end
96
+
97
+ end
@@ -0,0 +1,160 @@
1
+ module Coherent
2
+
3
+ class Plugin
4
+ attr_reader :name, :uri
5
+
6
+ def initialize(uri, name=nil)
7
+ @uri = uri
8
+ guess_name(uri)
9
+ end
10
+
11
+ def self.find(name)
12
+ name =~ /\// ? new(name) : Repositories.instance.find_plugin(name)
13
+ end
14
+
15
+ def to_s
16
+ "#{@name.ljust(30)}#{@uri}"
17
+ end
18
+
19
+ def svn_url?
20
+ @uri =~ /svn(?:\+ssh)?:\/\/*/
21
+ end
22
+
23
+ def git_url?
24
+ @uri =~ /^git:\/\// || @uri =~ /\.git$/
25
+ end
26
+
27
+ def installed?
28
+ File.directory?("#{project_env.root}/vendor/plugins/#{name}") \
29
+ or project_env.externals.detect{ |name, repo| self.uri == repo }
30
+ end
31
+
32
+ def install(method=nil, options = {})
33
+ method ||= project_env.best_install_method?
34
+ if :http == method
35
+ method = :export if svn_url?
36
+ method = :git if git_url?
37
+ end
38
+
39
+ uninstall if installed? and options[:force]
40
+
41
+ unless installed?
42
+ send("install_using_#{method}", options)
43
+ run_install_hook
44
+ else
45
+ puts "already installed: #{name} (#{uri}). pass --force to reinstall"
46
+ end
47
+ end
48
+
49
+ def uninstall
50
+ path = "#{project_env.root}/vendor/plugins/#{name}"
51
+ if File.directory?(path)
52
+ puts "Removing 'vendor/plugins/#{name}'" if $verbose
53
+ run_uninstall_hook
54
+ rm_r path
55
+ else
56
+ puts "Plugin doesn't exist: #{path}"
57
+ end
58
+ # clean up svn:externals
59
+ externals = project_env.externals
60
+ externals.reject!{|n,u| name == n or name == u}
61
+ project_env.externals = externals
62
+ end
63
+
64
+ def info
65
+ tmp = "#{project_env.root}/_tmp_about.yml"
66
+ if svn_url?
67
+ cmd = "svn export #{@uri} \"#{project_env.root}/#{tmp}\""
68
+ puts cmd if $verbose
69
+ system(cmd)
70
+ end
71
+ open(svn_url? ? tmp : File.join(@uri, 'about.yml')) do |stream|
72
+ stream.read
73
+ end rescue "No about.yml found in #{uri}"
74
+ ensure
75
+ FileUtils.rm_rf tmp if svn_url?
76
+ end
77
+
78
+ private
79
+
80
+ def run_install_hook
81
+ install_hook_file = "#{project_env.root}/vendor/plugins/#{name}/install.rb"
82
+ load install_hook_file if File.exist? install_hook_file
83
+ end
84
+
85
+ def run_uninstall_hook
86
+ uninstall_hook_file = "#{project_env.root}/vendor/plugins/#{name}/uninstall.rb"
87
+ load uninstall_hook_file if File.exist? uninstall_hook_file
88
+ end
89
+
90
+ def install_using_export(options = {})
91
+ svn_command :export, options
92
+ end
93
+
94
+ def install_using_checkout(options = {})
95
+ svn_command :checkout, options
96
+ end
97
+
98
+ def install_using_externals(options = {})
99
+ externals = project_env.externals
100
+ externals.push([@name, uri])
101
+ project_env.externals = externals
102
+ install_using_checkout(options)
103
+ end
104
+
105
+ def install_using_http(options = {})
106
+ root = project_env.root
107
+ mkdir_p "#{root}/vendor/plugins/#{@name}"
108
+ Dir.chdir "#{root}/vendor/plugins/#{@name}" do
109
+ puts "fetching from '#{uri}'" if $verbose
110
+ fetcher = RecursiveHTTPFetcher.new(uri, -1)
111
+ fetcher.quiet = true if options[:quiet]
112
+ fetcher.fetch
113
+ end
114
+ end
115
+
116
+ def install_using_git(options = {})
117
+ root = project_env.root
118
+ mkdir_p(install_path = "#{root}/vendor/plugins/#{name}")
119
+ Dir.chdir install_path do
120
+ init_cmd = "git init"
121
+ init_cmd += " -q" if options[:quiet] and not $verbose
122
+ puts init_cmd if $verbose
123
+ system(init_cmd)
124
+ base_cmd = "git pull --depth 1 #{uri}"
125
+ base_cmd += " -q" if options[:quiet] and not $verbose
126
+ base_cmd += " #{options[:revision]}" if options[:revision]
127
+ puts base_cmd if $verbose
128
+ if system(base_cmd)
129
+ puts "removing: .git .gitignore" if $verbose
130
+ rm_rf %w(.git .gitignore)
131
+ else
132
+ rm_rf install_path
133
+ end
134
+ end
135
+ end
136
+
137
+ def svn_command(cmd, options = {})
138
+ root = project_env.root
139
+ mkdir_p "#{root}/vendor/plugins"
140
+ base_cmd = "svn #{cmd} #{uri} \"#{root}/vendor/plugins/#{name}\""
141
+ base_cmd += ' -q' if options[:quiet] and not $verbose
142
+ base_cmd += " -r #{options[:revision]}" if options[:revision]
143
+ puts base_cmd if $verbose
144
+ system(base_cmd)
145
+ end
146
+
147
+ def guess_name(url)
148
+ @name = File.basename(url)
149
+ if @name == 'trunk' || @name.empty?
150
+ @name = File.basename(File.dirname(url))
151
+ end
152
+ @name.gsub!(/\.git$/, '') if @name =~ /\.git$/
153
+ end
154
+
155
+ def project_env
156
+ @project_env || Coherent::Environment.default
157
+ end
158
+ end
159
+
160
+ end
@@ -0,0 +1,71 @@
1
+ module Coherent
2
+
3
+ class RecursiveHTTPFetcher
4
+ attr_accessor :quiet
5
+ def initialize(urls_to_fetch, level = 1, cwd = ".")
6
+ @level = level
7
+ @cwd = cwd
8
+ @urls_to_fetch = RUBY_VERSION >= '1.9' ? urls_to_fetch.lines : urls_to_fetch.to_a
9
+ @quiet = false
10
+ end
11
+
12
+ def ls
13
+ @urls_to_fetch.collect do |url|
14
+ if url =~ /^svn(\+ssh)?:\/\/.*/ || url =~ /\/svn\//
15
+ `svn ls #{url}`.split("\n").map {|entry| "/#{entry}"} rescue nil
16
+ else
17
+ open(url) do |stream|
18
+ links("", stream.read)
19
+ end rescue nil
20
+ end
21
+ end.flatten
22
+ end
23
+
24
+ def push_d(dir)
25
+ @cwd = File.join(@cwd, dir)
26
+ FileUtils.mkdir_p(@cwd)
27
+ end
28
+
29
+ def pop_d
30
+ @cwd = File.dirname(@cwd)
31
+ end
32
+
33
+ def links(base_url, contents)
34
+ links = []
35
+ contents.scan(/href\s*=\s*\"*[^\">]*/i) do |link|
36
+ link = link.sub(/href="/i, "")
37
+ next if link =~ /svnindex.xsl$/
38
+ next if link =~ /^(\w*:|)\/\// || link =~ /^\./
39
+ links << File.join(base_url, link)
40
+ end
41
+ links
42
+ end
43
+
44
+ def download(link)
45
+ puts "+ #{File.join(@cwd, File.basename(link))}" unless @quiet
46
+ open(link) do |stream|
47
+ File.open(File.join(@cwd, File.basename(link)), "wb") do |file|
48
+ file.write(stream.read)
49
+ end
50
+ end
51
+ end
52
+
53
+ def fetch(links = @urls_to_fetch)
54
+ links.each do |l|
55
+ (l =~ /\/$/ || links == @urls_to_fetch) ? fetch_dir(l) : download(l)
56
+ end
57
+ end
58
+
59
+ def fetch_dir(url)
60
+ @level += 1
61
+ push_d(File.basename(url)) if @level > 0
62
+ open(url) do |stream|
63
+ contents = stream.read
64
+ fetch(links(url, contents))
65
+ end
66
+ pop_d if @level > 0
67
+ @level -= 1
68
+ end
69
+ end
70
+
71
+ end