onboard 0.1.2

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 ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MGI5YjdkODkxYmYyMTFjY2Q3ZjM0YjJiODE0OTIyN2IwN2M2YzYyMQ==
5
+ data.tar.gz: !binary |-
6
+ YmU4MzRiNjQ5ZjlhYWM3Y2Y0MzM4NDBmMmE3NzcyMmE2MmJkMmE3OA==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ ZTRjYjNhYTcwYWYxNDk3NTYwZjMxZjJjYTg0ZTZhNGQ5ZWEwNjUyNWRjNzU2
10
+ NzgyNjlhMGExNmJlYWY0N2YxM2U5NmZjMjlmMjAzZjhhYzE3ODQ4NDU1MjI4
11
+ YzczYTRiMmRhMDdiZjExM2ZmODIyMDIxYzQzMDRmNTc3MzNiM2Q=
12
+ data.tar.gz: !binary |-
13
+ N2Q5YjNhNjMxMTU2YzQzNWUyOWNjZWZmMzdhOTU1Y2ZkZjIwNDc2MDE2YzFi
14
+ ZTY4Y2FmNjA2NzAwNGViYTQzNWU0ZDU4YWJmMjJkMWE1NzAxNTFkMGU0MWI3
15
+ MDBhYjY4MDBmMTAxYzc4ZWNiNThkMzIyYjNjODEzMDBlYzNmOGY=
data/.gitignore ADDED
@@ -0,0 +1,22 @@
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
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in onboard.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Nathaniel Hoag
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.
data/README.md ADDED
@@ -0,0 +1,58 @@
1
+ # Onboard
2
+
3
+ Checks, downloads, verifies, adds, and commits Drupal contrib modules.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'onboard'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install onboard
18
+
19
+ ## Usage
20
+
21
+ __COMMANDS:__
22
+ ```
23
+ Commands:
24
+ onboard help [COMMAND] # Describe available commands or one s...
25
+ onboard modules DOCROOT -c, --core=N # add default modules to DOCROOT
26
+ ```
27
+
28
+ __MODULES:__
29
+ ```
30
+ Usage:
31
+ onboard modules DOCROOT -c, --core=N
32
+
33
+ Options:
34
+ -a, [--addendum=one two three] # Add projects to the default list
35
+ -c, --core=N # Specify Drupal core version
36
+ -d, [--destination=DESTINATION] # Specify contrib destination relative to docroot
37
+ -f, [--force=FORCE] # Force add modules
38
+ -n, [--no=NO] # Assume 'no' for all prompts
39
+ -p, [--projects=one two three] # Pass a custom list of projects
40
+ -s, [--subdir=SUBDIR] # Specify contrib subdir relative to 'modules'
41
+ -y, [--yes=YES] # Assume 'yes' for all prompts
42
+
43
+ Description:
44
+ onboard modules performs multiple steps when installing default contrib
45
+ modules (acquia_connector, fast_404, memcache):
46
+
47
+ 1. Checks for each module in the docroot
48
+ 2. Downloads the latest version of each module
49
+ 3. Adds and commits each module
50
+ ```
51
+
52
+ ## Contributing
53
+
54
+ 1. Fork it ( https://github.com/[my-github-username]/onboard/fork )
55
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
56
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
57
+ 4. Push to the branch (`git push origin my-new-feature`)
58
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
data/bin/onboard ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'onboard'
4
+
5
+ Onboard::CLI.start(ARGV)
@@ -0,0 +1,129 @@
1
+ # encoding: utf-8
2
+ require 'thor'
3
+ require 'open-uri/cached'
4
+ require_relative 'codebase'
5
+
6
+ module Onboard
7
+ class CLI < Thor
8
+ # TODO: switch from DOCROOT to CODEBASE to enable more comprehensive searching
9
+ desc "modules DOCROOT", "add default modules to DOCROOT"
10
+ long_desc <<-LONGDESC
11
+ `onboard modules` performs multiple tasks when installing contrib
12
+ modules:
13
+
14
+ * Checks for each module in the docroot
15
+
16
+ * Downloads the latest version of each module
17
+
18
+ * Adds and commits each module
19
+
20
+ Default contrib modules: acquia_connector, fast_404, memcache
21
+ LONGDESC
22
+ option :addendum, :aliases => "-a", :type => :array, :desc => "Add projects to the default list"
23
+ # TODO: Analyze codebase for core version?
24
+ # ala - find ./CODEBASE -type f -name '*.info' | xargs -I {} grep -rn '^version = \"' {}
25
+ option :core, :required => true, :aliases => "-c", :type => :numeric, :desc => "Specify Drupal core version"
26
+ option :destination, :aliases => "-d", :desc => "Specify contrib destination relative to docroot"
27
+ option :force, :aliases => "-f", :desc => "Force add modules (even if already present)"
28
+ option :no, :aliases => "-n", :desc => "Assume 'no' for all prompts"
29
+ option :projects, :aliases => "-p", :type => :array, :desc => "Pass a custom list of projects"
30
+ # option :remove, :aliases => "-r", :desc => "Remove all copies of existing modules"
31
+ option :subdir, :aliases => "-s", :desc => "Specify contrib subdir relative to 'modules'"
32
+ option :vc, :type => :boolean, :default => true, :desc => "Enable/Disable version control handling"
33
+ option :yes, :aliases => "-y", :desc => "Assume 'yes' for all prompts"
34
+ def modules(docroot)
35
+ core = "#{options[:core]}.x"
36
+ modules = []
37
+ if options[:projects].nil? == false
38
+ options[:projects].each { |x| modules.push x }
39
+ else
40
+ modules = ["acquia_connector", "fast_404", "memcache"]
41
+ end
42
+ if options[:addendum].nil? == false
43
+ options[:addendum].each { |x| modules.push x }
44
+ end
45
+ subdir = options[:subdir].nil? == true ? "" : "/#{options[:subdir]}"
46
+ destination = options[:destination].nil? ? "sites/all/modules#{subdir}" : "#{options[:destination]}#{subdir}"
47
+ require 'find'
48
+ found = []
49
+ Find.find(docroot) do |e|
50
+ if File.directory?(e)
51
+ if modules.include?(File.basename(e))
52
+ found.push e
53
+ end
54
+ end
55
+ end
56
+ if found.any?
57
+ say("Projects exist at the following locations:", :yellow)
58
+ found.each do |project|
59
+ puts " " + project
60
+ end
61
+ puts ""
62
+ end
63
+ if options[:force] != 'force'
64
+ found.each do |x|
65
+ modules.delete(File.basename(x))
66
+ end
67
+ end
68
+ if modules.empty? == false
69
+ say("Ready to add the following projects:", :green)
70
+ modules.each do |x|
71
+ puts " " + "#{docroot}/#{destination}/#{x}"
72
+ end
73
+ puts ""
74
+ if options[:no].nil? && options[:yes].nil?
75
+ answer = ""
76
+ while answer !~ /^[Y|N]$/i do
77
+ answer = ask("Proceed? [Y|N]: ")
78
+ puts ""
79
+ end
80
+ if answer =~ /^[N]$/i
81
+ say("Script was exited.")
82
+ exit
83
+ end
84
+ elsif options[:no] == 'no'
85
+ say("Script was exited.")
86
+ exit
87
+ end
88
+ modules.each do |x|
89
+ Codebase.new("#{docroot}/#{destination}/#{x}").rm
90
+ # TODO: replace 'open().read' with custom caching solution
91
+ require_relative 'contrib'
92
+ dl = Contrib.new(x, core).dl
93
+ feed_md5, archive = dl
94
+ # TODO: replace 'open().read' with custom caching solution
95
+ open(archive).read
96
+ uri = URI.parse(archive)
97
+ targz = "/tmp/open-uri-503" + [ @path, uri.host, Digest::SHA1.hexdigest(archive) ].join('/')
98
+ md5 = Digest::MD5.file(targz).hexdigest
99
+ # TODO: retry download after failed download verification
100
+ if md5 == feed_md5
101
+ Codebase.new(targz, "#{docroot}/#{destination}").extract
102
+ else
103
+ say("Verification failed for #{x} archive!", :red)
104
+ exit
105
+ end
106
+ end
107
+ if options[:vc] == true
108
+ require_relative 'repo'
109
+ require_relative 'screen'
110
+ modules.each do |x|
111
+ width = Screen.new().width
112
+ msg = "Pushing #{x} to the remote repo..."
113
+ spaces = " " * (width - msg.length - 8)
114
+ say(msg + spaces)
115
+ Repo.new(docroot, "docroot/#{destination}/#{x}").update
116
+ # TODO: error handling and conditional messaging for failures
117
+ say(" [done]", :green)
118
+ end
119
+ else
120
+ modules.each do |x|
121
+ say("#{x} added to codebase but changes are not yet tracked in version control.", :yellow)
122
+ end
123
+ end
124
+ else
125
+ say("All projects already in codebase.", :yellow)
126
+ end
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,49 @@
1
+ # encoding: utf-8
2
+ require 'fileutils'
3
+ require 'find'
4
+ require 'rubygems/package'
5
+ require 'zlib'
6
+
7
+ module Onboard
8
+
9
+ TAR_LONGLINK = '././@LongLink'
10
+
11
+ class Codebase
12
+ attr_reader :path, :dest
13
+
14
+ def initialize(path, dest = nil)
15
+ @path = path
16
+ @dest = dest
17
+ end
18
+
19
+ def rm
20
+ FileUtils.rm_r path if File.directory?(path)
21
+ end
22
+
23
+ def extract
24
+ Gem::Package::TarReader.new( Zlib::GzipReader.open path ) do |tar|
25
+ dst = nil
26
+ tar.each do |entry|
27
+ if entry.full_name == TAR_LONGLINK
28
+ dst = File.join dest, entry.read.strip
29
+ next
30
+ end
31
+ dst ||= File.join dest, entry.full_name
32
+ if entry.directory?
33
+ FileUtils.rm_rf dst unless File.directory? dst
34
+ FileUtils.mkdir_p dst, :mode => entry.header.mode, :verbose => false
35
+ elsif entry.file?
36
+ FileUtils.rm_rf dst unless File.file? dst
37
+ File.open dst, "wb" do |f|
38
+ f.print entry.read
39
+ end
40
+ FileUtils.chmod entry.header.mode, dst, :verbose => false
41
+ elsif entry.header.typeflag == '2' #Symlink!
42
+ File.symlink entry.header.linkname, dst
43
+ end
44
+ dst = nil
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,28 @@
1
+ # encoding: utf-8
2
+ require 'nokogiri'
3
+
4
+ module Onboard
5
+ class Contrib
6
+ attr_reader :project, :core
7
+
8
+ def initialize(project, core)
9
+ @feed = "http://updates.drupal.org/release-history/#{project}/#{core}"
10
+ end
11
+
12
+ def dl
13
+ doc = Nokogiri::XML(open(@feed).read)
14
+ releases = {}
15
+ doc.xpath('//releases//release').each do |item|
16
+ if !item.at_xpath('version_extra')
17
+ releases[item.at_xpath('mdhash').content] = item.at_xpath('download_link').content
18
+ end
19
+ end
20
+ if releases.nil?
21
+ doc.xpath('//releases//release').each do |item|
22
+ releases[item.at_xpath('mdhash').content] = item.at_xpath('download_link').content
23
+ end
24
+ end
25
+ return releases.first
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # TODO: Watch for updates to rugged that enable git push
4
+ require 'git'
5
+ require 'pathname'
6
+
7
+ module Onboard
8
+ class Repo
9
+ attr_reader :docroot, :path
10
+
11
+ def initialize(docroot, path)
12
+ @docroot = docroot
13
+ @path = path
14
+ end
15
+
16
+ def update
17
+ prj_root = Pathname.new(docroot)
18
+ workdir = prj_root.parent.to_s
19
+ project = File.basename(path)
20
+
21
+ g = Git.open(workdir)
22
+ g.branch('master').checkout
23
+
24
+ changes = []
25
+ g.status.changed.keys.each { |x| changes.push x }
26
+ g.status.deleted.keys.each { |x| changes.push x }
27
+ g.status.untracked.keys.each { |x| changes.push x }
28
+
29
+ if changes.nil? == false
30
+ g.add(path, :all=>true)
31
+ g.commit("Adds #{project}")
32
+ g.push
33
+ else
34
+ puts "No changes to commit for #{project}"
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'curses'
4
+
5
+ module Onboard
6
+ class Screen
7
+ Curses.init_screen()
8
+
9
+ def width
10
+ return Curses.cols
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,3 @@
1
+ module Onboard
2
+ VERSION = "0.1.2"
3
+ end
data/lib/onboard.rb ADDED
@@ -0,0 +1 @@
1
+ require 'onboard/cli'
data/onboard.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'onboard/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "onboard"
8
+ spec.version = Onboard::VERSION
9
+ spec.authors = ["Nathaniel Hoag"]
10
+ spec.email = ["info@nathanielhoag.com"]
11
+ spec.summary = %q{Automated Drupal contrib.}
12
+ spec.description = %q{Checks, downloads, verifies, adds, and commits Drupal contrib modules.}
13
+ spec.homepage = "https://github.com/nhoag/onboard"
14
+ spec.license = "MIT"
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = ["onboard"]
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+ spec.add_dependency "nokogiri", "~> 1.6"
20
+ spec.add_dependency "open-uri-cached", [">= 0.0.5", "< 2"]
21
+ spec.add_dependency "git", "~> 1.2"
22
+ spec.add_dependency "thor", [">= 0.19.1", "< 2"]
23
+ spec.add_development_dependency "bundler", "~> 1.6"
24
+ spec.add_development_dependency "rake", '~> 0'
25
+ end
metadata ADDED
@@ -0,0 +1,155 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: onboard
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.2
5
+ platform: ruby
6
+ authors:
7
+ - Nathaniel Hoag
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-05-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: nokogiri
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: open-uri-cached
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: 0.0.5
34
+ - - <
35
+ - !ruby/object:Gem::Version
36
+ version: '2'
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: 0.0.5
44
+ - - <
45
+ - !ruby/object:Gem::Version
46
+ version: '2'
47
+ - !ruby/object:Gem::Dependency
48
+ name: git
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: '1.2'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ~>
59
+ - !ruby/object:Gem::Version
60
+ version: '1.2'
61
+ - !ruby/object:Gem::Dependency
62
+ name: thor
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ! '>='
66
+ - !ruby/object:Gem::Version
67
+ version: 0.19.1
68
+ - - <
69
+ - !ruby/object:Gem::Version
70
+ version: '2'
71
+ type: :runtime
72
+ prerelease: false
73
+ version_requirements: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: 0.19.1
78
+ - - <
79
+ - !ruby/object:Gem::Version
80
+ version: '2'
81
+ - !ruby/object:Gem::Dependency
82
+ name: bundler
83
+ requirement: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ~>
86
+ - !ruby/object:Gem::Version
87
+ version: '1.6'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ~>
93
+ - !ruby/object:Gem::Version
94
+ version: '1.6'
95
+ - !ruby/object:Gem::Dependency
96
+ name: rake
97
+ requirement: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ~>
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ~>
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ description: Checks, downloads, verifies, adds, and commits Drupal contrib modules.
110
+ email:
111
+ - info@nathanielhoag.com
112
+ executables:
113
+ - onboard
114
+ extensions: []
115
+ extra_rdoc_files: []
116
+ files:
117
+ - .gitignore
118
+ - Gemfile
119
+ - LICENSE.txt
120
+ - README.md
121
+ - Rakefile
122
+ - bin/onboard
123
+ - lib/onboard.rb
124
+ - lib/onboard/cli.rb
125
+ - lib/onboard/codebase.rb
126
+ - lib/onboard/contrib.rb
127
+ - lib/onboard/repo.rb
128
+ - lib/onboard/screen.rb
129
+ - lib/onboard/version.rb
130
+ - onboard.gemspec
131
+ homepage: https://github.com/nhoag/onboard
132
+ licenses:
133
+ - MIT
134
+ metadata: {}
135
+ post_install_message:
136
+ rdoc_options: []
137
+ require_paths:
138
+ - lib
139
+ required_ruby_version: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - ! '>='
142
+ - !ruby/object:Gem::Version
143
+ version: '0'
144
+ required_rubygems_version: !ruby/object:Gem::Requirement
145
+ requirements:
146
+ - - ! '>='
147
+ - !ruby/object:Gem::Version
148
+ version: '0'
149
+ requirements: []
150
+ rubyforge_project:
151
+ rubygems_version: 2.2.2
152
+ signing_key:
153
+ specification_version: 4
154
+ summary: Automated Drupal contrib.
155
+ test_files: []