fife 0.0.1.alpha

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,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 43c985295f282009483540caf7df104753ccbc59
4
+ data.tar.gz: aa20d1317ca9286b8eb0937cb4d3b56df0eee3cd
5
+ SHA512:
6
+ metadata.gz: 09931e0e7810f6ecb565887186f6336adeb4b16c11161ddbf68622e8fe3618d8d826b6fda0b59ebc9a28291907e13cb348f265bd1e6129aab900ddaad1037ae4
7
+ data.tar.gz: 65b51126ee185b42ce488d678837fcd6ec5f8309dac05ee02e74562668f9f17a0170b50488bafcfd424e5898b415cfd5f3bc89f018954fde2426f3352895f344
data/.gitignore ADDED
@@ -0,0 +1,126 @@
1
+ # Created by .ignore support plugin (hsz.mobi)
2
+ ### Linux template
3
+ *~
4
+
5
+ # KDE directory preferences
6
+ .directory
7
+
8
+ # Linux trash folder which might appear on any partition or disk
9
+ .Trash-*
10
+ ### JetBrains template
11
+ # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio
12
+
13
+ *.iml
14
+
15
+ ## Directory-based project format:
16
+ .idea/
17
+ # if you remove the above rule, at least ignore the following:
18
+
19
+ # User-specific stuff:
20
+ # .idea/workspace.xml
21
+ # .idea/tasks.xml
22
+ # .idea/dictionaries
23
+
24
+ # Sensitive or high-churn files:
25
+ # .idea/dataSources.ids
26
+ # .idea/dataSources.xml
27
+ # .idea/sqlDataSources.xml
28
+ # .idea/dynamic.xml
29
+ # .idea/uiDesigner.xml
30
+
31
+ # Gradle:
32
+ # .idea/gradle.xml
33
+ # .idea/libraries
34
+
35
+ # Mongo Explorer plugin:
36
+ # .idea/mongoSettings.xml
37
+
38
+ ## File-based project format:
39
+ *.ipr
40
+ *.iws
41
+
42
+ ## Plugin-specific files:
43
+
44
+ # IntelliJ
45
+ /out/
46
+
47
+ # mpeltonen/sbt-idea plugin
48
+ .idea_modules/
49
+
50
+ # JIRA plugin
51
+ atlassian-ide-plugin.xml
52
+
53
+ # Crashlytics plugin (for Android Studio and IntelliJ)
54
+ com_crashlytics_export_strings.xml
55
+ crashlytics.properties
56
+ crashlytics-build.properties
57
+ ### Vim template
58
+ [._]*.s[a-w][a-z]
59
+ [._]s[a-w][a-z]
60
+ *.un~
61
+ Session.vim
62
+ .netrwhist
63
+ *~
64
+ ### Ruby template
65
+ *.gem
66
+ *.rbc
67
+ /.config
68
+ /coverage/
69
+ /InstalledFiles
70
+ /pkg/
71
+ /spec/reports/
72
+ /spec/examples.txt
73
+ /test/tmp/
74
+ /test/version_tmp/
75
+ /tmp/
76
+
77
+ ## Specific to RubyMotion:
78
+ .dat*
79
+ .repl_history
80
+ build/
81
+
82
+ ## Documentation cache and generated files:
83
+ /.yardoc/
84
+ /_yardoc/
85
+ /doc/
86
+ /rdoc/
87
+
88
+ ## Environment normalisation:
89
+ /.bundle/
90
+ /vendor/bundle
91
+ /lib/bundler/man/
92
+
93
+ # for a library or gem, you might want to ignore these files since the code is
94
+ # intended to run in multiple environments; otherwise, check them in:
95
+ # Gemfile.lock
96
+ # .ruby-version
97
+ # .ruby-gemset
98
+
99
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
100
+ .rvmrc
101
+ ### OSX template
102
+ .DS_Store
103
+ .AppleDouble
104
+ .LSOverride
105
+
106
+ # Icon must end with two \r
107
+ Icon
108
+
109
+ # Thumbnails
110
+ ._*
111
+
112
+ # Files that might appear in the root of a volume
113
+ .DocumentRevisions-V100
114
+ .fseventsd
115
+ .Spotlight-V100
116
+ .TemporaryItems
117
+ .Trashes
118
+ .VolumeIcon.icns
119
+
120
+ # Directories potentially created on remote AFP share
121
+ .AppleDB
122
+ .AppleDesktop
123
+ Network Trash Folder
124
+ Temporary Items
125
+ .apdisk
126
+
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.3
4
+ before_install: gem install bundler -v 1.10.6
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'http://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in fife.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,52 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ fife (0.0.1.alpha)
5
+ activesupport (~> 4.2)
6
+ net-sftp (~> 2.1)
7
+
8
+ GEM
9
+ remote: http://rubygems.org/
10
+ specs:
11
+ activesupport (4.2.5)
12
+ i18n (~> 0.7)
13
+ json (~> 1.7, >= 1.7.7)
14
+ minitest (~> 5.1)
15
+ thread_safe (~> 0.3, >= 0.3.4)
16
+ tzinfo (~> 1.1)
17
+ diff-lcs (1.2.5)
18
+ i18n (0.7.0)
19
+ json (1.8.3)
20
+ minitest (5.8.3)
21
+ net-sftp (2.1.2)
22
+ net-ssh (>= 2.6.5)
23
+ net-ssh (3.0.1)
24
+ rake (10.4.2)
25
+ rspec (3.4.0)
26
+ rspec-core (~> 3.4.0)
27
+ rspec-expectations (~> 3.4.0)
28
+ rspec-mocks (~> 3.4.0)
29
+ rspec-core (3.4.1)
30
+ rspec-support (~> 3.4.0)
31
+ rspec-expectations (3.4.0)
32
+ diff-lcs (>= 1.2.0, < 2.0)
33
+ rspec-support (~> 3.4.0)
34
+ rspec-mocks (3.4.0)
35
+ diff-lcs (>= 1.2.0, < 2.0)
36
+ rspec-support (~> 3.4.0)
37
+ rspec-support (3.4.1)
38
+ thread_safe (0.3.5)
39
+ tzinfo (1.2.2)
40
+ thread_safe (~> 0.1)
41
+
42
+ PLATFORMS
43
+ ruby
44
+
45
+ DEPENDENCIES
46
+ bundler (~> 1.10)
47
+ fife!
48
+ rake (~> 10.0)
49
+ rspec (~> 3.4)
50
+
51
+ BUNDLED WITH
52
+ 1.10.6
data/README.md ADDED
@@ -0,0 +1,135 @@
1
+ # Fife
2
+
3
+ **Fife** is a multiple IO pipelining tool, originally designed for
4
+ file uploading through HTTP, but can be used in any other cases.
5
+
6
+ ## Warning
7
+ This gem is in early development stage, and the interface could be changed enormously in future releases.
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ ```ruby
14
+ gem 'fife'
15
+ ```
16
+
17
+ And then execute:
18
+
19
+ $ bundle
20
+
21
+ Or install it yourself as:
22
+
23
+ $ gem install fife
24
+
25
+ ## Usage
26
+
27
+ Create a `Fife` instance by calling `Fife(io_ary)`,
28
+ then chain as many `pipe` calls as you want.
29
+
30
+ ```ruby
31
+ io_ary = [
32
+ File.new('/path/to/my/file'),
33
+ StringIO.new('Hello world'),
34
+ Tempfile.new('temp')
35
+ ]
36
+
37
+ Fife(io_ary).pipe(-> io {io})
38
+ .pipe(-> io {[io, io]})
39
+ .pipe(:close)
40
+ ```
41
+
42
+ ### Kernel#Fife(*ios)
43
+
44
+ This method returns a `Fife::Pipe` instance for chaining.
45
+
46
+ This method expect 0 or more IO-like objects as arguments.
47
+ Alternatively it can take an array of IO-like objects
48
+
49
+ ### Fife::Pipe#pipe
50
+
51
+ This method returns a new `Fife::Pipe` instance.
52
+
53
+ It has 2 forms of usage:
54
+
55
+ 1. pass an operation as the argument
56
+ `Fife(io_ary).pipe(->io{io})`
57
+ 2. pass the underscored name of an operation class,
58
+ and 0 or more arguments as the constructor arguments of that class.
59
+ `Fife(io_ary).pipe(:store, my_storage)`
60
+ see *Define custom operations* for detail.
61
+
62
+ ### Operation
63
+
64
+ An operation is an object that responds to `call(io)`, and returns 0 or more IO-like objects.
65
+ A *lambda* is often used as an operation, but an operation can be of any type.
66
+
67
+ Currently, `Fife` ships with 4 operations: `:noop`, `:name`, `:store` and `:close`
68
+
69
+ * noop
70
+ Performs no operation on the IO, and returns the IO directly.
71
+ * close
72
+ Closes the
73
+ * store
74
+ Stores the content of the IO.
75
+ * name
76
+ Gives the IO a name according to the per-io naming strategy you specified.
77
+ You can retrieve it's name by calling `#name` on the IO instance.
78
+ ```ruby
79
+ name = Fife::Operations::Name.new(->io { 'some_name' })
80
+ Fife(io_ary).pipe(name)
81
+
82
+ # Or
83
+ Fife(io_ary).pipe(:name, ->io { 'some_name' })
84
+ ```
85
+
86
+ #### Define custom operations
87
+
88
+ If you feel lambdas are not enough for your job,
89
+ you can easily define your own operations.
90
+
91
+ ```ruby
92
+ class Fife::Operations::MyOperation
93
+ def initialize(arg1, arg2)
94
+ # Initialize the Operation
95
+ end
96
+
97
+ def call(io)
98
+ # Handle the io and return some IO instances
99
+ end
100
+ end
101
+ ```
102
+ Then you can use it like
103
+ ```ruby
104
+ Fife(io_ary).pipe(:my_operation, 1, 2)
105
+ ```
106
+
107
+ ### Storage
108
+ To leverage the `:store` operation, you need a *storage*.
109
+
110
+ A storage is just an object that responds to `store(io)`.
111
+
112
+ Currently, **Fife** ships with 2 storage classes:
113
+
114
+ * `Fife::Storage::Null`
115
+ Simply does nothing
116
+ * `Fife::Storage::Sftp`
117
+ Streams the IO to a remote file via SFTP.
118
+ This storage should be used with `:name` operation because
119
+ the remote filename depends on the name of the IO.
120
+ (I know it's nasty, but it's still under developing)
121
+
122
+ ```ruby
123
+ storage = Fife::Storage::Sftp.new('localhost', 'me', '/path/to/remote/dir', password: 'P@ssw0rd')
124
+ Fife(io_ary).pipe(:store, storage)
125
+ ```
126
+
127
+ ## Development
128
+
129
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake false` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
130
+
131
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
132
+
133
+ ## Contributing
134
+
135
+ Bug reports and pull requests are welcome on GitHub at https://github.com/aetherus/fife.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'fife'
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require 'irb'
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
data/fife.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'fife/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'fife'
8
+ spec.version = Fife::VERSION
9
+ spec.authors = ['aetherus']
10
+ spec.email = ['aetherus.zhou@gmail.com']
11
+ spec.licenses = ['MIT']
12
+
13
+ spec.summary = 'A multiple IO pipelining tool'
14
+ spec.description = %q{
15
+ A multiple IO pipelining tool.
16
+ You can use it to spawn as many or as few IO-like instances from 0 or more IO-like instances.
17
+ }
18
+ spec.homepage = 'https://github.com/aetherus/fife'
19
+
20
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
21
+ spec.bindir = 'bin'
22
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
+ spec.require_paths = ['lib']
24
+
25
+ spec.add_development_dependency 'bundler', '~> 1.10'
26
+ spec.add_development_dependency 'rake', '~> 10.0'
27
+ spec.add_development_dependency 'rspec', '~> 3.4'
28
+ spec.add_runtime_dependency 'net-sftp', '~> 2.1'
29
+ spec.add_runtime_dependency 'activesupport', '~> 4.2'
30
+ end
@@ -0,0 +1,8 @@
1
+ module Fife::HasName
2
+ def self.extended(obj)
3
+ class << obj
4
+ attr_reader :name unless instance_methods(true).include? :name
5
+ attr_writer :name unless instance_methods(true).include? :name=
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,5 @@
1
+ class Fife::Operations::Close
2
+ def call(io)
3
+ io.close unless io.closed?
4
+ end
5
+ end
@@ -0,0 +1,14 @@
1
+ require 'pathname'
2
+ require 'fileutils'
3
+
4
+ class Fife::Operations::Name
5
+ def initialize(naming)
6
+ @naming = naming
7
+ end
8
+
9
+ def call(io)
10
+ io.extend(Fife::HasName)
11
+ io.name = @naming.call(io)
12
+ io
13
+ end
14
+ end
@@ -0,0 +1,5 @@
1
+ class Fife::Operations::Noop
2
+ def call(io)
3
+ io
4
+ end
5
+ end
@@ -0,0 +1,11 @@
1
+ class Fife::Operations::Store
2
+ attr_reader :storage
3
+
4
+ def initialize(storage)
5
+ @storage = storage
6
+ end
7
+
8
+ def call(io)
9
+ storage.store(io)
10
+ end
11
+ end
@@ -0,0 +1,8 @@
1
+ module Fife::Operations
2
+ extend ActiveSupport::Autoload
3
+
4
+ autoload :Noop
5
+ autoload :Close
6
+ autoload :Name
7
+ autoload :Store
8
+ end
data/lib/fife/pipe.rb ADDED
@@ -0,0 +1,22 @@
1
+ class Fife::Pipe
2
+
3
+ attr_reader :ios
4
+
5
+ def initialize(ios)
6
+ @ios = ios.flatten.tap(&:compact!)
7
+ end
8
+
9
+ def pipe(op, *args)
10
+ op = Fife::Operations.const_get(op.to_s.camelize.to_sym).new(*args) unless op.respond_to? :call
11
+ output = []
12
+
13
+ ios.map { |io|
14
+ Thread.new do
15
+ output << op.call(io.tap(&:rewind))
16
+ end
17
+ }.each(&:join)
18
+
19
+ self.class.new(output)
20
+ end
21
+
22
+ end
@@ -0,0 +1,5 @@
1
+ class Fife::Storage::Null
2
+ def store(io)
3
+ # Do nothing
4
+ end
5
+ end
@@ -0,0 +1,31 @@
1
+ require 'net/sftp'
2
+ require 'pathname'
3
+ require 'fileutils'
4
+
5
+ class Fife::Storage::Sftp
6
+ attr_reader :host, :user, :remote_dir, :ssh_options
7
+
8
+ def initialize(host, user, remote_dir, ssh_options)
9
+ @host, @user, @ssh_options = host, user, ssh_options
10
+ @remote_dir = Pathname(remote_dir)
11
+ ensure_remote_dir_presence!
12
+ end
13
+
14
+ def store(io)
15
+ raise UnnamedIO unless io.respond_to? :name
16
+ remote_path = remote_dir.join(io.name)
17
+ Net::SFTP.start(host, user, ssh_options) do |sftp|
18
+ sftp.file.open(remote_path, 'w') { |f| IO.copy_stream(io, f) }
19
+ end
20
+ io.close
21
+ end
22
+
23
+ private
24
+ def ensure_remote_dir_presence!
25
+ Net::SFTP.start(host, user, ssh_options) do |sftp|
26
+ remote_dir.descend do |path|
27
+ sftp.mkdir!(path) rescue nil
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,8 @@
1
+ module Fife::Storage
2
+ extend ActiveSupport::Autoload
3
+
4
+ class UnnamedIO < RuntimeError; end
5
+
6
+ autoload :Null
7
+ autoload :Sftp
8
+ end
@@ -0,0 +1,3 @@
1
+ module Fife
2
+ VERSION = "0.0.1.alpha"
3
+ end
data/lib/fife.rb ADDED
@@ -0,0 +1,17 @@
1
+ require 'fife/version'
2
+ require 'active_support/all'
3
+
4
+ module Fife
5
+ extend ActiveSupport::Autoload
6
+
7
+ autoload :Pipe
8
+ autoload :Operations
9
+ autoload :Storage
10
+ autoload :HasName
11
+ end
12
+
13
+ module Kernel
14
+ def Fife(*ios)
15
+ Fife::Pipe.new(ios)
16
+ end
17
+ end
metadata ADDED
@@ -0,0 +1,136 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fife
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1.alpha
5
+ platform: ruby
6
+ authors:
7
+ - aetherus
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-11-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.10'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.10'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.4'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.4'
55
+ - !ruby/object:Gem::Dependency
56
+ name: net-sftp
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '2.1'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '2.1'
69
+ - !ruby/object:Gem::Dependency
70
+ name: activesupport
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '4.2'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '4.2'
83
+ description: "\n A multiple IO pipelining tool.\n You can use it to spawn as
84
+ many or as few IO-like instances from 0 or more IO-like instances.\n "
85
+ email:
86
+ - aetherus.zhou@gmail.com
87
+ executables: []
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - ".gitignore"
92
+ - ".travis.yml"
93
+ - Gemfile
94
+ - Gemfile.lock
95
+ - README.md
96
+ - Rakefile
97
+ - bin/console
98
+ - bin/setup
99
+ - fife.gemspec
100
+ - lib/fife.rb
101
+ - lib/fife/has_name.rb
102
+ - lib/fife/operations.rb
103
+ - lib/fife/operations/close.rb
104
+ - lib/fife/operations/name.rb
105
+ - lib/fife/operations/noop.rb
106
+ - lib/fife/operations/store.rb
107
+ - lib/fife/pipe.rb
108
+ - lib/fife/storage.rb
109
+ - lib/fife/storage/null.rb
110
+ - lib/fife/storage/sftp.rb
111
+ - lib/fife/version.rb
112
+ homepage: https://github.com/aetherus/fife
113
+ licenses:
114
+ - MIT
115
+ metadata: {}
116
+ post_install_message:
117
+ rdoc_options: []
118
+ require_paths:
119
+ - lib
120
+ required_ruby_version: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ required_rubygems_version: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - ">"
128
+ - !ruby/object:Gem::Version
129
+ version: 1.3.1
130
+ requirements: []
131
+ rubyforge_project:
132
+ rubygems_version: 2.4.8
133
+ signing_key:
134
+ specification_version: 4
135
+ summary: A multiple IO pipelining tool
136
+ test_files: []