sourcerer_ 0.0.2.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +3 -0
  3. data/README.md +64 -0
  4. data/i18n/en.yml +15 -0
  5. data/lib/sourcerer/core.rb +100 -0
  6. data/lib/sourcerer/error.rb +13 -0
  7. data/lib/sourcerer/metadata.rb +4 -0
  8. data/lib/sourcerer/source_type.rb +45 -0
  9. data/lib/sourcerer/source_types/dir.rb +9 -0
  10. data/lib/sourcerer/source_types/git.rb +21 -0
  11. data/lib/sourcerer/source_types/zip.rb +16 -0
  12. data/lib/sourcerer.rb +29 -0
  13. data/lib/sourcerer_.rb +2 -0
  14. data/spec/fixtures/i18n.yml +5 -0
  15. data/spec/fixtures/source.dir/bar/file.bar +0 -0
  16. data/spec/fixtures/source.dir/foo/file.foo +0 -0
  17. data/spec/fixtures/source.git/COMMIT_EDITMSG +1 -0
  18. data/spec/fixtures/source.git/HEAD +1 -0
  19. data/spec/fixtures/source.git/config +7 -0
  20. data/spec/fixtures/source.git/description +1 -0
  21. data/spec/fixtures/source.git/hooks/applypatch-msg.sample +15 -0
  22. data/spec/fixtures/source.git/hooks/commit-msg.sample +24 -0
  23. data/spec/fixtures/source.git/hooks/post-update.sample +8 -0
  24. data/spec/fixtures/source.git/hooks/pre-applypatch.sample +14 -0
  25. data/spec/fixtures/source.git/hooks/pre-commit.sample +49 -0
  26. data/spec/fixtures/source.git/hooks/pre-push.sample +54 -0
  27. data/spec/fixtures/source.git/hooks/pre-rebase.sample +169 -0
  28. data/spec/fixtures/source.git/hooks/prepare-commit-msg.sample +36 -0
  29. data/spec/fixtures/source.git/hooks/update.sample +128 -0
  30. data/spec/fixtures/source.git/index +0 -0
  31. data/spec/fixtures/source.git/info/exclude +6 -0
  32. data/spec/fixtures/source.git/logs/HEAD +1 -0
  33. data/spec/fixtures/source.git/logs/refs/heads/master +1 -0
  34. data/spec/fixtures/source.git/objects/35/d778d19cdf4fea30f1f8090d3167723b3421ec +0 -0
  35. data/spec/fixtures/source.git/objects/65/5cd0061e2c5fba07b5e38fbc6a8a752f0d8a8e +0 -0
  36. data/spec/fixtures/source.git/objects/92/469c6ba0e1585b36e474ef8e5dc069daa28842 +0 -0
  37. data/spec/fixtures/source.git/objects/c7/e09aa454d4e5b551131ed168bc5ba5d6169753 +3 -0
  38. data/spec/fixtures/source.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 +0 -0
  39. data/spec/fixtures/source.git/refs/heads/master +1 -0
  40. data/spec/fixtures/source.zip +0 -0
  41. data/spec/lib/sourcerer/core_spec.rb +118 -0
  42. data/spec/lib/sourcerer/error_spec.rb +15 -0
  43. data/spec/lib/sourcerer/source_type_spec.rb +139 -0
  44. data/spec/lib/sourcerer/source_types/dir_spec.rb +2 -0
  45. data/spec/lib/sourcerer/source_types/git_spec.rb +26 -0
  46. data/spec/lib/sourcerer/source_types/zip_spec.rb +2 -0
  47. data/spec/lib/sourcerer_spec.rb +15 -0
  48. data/spec/spec_helper.rb +74 -0
  49. metadata +321 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d96577345c38942604430d4c8b59378bc098391e
4
+ data.tar.gz: fcc9390a4737f5a1d23ffdcf9ee96907452a79a9
5
+ SHA512:
6
+ metadata.gz: dc02b2c2da733a0520d13a552f2b4bf63f8f89bcbb688355a94b61863083e1d0834a8a598e958f10f9c7be84baa8cb681cdd917d8289d47b127e73dac3e41452
7
+ data.tar.gz: 3ae263f9175e8c605a390723b513bb07c4dbfde172d5675a2d449dfd41e55f2e576ffdfe94bb7fcd95ec5fb8aa46c007fccb5f8a940a519aa3305af8df2e4929
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ ###### 0.0.2.pre
2
+ ###### 0.0.1.pre
3
+ * MVP
data/README.md ADDED
@@ -0,0 +1,64 @@
1
+ [![gem version](https://badge.fury.io/rb/sourcerer_.svg)](https://rubygems.org/gems/sourcerer_)
2
+ [![dependencies](https://gemnasium.com/brewster1134/sourcerer.svg)](https://gemnasium.com/brewster1134/sourcerer)
3
+ [![docs](http://inch-ci.org/github/brewster1134/sourcerer.svg?branch=master)](http://inch-ci.org/github/brewster1134/sourcerer)
4
+ [![build](https://travis-ci.org/brewster1134/sourcerer.svg?branch=master)](https://travis-ci.org/brewster1134/sourcerer)
5
+ [![coverage](https://coveralls.io/repos/brewster1134/sourcerer/badge.svg?branch=master)](https://coveralls.io/r/brewster1134/sourcerer?branch=master)
6
+ [![code climate](https://codeclimate.com/github/brewster1134/sourcerer/badges/gpa.svg)](https://codeclimate.com/github/brewster1134/sourcerer)
7
+
8
+ # SOURCERER
9
+ ###### Consume local & remote sources with ease
10
+ ---
11
+
12
+ From inside a ruby app, you can quickly grab entire directories of assets, either locally from a zip file or folder, or remotely from a git repo or zip file.
13
+
14
+ ---
15
+ #### Install
16
+ ```shell
17
+ gem install sourcerer_
18
+ ```
19
+
20
+ ---
21
+ #### Quick Usage
22
+ ```ruby
23
+ require 'sourcerer'
24
+
25
+ # download a remote github repo to your Documents folder
26
+ source = Sourcerer.new 'brewster1134/sourcerer', '~/Documents/sourcerer'
27
+
28
+ # use file globbing to return a custom array of files
29
+ source.files '**/*_helper.rb'
30
+ => ["spec/spec_helper.rb"]
31
+ ```
32
+
33
+ ---
34
+ #### Supported Sources
35
+ * git repo
36
+ * local or remote
37
+ * github shorthand _(see example)_
38
+ * zip files
39
+ * local or remote
40
+ * local directories _(although not very useful)_
41
+ * relative or absolute paths
42
+
43
+ ---
44
+ #### Roadmap
45
+ * Command line tool
46
+ * Automate consuming multiple sources with a sourcerer.yaml file
47
+ * Support for branches, tags & commits from a git repo
48
+
49
+ ---
50
+ #### Development
51
+ ###### Install Dependencies
52
+ ```shell
53
+ # clone repo
54
+ git clone https://github.com/brewster1134/sourcerer.git
55
+ cd sourcerer
56
+
57
+ # install dependencies
58
+ bundle install
59
+
60
+ # run watcher for linting and tests
61
+ bundle exec guard
62
+ ```
63
+
64
+ [![WTFPL](http://www.wtfpl.net/wp-content/uploads/2012/12/wtfpl-badge-4.png)](http://www.wtfpl.net)
data/i18n/en.yml ADDED
@@ -0,0 +1,15 @@
1
+ en: &en
2
+ sourcerer:
3
+ errors:
4
+ core:
5
+ get_type_source:
6
+ no_type_detected: No supported type could be determined from `%{source}`. Make sure the source is in a supported format.
7
+ source_type:
8
+ initialize:
9
+ destination_already_exists: The directory %{destination} already exists. Choose a new destination to be created.
10
+
11
+ # regional variations
12
+ en_gb:
13
+ <<: *en
14
+ en_us:
15
+ <<: *en
@@ -0,0 +1,100 @@
1
+ #
2
+ # Sourcerer::Core
3
+ # Base class for initializing Sourcerer
4
+ #
5
+ class Sourcerer::Core
6
+ GIT_GITHUB_SHORTHAND_REGEX = %r{^[A-Za-z0-9-]+\/[A-Za-z0-9\-_.]+$}
7
+ attr_reader :source_type
8
+
9
+ # Initialize a new sourcerer core object
10
+ # @param source [String] A valid source location or supported shorthand
11
+ # @param destination [String] A local path to copy the source to, nil
12
+ # @return [Sourcerer::SourceType[TYPE]]
13
+ #
14
+ def initialize source, destination, options
15
+ # get absolute path of destination
16
+ destination = File.expand_path(destination)
17
+
18
+ # initialize a source type object
19
+ type_source = options[:type] || get_type_source(source)
20
+ type = type_source[:type]
21
+ source = type_source[:source]
22
+ type_class = get_type_class type
23
+ @source_type = type_class.new source, destination, options
24
+ end
25
+
26
+ # Determine the type of source based on a string
27
+ # @param source [String] A string representing a local or remote source location
28
+ # @return [Hash] An object with a supported source :type and :source
29
+ # @raise [Sourcerer::Error] Could not determine the source type based on the provided source
30
+ # @todo Add additional source types
31
+ #
32
+ # rubocop:disable Metrics/CyclomaticComplexity
33
+ def get_type_source source
34
+ type_source = nil
35
+
36
+ # LOCAL
37
+ #
38
+ # => local directory
39
+ expanded_source = File.expand_path(source)
40
+ if Dir.exist?(expanded_source)
41
+ type_source = {
42
+ type: :dir,
43
+ source: expanded_source
44
+ }
45
+
46
+ # => local file
47
+ elsif File.exist?(expanded_source)
48
+ case File.extname(expanded_source)
49
+
50
+ # => local zip file
51
+ when '.zip'
52
+ type_source = {
53
+ type: :zip,
54
+ source: expanded_source
55
+ }
56
+ end
57
+
58
+ # REMOTE
59
+ #
60
+ # => remote file
61
+ else
62
+ case File.extname(source)
63
+
64
+ # => remote zip file
65
+ when '.zip'
66
+ type_source = {
67
+ type: :zip,
68
+ source: source
69
+ }
70
+
71
+ # => remote git repo
72
+ when '.git', ''
73
+ type_source = {
74
+ type: :git,
75
+ source: source
76
+ }
77
+ end
78
+ end
79
+
80
+ return type_source unless type_source.nil?
81
+
82
+ # raise an error if no source type was found
83
+ raise Sourcerer::Error.new 'core.get_type_source.no_type_detected', source: source
84
+ end
85
+ # rubocop:enable Metrics/CyclomaticComplexity
86
+
87
+ # Initialize a new source type from the provided symbol
88
+ # @param type [Symbol] A supported source type name
89
+ # @return [Sourcerer::SourceType::[TYPE]]
90
+ #
91
+ def get_type_class type
92
+ "Sourcerer::SourceType::#{type.to_s.classify}".constantize
93
+ end
94
+
95
+ # @see Sourcerer::SourceType#files
96
+ #
97
+ def files *args
98
+ source_type.files *args
99
+ end
100
+ end
@@ -0,0 +1,13 @@
1
+ #
2
+ # Sourcerer::Error
3
+ # Custom error class
4
+ #
5
+ class Sourcerer::Error < StandardError
6
+ # @param i18n_keys [String] Dot delimited heirarchy of i18n key
7
+ # @param i18n_args_hash [Hash] Object of values to pass to i18n
8
+ # @return [Sourcerer::Error]
9
+ #
10
+ def initialize i18n_keys, i18n_args_hash
11
+ I18n.t "sourcerer.errors.#{i18n_keys}", i18n_args_hash
12
+ end
13
+ end
@@ -0,0 +1,4 @@
1
+ module Sourcerer
2
+ VERSION = '0.0.2.pre'.freeze
3
+ SUMMARY = 'Consume local & remote sources with ease'.freeze
4
+ end
@@ -0,0 +1,45 @@
1
+ #
2
+ # Sourcerer::SourceType
3
+ # Base class for supported source types
4
+ #
5
+ class Sourcerer::SourceType
6
+ def initialize source, destination, options
7
+ @destination = destination
8
+
9
+ # raise error if destination already exists
10
+ if ::Dir.exist? @destination
11
+ raise Sourcerer::Error.new 'source_type.initialize.destination_already_exists', destination: @destination
12
+ end
13
+
14
+ # calls the custom `move` method for the given type
15
+ move source, destination, options
16
+
17
+ self
18
+ end
19
+
20
+ # Return an array of file paths that match the provided glob
21
+ #
22
+ def files glob = :all, relative = false
23
+ glob = case glob
24
+ when :all
25
+ '**/*'
26
+ when :hidden
27
+ '**/.*'
28
+ else
29
+ glob
30
+ end
31
+
32
+ files = ::Dir.glob(File.join(@destination, glob), File::FNM_DOTMATCH).select do |file|
33
+ File.file? file
34
+ end
35
+
36
+ if relative
37
+ base_path = Pathname.new @destination
38
+ files = files.collect do |file|
39
+ Pathname.new(file).relative_path_from(base_path).to_s
40
+ end
41
+ end
42
+
43
+ files
44
+ end
45
+ end
@@ -0,0 +1,9 @@
1
+ #
2
+ # Sourcerer::SourceTypeDir
3
+ # Handler for directory sources
4
+ #
5
+ class Sourcerer::SourceType::Dir < Sourcerer::SourceType
6
+ def move source, destination, _options
7
+ FileUtils.cp_r "#{source}/.", destination
8
+ end
9
+ end
@@ -0,0 +1,21 @@
1
+ #
2
+ # Sourcerer::SourceTypeDir
3
+ # Handler for git repo sources
4
+ #
5
+ class Sourcerer::SourceType::Git < Sourcerer::SourceType
6
+ require 'git'
7
+
8
+ def move source, destination, _options
9
+ # if git repo is remote
10
+ unless ::Dir.exist? source
11
+ # regex to match any repo url to only the usename and repo name
12
+ # @example
13
+ # 'https://github.com/brewster1134/sourcerer.git' #=> 'brewster1134/sourcerer'
14
+ regex = %r{^(?:.*com[:\/])?([^.]+)(?:\.git)?$}
15
+ username_repo = source.match(regex)[1]
16
+ source = "https://github.com/#{username_repo}.git"
17
+ end
18
+
19
+ ::Git.clone source, destination
20
+ end
21
+ end
@@ -0,0 +1,16 @@
1
+ #
2
+ # Sourcerer::SourceTypeDir
3
+ # Handler for zip file sources
4
+ #
5
+ class Sourcerer::SourceType::Zip < Sourcerer::SourceType
6
+ require 'zip'
7
+
8
+ def move source, destination, _options
9
+ ::Zip::File.open(source) do |zip_file|
10
+ zip_file.each do |file|
11
+ file_path = File.join destination, file.name
12
+ zip_file.extract(file, file_path) unless File.exist? file_path
13
+ end
14
+ end
15
+ end
16
+ end
data/lib/sourcerer.rb ADDED
@@ -0,0 +1,29 @@
1
+ require 'active_support/core_ext/string/inflections'
2
+ require 'i18n'
3
+ require 'tmpdir'
4
+
5
+ # I18n
6
+ I18n.load_path += Dir[File.expand_path(File.join('i18n', '*.yml'))]
7
+ I18n.locale = ENV['LANG'].split('.').first.downcase
8
+ I18n.reload!
9
+
10
+ #
11
+ # Sourcerer
12
+ # Entrypoint & controller
13
+ #
14
+ module Sourcerer
15
+ def self.new source, destination, options = {}
16
+ Sourcerer::Core.new source, destination, options
17
+ end
18
+ end
19
+
20
+ # SOURCERER LIBRARY
21
+ require 'sourcerer/core'
22
+ require 'sourcerer/error'
23
+ require 'sourcerer/metadata'
24
+ require 'sourcerer/source_type'
25
+
26
+ # Requre all source types
27
+ Dir[File.join(Dir.pwd, 'lib', 'sourcerer', 'source_types', '*.rb')].each do |file|
28
+ require file
29
+ end
data/lib/sourcerer_.rb ADDED
@@ -0,0 +1,2 @@
1
+ # file to require that matches the actual gem name
2
+ require 'sourcerer'
@@ -0,0 +1,5 @@
1
+ spec:
2
+ sourcerer:
3
+ errors:
4
+ foo:
5
+ bar: This %{foo} is a %{bar}
File without changes
File without changes
@@ -0,0 +1 @@
1
+ source.git
@@ -0,0 +1 @@
1
+ ref: refs/heads/master
@@ -0,0 +1,7 @@
1
+ [core]
2
+ repositoryformatversion = 0
3
+ filemode = true
4
+ bare = false
5
+ logallrefupdates = true
6
+ ignorecase = true
7
+ precomposeunicode = true
@@ -0,0 +1 @@
1
+ Unnamed repository; edit this file 'description' to name the repository.
@@ -0,0 +1,15 @@
1
+ #!/bin/sh
2
+ #
3
+ # An example hook script to check the commit log message taken by
4
+ # applypatch from an e-mail message.
5
+ #
6
+ # The hook should exit with non-zero status after issuing an
7
+ # appropriate message if it wants to stop the commit. The hook is
8
+ # allowed to edit the commit message file.
9
+ #
10
+ # To enable this hook, rename this file to "applypatch-msg".
11
+
12
+ . git-sh-setup
13
+ test -x "$GIT_DIR/hooks/commit-msg" &&
14
+ exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"}
15
+ :
@@ -0,0 +1,24 @@
1
+ #!/bin/sh
2
+ #
3
+ # An example hook script to check the commit log message.
4
+ # Called by "git commit" with one argument, the name of the file
5
+ # that has the commit message. The hook should exit with non-zero
6
+ # status after issuing an appropriate message if it wants to stop the
7
+ # commit. The hook is allowed to edit the commit message file.
8
+ #
9
+ # To enable this hook, rename this file to "commit-msg".
10
+
11
+ # Uncomment the below to add a Signed-off-by line to the message.
12
+ # Doing this in a hook is a bad idea in general, but the prepare-commit-msg
13
+ # hook is more suited to it.
14
+ #
15
+ # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
16
+ # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
17
+
18
+ # This example catches duplicate Signed-off-by lines.
19
+
20
+ test "" = "$(grep '^Signed-off-by: ' "$1" |
21
+ sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || {
22
+ echo >&2 Duplicate Signed-off-by lines.
23
+ exit 1
24
+ }
@@ -0,0 +1,8 @@
1
+ #!/bin/sh
2
+ #
3
+ # An example hook script to prepare a packed repository for use over
4
+ # dumb transports.
5
+ #
6
+ # To enable this hook, rename this file to "post-update".
7
+
8
+ exec git update-server-info
@@ -0,0 +1,14 @@
1
+ #!/bin/sh
2
+ #
3
+ # An example hook script to verify what is about to be committed
4
+ # by applypatch from an e-mail message.
5
+ #
6
+ # The hook should exit with non-zero status after issuing an
7
+ # appropriate message if it wants to stop the commit.
8
+ #
9
+ # To enable this hook, rename this file to "pre-applypatch".
10
+
11
+ . git-sh-setup
12
+ test -x "$GIT_DIR/hooks/pre-commit" &&
13
+ exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"}
14
+ :
@@ -0,0 +1,49 @@
1
+ #!/bin/sh
2
+ #
3
+ # An example hook script to verify what is about to be committed.
4
+ # Called by "git commit" with no arguments. The hook should
5
+ # exit with non-zero status after issuing an appropriate message if
6
+ # it wants to stop the commit.
7
+ #
8
+ # To enable this hook, rename this file to "pre-commit".
9
+
10
+ if git rev-parse --verify HEAD >/dev/null 2>&1
11
+ then
12
+ against=HEAD
13
+ else
14
+ # Initial commit: diff against an empty tree object
15
+ against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
16
+ fi
17
+
18
+ # If you want to allow non-ASCII filenames set this variable to true.
19
+ allownonascii=$(git config --bool hooks.allownonascii)
20
+
21
+ # Redirect output to stderr.
22
+ exec 1>&2
23
+
24
+ # Cross platform projects tend to avoid non-ASCII filenames; prevent
25
+ # them from being added to the repository. We exploit the fact that the
26
+ # printable range starts at the space character and ends with tilde.
27
+ if [ "$allownonascii" != "true" ] &&
28
+ # Note that the use of brackets around a tr range is ok here, (it's
29
+ # even required, for portability to Solaris 10's /usr/bin/tr), since
30
+ # the square bracket bytes happen to fall in the designated range.
31
+ test $(git diff --cached --name-only --diff-filter=A -z $against |
32
+ LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
33
+ then
34
+ cat <<\EOF
35
+ Error: Attempt to add a non-ASCII file name.
36
+
37
+ This can cause problems if you want to work with people on other platforms.
38
+
39
+ To be portable it is advisable to rename the file.
40
+
41
+ If you know what you are doing you can disable this check using:
42
+
43
+ git config hooks.allownonascii true
44
+ EOF
45
+ exit 1
46
+ fi
47
+
48
+ # If there are whitespace errors, print the offending file names and fail.
49
+ exec git diff-index --check --cached $against --
@@ -0,0 +1,54 @@
1
+ #!/bin/sh
2
+
3
+ # An example hook script to verify what is about to be pushed. Called by "git
4
+ # push" after it has checked the remote status, but before anything has been
5
+ # pushed. If this script exits with a non-zero status nothing will be pushed.
6
+ #
7
+ # This hook is called with the following parameters:
8
+ #
9
+ # $1 -- Name of the remote to which the push is being done
10
+ # $2 -- URL to which the push is being done
11
+ #
12
+ # If pushing without using a named remote those arguments will be equal.
13
+ #
14
+ # Information about the commits which are being pushed is supplied as lines to
15
+ # the standard input in the form:
16
+ #
17
+ # <local ref> <local sha1> <remote ref> <remote sha1>
18
+ #
19
+ # This sample shows how to prevent push of commits where the log message starts
20
+ # with "WIP" (work in progress).
21
+
22
+ remote="$1"
23
+ url="$2"
24
+
25
+ z40=0000000000000000000000000000000000000000
26
+
27
+ IFS=' '
28
+ while read local_ref local_sha remote_ref remote_sha
29
+ do
30
+ if [ "$local_sha" = $z40 ]
31
+ then
32
+ # Handle delete
33
+ :
34
+ else
35
+ if [ "$remote_sha" = $z40 ]
36
+ then
37
+ # New branch, examine all commits
38
+ range="$local_sha"
39
+ else
40
+ # Update to existing branch, examine new commits
41
+ range="$remote_sha..$local_sha"
42
+ fi
43
+
44
+ # Check for WIP commit
45
+ commit=`git rev-list -n 1 --grep '^WIP' "$range"`
46
+ if [ -n "$commit" ]
47
+ then
48
+ echo "Found WIP commit in $local_ref, not pushing"
49
+ exit 1
50
+ fi
51
+ fi
52
+ done
53
+
54
+ exit 0