sourcerer_ 0.0.2.pre

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 (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