onboard 0.2.3 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- MjlmMTg5NmViZWI0N2VmNGNhYTRkNDg5ZDM2YWFjYWU5Y2EwZWI5NA==
4
+ NTE0NDRmNTk5YzIyYjZhNTRlMWRkM2VlZjMwYmFjZTVlYTNiNTJlNw==
5
5
  data.tar.gz: !binary |-
6
- MmU4ZjRiMjllNWFhYjlhODY1ODFjNjM2YTFkNDIxNjEzM2I1NWE1ZQ==
6
+ YzliYzIwZTQ5ZmQyYWQ0ODcxNTQ3YTJhNWNlYmNkMjgxZWI2NzE1ZQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MmVlZjM4MmExZGJlMjE1YmQ4OWNmOGE3NDI5ZjM1NGE1ODA1YzQ1ZTE4MTk3
10
- ZjIzNTFhMzMzOGFhZTMwMzgwYzU2ZWJmMGYxYzc5ZjUwYTFlMTM2MDYyOTU2
11
- YWY5NjFiMDFhNWQ2MmM1YTZhYzY0NmViZDk2OTJkM2VkMGVmYjY=
9
+ ZjZhZDYwOTgyMmFlN2I1OWI3MGFjOTJmZjI2N2IwMDdhNzcxNzJlZmMzZWZi
10
+ Zjg1NWJjNzVmNmI3NDI3YTM1NjQ3MmU1ZGJiYjU1NDZkNjc0YzQ3YzZmZTZl
11
+ NTcwN2QyNTcwMzdkMTY1ZWEwN2M0MDdkZGZiNmEzMzJmMWRlMDk=
12
12
  data.tar.gz: !binary |-
13
- NjI0MGMwNjlkYjNjODg0MmZjNjg0ZTk5MzdjZTQ4MDk5MThkZjkwZjhmNTE3
14
- ODIzMTQ1YmNhYzhmN2E1YzI3OWQyODM2ZmI5NGNlYWNmZGIxOTNlNjIzNWQ1
15
- ZGFlNDgwMzg0ZDk3M2E5YTllYjgzODUwOTFjM2FmMzIzM2QzODY=
13
+ MmYyZTlkZjBkMTlhZWI4MDRjNWMxMjk1OTgwM2Q4MWY2OGRiYjFmZDlmMzUw
14
+ YjJmZjcwMDliOGY3ZjcwMWRhNDU3YTZmYjJlNmM2YmQ0ZTFkYmM0OWU2ZDcx
15
+ ZGIwZGFkOGY4ODQ0N2UxNDllMGJlYThjZGI4M2JhNDc4NTkxNjM=
data/.rubocop.yml ADDED
@@ -0,0 +1,8 @@
1
+ Documentation:
2
+ Enabled: false
3
+
4
+ HashSyntax:
5
+ EnforcedStyle: hash_rockets
6
+
7
+ LineLength:
8
+ Enabled: false
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.1.0
5
+ - 2.1.1
6
+ - 2.1.2
data/Gemfile CHANGED
@@ -1,4 +1,14 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- # Specify your gem's dependencies in onboard.gemspec
3
+ gem 'rake'
4
+
5
+ group :test do
6
+ gem 'coveralls'
7
+ gem 'rspec', '>= 3'
8
+ gem 'rubocop', '>= 0.25'
9
+ gem 'simplecov', '>= 0.9'
10
+ gem 'timecop'
11
+ gem 'webmock', '>= 1.10.1'
12
+ end
13
+
4
14
  gemspec
data/README.md CHANGED
@@ -21,33 +21,36 @@ Or install it yourself as:
21
21
  __COMMANDS:__
22
22
  ```
23
23
  Commands:
24
- onboard help [COMMAND] # Describe available commands or one specific command
25
- onboard projects CODEBASE -c, --core=N -p, --path=PATH # add projects to CODEBASE
24
+ onboard help [COMMAND] # Describe available commands or one specific command
25
+ onboard lift CODEBASE (coming soon) # add lift to CODEBASE
26
+ onboard projects CODEBASE -d, --destination=DESTINATION # add projects to CODEBASE
27
+ onboard update CODEBASE (coming soon) # update projects in CODEBASE
26
28
  ```
27
29
 
28
- __MODULES:__
30
+ __PROJECTS:__
29
31
  ```
30
32
  Usage:
31
- onboard projects CODEBASE -c, --core=N -p, --path=PATH
33
+ onboard projects CODEBASE -d, --destination=DESTINATION
32
34
 
33
35
  Options:
34
- -b, [--branch=BRANCH] # Specify repository branch to update
35
- -c, --core=N # Specify Drupal core version
36
- -p, --path=PATH # Specify project path relative to CODEBASE
37
- -f, [--force=FORCE] # Force add modules (even if already present)
38
- -n, [--no=NO] # Assume 'no' for all prompts
39
- -m, [--modules=one two three] # Pass a list of modules
40
- -t, [--themes=one two three] # Pass a list of themes
41
- [--vc], [--no-vc] # Enable/Disable version control handling
42
- # Default: true
43
- -y, [--yes=YES] # Assume 'yes' for all prompts
36
+ -c, [--commit=COMMIT] # Specify commit object for Git source
37
+ -D, [--delete=DELETE] # Delete existing projects
38
+ -d, --destination=DESTINATION # Specify project destination relative to CODEBASE
39
+ -f, [--force=FORCE] # Force add projects (even if already present)
40
+ -n, [--no=NO] # Assume "no" for all prompts
41
+ -p, [--projects=one two three] # Pass a list of projects
42
+ [--vc], [--no-vc] # Enable/Disable version control handling
43
+ # Default: true
44
+ -y, [--yes=YES] # Assume "yes" for all prompts
44
45
 
45
46
  Description:
46
47
  `onboard projects` performs multiple tasks when installing contrib projects:
47
48
 
48
49
  * Checks for each project in the CODEBASE
49
50
 
50
- * Downloads the latest version of each project
51
+ * Reports patched projects
52
+
53
+ * Downloads the latest/stablest version of each project
51
54
 
52
55
  * Adds and commits each project
53
56
  ```
data/Rakefile CHANGED
@@ -1,2 +1,20 @@
1
- require "bundler/gem_tasks"
1
+ require 'bundler/gem_tasks'
2
2
 
3
+ require 'rspec/core/rake_task'
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ begin
7
+ require 'rubocop/rake_task'
8
+ RuboCop::RakeTask.new
9
+ rescue LoadError
10
+ desc 'Run RuboCop'
11
+ task :rubocop do
12
+ $stderr.puts 'Rubocop is disabled'
13
+ end
14
+ end
15
+
16
+ Dir.glob('tasks/*.rake').each { |r| import r }
17
+
18
+ task :release => ['completion:zsh', 'completion:bash']
19
+ task :test => :spec
20
+ task :default => [:spec, :rubocop]
data/lib/onboard/cli.rb CHANGED
@@ -1,95 +1,84 @@
1
1
  # encoding: utf-8
2
2
 
3
- require 'open-uri/cached'
4
3
  require 'thor'
5
4
 
6
5
  require_relative 'confirm'
6
+ require_relative 'core'
7
7
  require_relative 'find'
8
+ require_relative 'prepare'
8
9
  require_relative 'project'
9
- require_relative 'repo'
10
10
 
11
11
  module Onboard
12
12
  class CLI < Thor
13
- desc "projects CODEBASE", "add projects to CODEBASE"
13
+ desc 'update CODEBASE', 'update projects in CODEBASE'
14
+ long_desc <<-LONGDESC
15
+ `onboard update` performs multiple tasks when updating contrib projects:
16
+
17
+ * Checks for each project in the CODEBASE
18
+
19
+ * Downloads the latest release for each project
20
+
21
+ * Adds and commits updates
22
+
23
+ LONGDESC
24
+ option :all, :default => false, :aliases => '-a', :desc => 'Perform all updates (default is security updates only)'
25
+ option :core, :aliases => '-C', :desc => 'Update Drupal core only'
26
+ option :contrib, :aliases => '-c', :desc => 'Update Drupal contrib only'
27
+ option :distro, :aliases => '-d', :desc => 'Specify a distribution other than Drupal or Pressflow'
28
+ option :no, :aliases => '-n', :desc => 'Assume "no" for all prompts'
29
+ option :projects, :aliases => '-p', :desc => 'Specify projects to update'
30
+ option :vc, :type => :boolean, :default => true, :desc => 'Enable/Disable version control handling'
31
+ option :yes, :aliases => '-y', :desc => 'Assume "yes" for all prompts'
32
+ def update(codebase)
33
+ puts codebase
34
+ end
35
+
36
+ desc 'projects CODEBASE', 'add projects to CODEBASE'
14
37
  long_desc <<-LONGDESC
15
38
  `onboard projects` performs multiple tasks when installing contrib
16
39
  projects:
17
40
 
18
41
  * Checks for each project in the CODEBASE
19
42
 
20
- * Downloads the latest version of each project
43
+ * Reports patched projects
44
+
45
+ * Downloads the latest/stablest version of each project
21
46
 
22
47
  * Adds and commits each project
23
48
 
24
49
  LONGDESC
25
- option :branch, :aliases => "-b", :desc => "Specify repository branch to update"
26
- option :core, :required => true, :aliases => "-c", :type => :numeric, :desc => "Specify Drupal core version"
27
- option :path, :required => true, :aliases => "-p", :desc => "Specify project path relative to CODEBASE"
28
- option :force, :aliases => "-f", :desc => "Force add modules (even if already present)"
29
- option :no, :aliases => "-n", :desc => "Assume 'no' for all prompts"
30
- option :modules, :aliases => "-m", :type => :array, :desc => "Pass a list of modules"
31
- option :delete, :aliases => "-d", :desc => "Delete existing projects"
32
- # option :source, :aliases => "-s", :desc => "Specify a project source other than drupal.org"
33
- option :themes, :aliases => "-t", :type => :array, :desc => "Pass a list of themes"
34
- option :vc, :type => :boolean, :default => true, :desc => "Enable/Disable version control handling"
35
- option :yes, :aliases => "-y", :desc => "Assume 'yes' for all prompts"
50
+ option :commit, :aliases => '-c', :desc => 'Specify commit object for Git source'
51
+ option :delete, :aliases => '-D', :desc => 'Delete existing projects'
52
+ option :destination, :required => true, :aliases => '-d', :desc => 'Specify project destination relative to CODEBASE'
53
+ option :force, :aliases => '-f', :desc => 'Force add projects (even if already present)'
54
+ option :no, :aliases => '-n', :desc => 'Assume "no" for all prompts'
55
+ option :projects, :aliases => '-p', :type => :array, :desc => 'Pass a list of projects'
56
+ # option :source, :aliases => '-s', :desc => 'Specify a project source other than drupal.org'
57
+ option :vc, :type => :boolean, :default => true, :desc => 'Enable/Disable version control handling'
58
+ option :yes, :aliases => '-y', :desc => 'Assume "yes" for all prompts'
36
59
  def projects(codebase)
37
- core = "#{options[:core]}.x"
38
- projects = {}
39
- if options[:modules].nil? == false
40
- options[:modules].each { |x| projects[x] = '' }
41
- elsif options[:themes].nil? == false
42
- options[:themes].each { |x| projects[x] = '' }
43
- end
44
- path = "#{options[:path]}"
45
- found = Finder.new(projects, codebase).locate
46
- if found.empty? == false
47
- say("Projects exist at the following locations:", :yellow)
48
- found.each do |x, y|
49
- puts " " + x
50
- projects[File.basename(x)] = y[0]
51
- end
52
- puts ""
53
- if options[:delete] == 'delete'
54
- say("Ready to delete existing projects:", :yellow)
55
- Confirm.new("Proceed?", true).yes?
56
- found.each do |x, y|
57
- Project.new.clean(x)
58
- projects[File.basename(x)] = ''
59
- end
60
- end
61
- end
62
- if options[:force] != 'force'
63
- if found.empty? == false
64
- found.each do |x, y|
65
- projects.delete(File.basename(x))
66
- end
67
- end
68
- end
69
- if projects.empty? == false
70
- say("Ready to add the following projects:", :green)
71
- projects.each do |x, y|
72
- puts " " + "#{codebase}/#{path}/#{x}"
73
- end
74
- puts ""
75
- if options[:no].nil? && options[:yes].nil?
76
- Confirm.new("Proceed?").yes?
77
- elsif options[:no] == 'no'
78
- say("Script was exited.")
79
- exit
80
- end
81
- prj = {}
82
- branch = options[:branch].nil? ? '' : options[:branch]
83
- prj['branch'] = branch
84
- prj['codebase'] = codebase
85
- prj['core'] = core
86
- prj['path'] = path
87
- prj['projects'] = projects
88
- prj['vc'] = options[:vc]
89
- Project.new(prj).dl
90
- else
91
- say("All projects already in codebase.", :yellow)
92
- end
60
+ found = Finder.new(options[:projects], codebase).locate
61
+ projects, answer = Prepare.new(codebase, found, options).do
62
+ info = [codebase, Core.new(codebase).info['major'], answer]
63
+ Project.new(info, projects, options).dl
64
+ end
65
+
66
+ desc 'lift CODEBASE', 'add lift to CODEBASE'
67
+ long_desc <<-LONGDESC
68
+ `onboard lift` performs multiple tasks when adding lift:
69
+
70
+ * Checks for each lift component in the CODEBASE
71
+
72
+ * Downloads the recommended release for each lift component
73
+
74
+ * Adds and commits updates
75
+
76
+ LONGDESC
77
+ option :no, :aliases => '-n', :desc => 'Assume "no" for all prompts'
78
+ option :vc, :type => :boolean, :default => true, :desc => 'Enable/Disable version control handling'
79
+ option :yes, :aliases => '-y', :desc => 'Assume "yes" for all prompts'
80
+ def lift(codebase)
81
+ puts codebase
93
82
  end
94
83
  end
95
84
  end
@@ -12,20 +12,29 @@ module Onboard
12
12
  @full_stop = full_stop
13
13
  end
14
14
 
15
- def yes?
16
- answer = ""
17
- while answer !~ /^[Y|N]$/i do
18
- answer = ask(message + " [Y|N]: ")
19
- puts ""
15
+ def q(prefill = '')
16
+ return response(prefill) if prefill =~ /^[N]$/i || prefill =~ /^[Y]$/i
17
+ answer = ''
18
+ while answer !~ /^[Y|N]$/i
19
+ answer = ask(message + ' [Y|N]: ')
20
+ puts ''
20
21
  end
22
+ response(answer)
23
+ end
24
+
25
+ def no
26
+ if full_stop
27
+ say('Script was exited.')
28
+ exit
29
+ else
30
+ say('Action was aborted.')
31
+ return false
32
+ end
33
+ end
34
+
35
+ def response(answer)
21
36
  if answer =~ /^[N]$/i
22
- if full_stop
23
- say("Script was exited.")
24
- exit
25
- else
26
- say("Action was aborted.")
27
- return false
28
- end
37
+ no
29
38
  elsif answer =~ /^[Y]$/i
30
39
  return true
31
40
  end
@@ -0,0 +1,67 @@
1
+ # encoding: utf-8
2
+
3
+ require 'find'
4
+
5
+ module Onboard
6
+ class Core
7
+ attr_reader :codebase
8
+
9
+ def initialize(codebase)
10
+ @codebase = codebase
11
+ end
12
+
13
+ def parser(file, v, pattern)
14
+ open(file) do |f|
15
+ f.each_line.find do |line|
16
+ next unless v.match(line)
17
+ return line.scan(pattern)[0][0] unless line.scan(pattern)[0].nil?
18
+ end
19
+ end
20
+ end
21
+
22
+ def drupal(file)
23
+ pattern = /.*?"(.*?)".*$/
24
+ v = /version/
25
+ parser(file, v, pattern)
26
+ end
27
+
28
+ def pressflow(file)
29
+ pattern = /^.*?,\s\'(.*?)\'.*$/
30
+ v = /define\(\'VERSION/
31
+ parser(file, v, pattern)
32
+ end
33
+
34
+ def collector
35
+ i = {}
36
+ Find.find(codebase) do |e|
37
+ next unless File.file?(e)
38
+ i['drupal'] = drupal(e) if %r{modules/system/system\.info$} =~ e
39
+ i['pressflow'] = pressflow(e) if %r{modules/system/system\.module$} =~ e
40
+ if /includes\/bootstrap\.inc$/ =~ e
41
+ i['distro'] = pressflow?(e) ? 'pressflow' : 'drupal'
42
+ end
43
+ end
44
+ i
45
+ end
46
+
47
+ def info
48
+ core = {}
49
+ i = collector
50
+ version = i['pressflow'].nil? ? i['drupal'] : i['pressflow']
51
+ core['distro'] = i['distro']
52
+ core['version'] = version
53
+ core['major'] = "#{version.scan(/^(.*?)\..*$/)[0][0]}.x"
54
+ core
55
+ end
56
+
57
+ def pressflow?(file)
58
+ pattern = /drupal_page_cache_header_external/
59
+ open(file) do |f|
60
+ f.each_line.find do |line|
61
+ next unless pattern.match(line)
62
+ return true
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -2,28 +2,33 @@
2
2
 
3
3
  require 'fileutils'
4
4
  require 'net/http'
5
+ require 'rubygems/package'
5
6
 
6
7
  module Onboard
8
+ DRUPAL_DL_LINK = 'http://ftp.drupal.org/files/projects/'
9
+
7
10
  class Download
8
11
  attr_reader :cache_dir
9
12
 
10
- def initialize(cache_dir='/tmp/onboard/cache')
13
+ def initialize(cache_dir = '/tmp/onboard/cache')
11
14
  @cache_dir = cache_dir
12
15
  end
13
16
 
17
+ def build_link(project, version)
18
+ DRUPAL_DL_LINK + "#{project}-#{version}.tar.gz"
19
+ end
20
+
14
21
  def path(url)
15
- File.join("", @cache_dir, Digest::MD5.hexdigest(url))
22
+ File.join('', @cache_dir, Digest::MD5.hexdigest(url))
16
23
  end
17
24
 
18
- def fetch(url, max_age=1800)
19
- unless File.directory?(cache_dir)
20
- FileUtils.mkdir_p(cache_dir)
21
- end
22
- file_path = self.path(url)
23
- if File.exists? file_path
24
- return File.new(file_path).read if Time.now-File.mtime(file_path)<max_age
25
+ def fetch(url, max_age = 1800)
26
+ FileUtils.mkdir_p(cache_dir) unless File.directory?(cache_dir)
27
+ file_path = path(url)
28
+ if File.exist? file_path
29
+ return File.new(file_path).read if Time.now - File.mtime(file_path) < max_age
25
30
  end
26
- File.open(file_path, "w") do |data|
31
+ File.open(file_path, 'w') do |data|
27
32
  data << Net::HTTP.get_response(URI.parse(url)).body
28
33
  end
29
34
  end
@@ -0,0 +1,57 @@
1
+ # encoding: utf-8
2
+
3
+ require 'fileutils'
4
+ require 'rubygems/package'
5
+ require 'thor'
6
+ require 'zlib'
7
+
8
+ module Onboard
9
+ TAR_LONGLINK = '././@LongLink'
10
+
11
+ class Extract
12
+ attr_reader :archive, :link, :path
13
+
14
+ def initialize(archive, link, path)
15
+ @archive = archive
16
+ @link = link
17
+ @path = path
18
+ end
19
+
20
+ def longlink(entry)
21
+ return File.join path, entry.read.strip if entry.full_name == TAR_LONGLINK
22
+ end
23
+
24
+ def xdir(dst, entry)
25
+ return false unless entry.directory?
26
+ FileUtils.rm_rf dst unless File.directory? dst
27
+ FileUtils.mkdir_p dst, :mode => entry.header.mode, :verbose => false
28
+ end
29
+
30
+ def xfile(dst, entry)
31
+ return false unless entry.file?
32
+ FileUtils.rm_rf dst unless File.file? dst
33
+ File.open dst, 'wb' do |f|
34
+ f.print entry.read
35
+ end
36
+ FileUtils.chmod entry.header.mode, dst, :verbose => false
37
+ end
38
+
39
+ def xlink(dst, entry)
40
+ return false unless entry.header.typeflag == '2' # Symlink!
41
+ File.symlink entry.header.linkname, dst
42
+ end
43
+
44
+ def x(dst = nil)
45
+ Gem::Package::TarReader.new(Zlib::GzipReader.open archive) do |tar|
46
+ tar.each do |entry|
47
+ dst = longlink(entry)
48
+ dst ||= File.join path, entry.full_name
49
+ xdir(dst, entry)
50
+ xfile(dst, entry)
51
+ xlink(dst, entry)
52
+ dst = nil
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
data/lib/onboard/find.rb CHANGED
@@ -14,22 +14,19 @@ module Onboard
14
14
  def locate
15
15
  found = {}
16
16
  Find.find(haystack) do |e|
17
- if File.directory?(e)
18
- if needle.has_key?(File.basename(e))
19
- Dir.entries(e).select do |f|
20
- file = "#{e}/#{f}"
21
- if File.file?(file)
22
- if self.info_ext?(file)
23
- if self.version(file).empty? == false
24
- found[e] = self.version(file)
25
- end
26
- end
27
- end
28
- end
29
- end
30
- end
17
+ next unless File.directory?(e)
18
+ next unless needle.include?(File.basename(e))
19
+ file = info_file(e)
20
+ found[e] = version(file)
21
+ end
22
+ found
23
+ end
24
+
25
+ def info_file(dir)
26
+ Find.find(dir).select do |f|
27
+ next unless File.file?(f)
28
+ return f if info_ext?(f)
31
29
  end
32
- return found
33
30
  end
34
31
 
35
32
  def info_ext?(file)
@@ -40,7 +37,7 @@ module Onboard
40
37
  File.open(file) do |g|
41
38
  g.each_line do |line|
42
39
  if line =~ /version/
43
- return line.scan(/.*?"(.*?)".*$/)[0].nil? ? '' : line.scan(/.*?"(.*?)".*$/)[0]
40
+ return line.scan(/.*?"(.*?)".*$/)[0].nil? ? false : line.scan(/.*?"(.*?)".*$/)[0][0]
44
41
  end
45
42
  end
46
43
  end
data/lib/onboard/msg.rb CHANGED
@@ -14,11 +14,10 @@ module Onboard
14
14
  end
15
15
 
16
16
  def format
17
- height, width = Screen.new().size
18
- spaces = " " * (width - msg.length - 8)
17
+ _height, width = Screen.new.size
18
+ spaces = ' ' * (width - msg.length - 8)
19
19
  say(msg + spaces)
20
20
  end
21
21
  end
22
22
  end
23
23
  end
24
-
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'fileutils'
4
+ require 'git'
5
+ require 'pathname'
6
+ require 'thor'
7
+
8
+ module Onboard
9
+ class Patch
10
+ attr_reader :dir
11
+
12
+ def initialize(dir = '/tmp/onboard/patches')
13
+ @dir = dir
14
+ end
15
+
16
+ def patch_dir
17
+ FileUtils.mkdir_p(dir) unless File.directory?(dir)
18
+ end
19
+
20
+ def cleanup
21
+ Dir.foreach(dir) do |item|
22
+ file = "#{dir}/#{item}"
23
+ FileUtils.rm_r file if File.zero?(file)
24
+ end
25
+ end
26
+
27
+ def open(project)
28
+ patch_dir
29
+ patch_file = File.open("#{dir}/#{Time.now.to_i}_#{project}.patch", 'w')
30
+ patch_file
31
+ end
32
+
33
+ def close(patch_file = '')
34
+ patch_file.close
35
+ cleanup
36
+ end
37
+ end
38
+ end