onboard 0.2.3 → 0.3.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.
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