file_structure 0.1.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 +7 -0
- data/.rubocop.yml +45 -0
- data/Gemfile +24 -0
- data/Gemfile.lock +73 -0
- data/LICENSE.txt +21 -0
- data/README.md +54 -0
- data/Rakefile +20 -0
- data/file_structure.gemspec +40 -0
- data/lib/file_structure/contract.rb +19 -0
- data/lib/file_structure/validator.rb +57 -0
- data/lib/file_structure/version.rb +5 -0
- data/lib/file_structure.rb +122 -0
- metadata +64 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: b0896ec610bd688790fad3b0f995766076ffee13148ff16ee3f9e9ae7a646b34
|
4
|
+
data.tar.gz: e3a445ce085c12d7a7971dbed9469b48247d0a130fdb91acb2b28696f84d9a62
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 48cd8e05e96096a21265e5c3e69f7bc5bb2bf11e5094984006f938dc79fd186fcbe8ac9f97d31d11a431db756f940780741924abdac37fccdc555e51bba75f6a
|
7
|
+
data.tar.gz: c12c1441fd3dc451fdbe179bec7c4b0a90f8f473990de86273b9200db757aa75f173a12b35b7c071e5ccb1642b55c58aff5554666549cdafc95ba147dde4e2ee
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# See list of defaults here: https://docs.rubocop.org/rubocop/index.html
|
2
|
+
|
3
|
+
require:
|
4
|
+
- rubocop-performance
|
5
|
+
- rubocop-minitest
|
6
|
+
- rubocop-rake
|
7
|
+
|
8
|
+
AllCops:
|
9
|
+
TargetRubyVersion: 2.6
|
10
|
+
NewCops: enable
|
11
|
+
|
12
|
+
# ------------------------------------------------------------------------------
|
13
|
+
# DEPARTMENT LAYOUT
|
14
|
+
# ------------------------------------------------------------------------------
|
15
|
+
|
16
|
+
Layout/FirstArrayElementIndentation:
|
17
|
+
EnforcedStyle: consistent # default: special_inside_parentheses
|
18
|
+
|
19
|
+
Layout/FirstHashElementIndentation:
|
20
|
+
EnforcedStyle: consistent # default: special_inside_parentheses
|
21
|
+
|
22
|
+
Layout/LineLength:
|
23
|
+
Max: 80 # default: 120
|
24
|
+
|
25
|
+
# ------------------------------------------------------------------------------
|
26
|
+
# DEPARTMENT METRICS
|
27
|
+
# ------------------------------------------------------------------------------
|
28
|
+
|
29
|
+
Metrics/AbcSize:
|
30
|
+
Max: 20 # default: 17
|
31
|
+
|
32
|
+
Metrics/BlockLength:
|
33
|
+
Exclude:
|
34
|
+
- file_structure.gemspec
|
35
|
+
- test/**/test_*.rb
|
36
|
+
|
37
|
+
Metrics/MethodLength:
|
38
|
+
Max: 15 # default: 10
|
39
|
+
|
40
|
+
# ------------------------------------------------------------------------------
|
41
|
+
# DEPARTMENT STYLE
|
42
|
+
# ------------------------------------------------------------------------------
|
43
|
+
|
44
|
+
Style/Documentation:
|
45
|
+
Enabled: false # default: true
|
data/Gemfile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
source 'https://rubygems.org'
|
4
|
+
|
5
|
+
# Specify your gem's dependencies in file_structure.gemspec
|
6
|
+
gemspec
|
7
|
+
|
8
|
+
group :development do
|
9
|
+
gem 'rake', '~> 13.0'
|
10
|
+
gem 'rubocop', '~> 1.21', require: false
|
11
|
+
gem 'rubocop-minitest', '~> 0.17.2', require: false
|
12
|
+
gem 'rubocop-performance', '~> 1.13', require: false
|
13
|
+
gem 'rubocop-rake', '~> 0.6.0', require: false
|
14
|
+
gem 'yard', '~> 0.9.27', require: false
|
15
|
+
end
|
16
|
+
|
17
|
+
group :test do
|
18
|
+
gem 'minitest', '~> 5.0'
|
19
|
+
gem 'minitest-reporters', '~> 1.5'
|
20
|
+
end
|
21
|
+
|
22
|
+
group :development, :test do
|
23
|
+
gem 'debug', '~> 1.4'
|
24
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
file_structure (0.1.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
ansi (1.5.0)
|
10
|
+
ast (2.4.2)
|
11
|
+
builder (3.2.4)
|
12
|
+
debug (1.4.0)
|
13
|
+
irb (>= 1.3.6)
|
14
|
+
reline (>= 0.2.7)
|
15
|
+
io-console (0.5.11)
|
16
|
+
irb (1.4.1)
|
17
|
+
reline (>= 0.3.0)
|
18
|
+
minitest (5.15.0)
|
19
|
+
minitest-reporters (1.5.0)
|
20
|
+
ansi
|
21
|
+
builder
|
22
|
+
minitest (>= 5.0)
|
23
|
+
ruby-progressbar
|
24
|
+
parallel (1.21.0)
|
25
|
+
parser (3.1.1.0)
|
26
|
+
ast (~> 2.4.1)
|
27
|
+
rainbow (3.1.1)
|
28
|
+
rake (13.0.6)
|
29
|
+
regexp_parser (2.2.1)
|
30
|
+
reline (0.3.1)
|
31
|
+
io-console (~> 0.5)
|
32
|
+
rexml (3.2.5)
|
33
|
+
rubocop (1.25.1)
|
34
|
+
parallel (~> 1.10)
|
35
|
+
parser (>= 3.1.0.0)
|
36
|
+
rainbow (>= 2.2.2, < 4.0)
|
37
|
+
regexp_parser (>= 1.8, < 3.0)
|
38
|
+
rexml
|
39
|
+
rubocop-ast (>= 1.15.1, < 2.0)
|
40
|
+
ruby-progressbar (~> 1.7)
|
41
|
+
unicode-display_width (>= 1.4.0, < 3.0)
|
42
|
+
rubocop-ast (1.16.0)
|
43
|
+
parser (>= 3.1.1.0)
|
44
|
+
rubocop-minitest (0.17.2)
|
45
|
+
rubocop (>= 0.90, < 2.0)
|
46
|
+
rubocop-performance (1.13.2)
|
47
|
+
rubocop (>= 1.7.0, < 2.0)
|
48
|
+
rubocop-ast (>= 0.4.0)
|
49
|
+
rubocop-rake (0.6.0)
|
50
|
+
rubocop (~> 1.0)
|
51
|
+
ruby-progressbar (1.11.0)
|
52
|
+
unicode-display_width (2.1.0)
|
53
|
+
webrick (1.7.0)
|
54
|
+
yard (0.9.27)
|
55
|
+
webrick (~> 1.7.0)
|
56
|
+
|
57
|
+
PLATFORMS
|
58
|
+
x86_64-linux
|
59
|
+
|
60
|
+
DEPENDENCIES
|
61
|
+
debug (~> 1.4)
|
62
|
+
file_structure!
|
63
|
+
minitest (~> 5.0)
|
64
|
+
minitest-reporters (~> 1.5)
|
65
|
+
rake (~> 13.0)
|
66
|
+
rubocop (~> 1.21)
|
67
|
+
rubocop-minitest (~> 0.17.2)
|
68
|
+
rubocop-performance (~> 1.13)
|
69
|
+
rubocop-rake (~> 0.6.0)
|
70
|
+
yard (~> 0.9.27)
|
71
|
+
|
72
|
+
BUNDLED WITH
|
73
|
+
2.3.7
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2022 Rémi Durieu
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# file_structure
|
2
|
+
|
3
|
+
[](https://github.com/durierem/file_structure/actions/workflows/test.yml)
|
4
|
+
[](https://github.com/durierem/file_structure/actions/workflows/lint.yml)
|
5
|
+
|
6
|
+
Define a file structure with a `Hash` with support for files, file content,
|
7
|
+
directories and symlinks across the structure. Mount and unmount the structure
|
8
|
+
in a directory on the file system.
|
9
|
+
|
10
|
+
Useful for creating test environment for programs that manipulate
|
11
|
+
files but can be used as is for something else entirely.
|
12
|
+
|
13
|
+
## Usage
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
# Example creating the following file hierarchy:
|
17
|
+
# /tmp/mydir
|
18
|
+
# ├── dir1
|
19
|
+
# │ ├── dir2
|
20
|
+
# │ │ └── file2
|
21
|
+
# │ ├── file3
|
22
|
+
# │ └── link_to_file2 -> /tmp/mydir/dir1/dir2/file2
|
23
|
+
# └── file1
|
24
|
+
|
25
|
+
fs = FileStructure.new([
|
26
|
+
{ type: :file, name: 'file1' },
|
27
|
+
{
|
28
|
+
type: :directory,
|
29
|
+
name: 'dir1',
|
30
|
+
children: [
|
31
|
+
{
|
32
|
+
type: :directory,
|
33
|
+
name: 'dir2',
|
34
|
+
children: [
|
35
|
+
{ type: :file, name: 'file2', ref: 'ref_file2', content: 'abc' }
|
36
|
+
]
|
37
|
+
},
|
38
|
+
{ type: :file, name: 'file3' },
|
39
|
+
{ type: :symlink, name: 'link_to_file2', to: 'ref_file2' }
|
40
|
+
]
|
41
|
+
}
|
42
|
+
])
|
43
|
+
|
44
|
+
fs.mount('/tmp/mydir') # also creates the /tmp/mydir directory if it doesn't exist
|
45
|
+
fs.mounted? # => true
|
46
|
+
fs.mountpoint # => "/tmp/mydir"
|
47
|
+
fs.unmount # deletes all files in /tmp/mydir
|
48
|
+
|
49
|
+
JSON.dump(fs.structure) # (bonus) easily serializable :D
|
50
|
+
```
|
51
|
+
|
52
|
+
## License
|
53
|
+
|
54
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/gem_tasks'
|
4
|
+
require 'rake/testtask'
|
5
|
+
require 'rubocop/rake_task'
|
6
|
+
|
7
|
+
Rake::TestTask.new(:test) do |t|
|
8
|
+
t.libs << 'test'
|
9
|
+
t.libs << 'lib'
|
10
|
+
t.test_files = FileList['test/**/test_*.rb']
|
11
|
+
end
|
12
|
+
|
13
|
+
RuboCop::RakeTask.new
|
14
|
+
|
15
|
+
desc 'Generate documentation with Yard'
|
16
|
+
task :doc do
|
17
|
+
sh 'yard doc --no-private'
|
18
|
+
end
|
19
|
+
|
20
|
+
task default: %i[test rubocop doc]
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'lib/file_structure/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = 'file_structure'
|
7
|
+
spec.version = FileStructure::VERSION
|
8
|
+
spec.authors = ['Rémi Durieu']
|
9
|
+
spec.email = ['mail@remidurieu.dev']
|
10
|
+
|
11
|
+
spec.summary = <<-TEXT
|
12
|
+
Manage file structures (ie: files and directories) on the file system.
|
13
|
+
TEXT
|
14
|
+
spec.description = <<-TEXT
|
15
|
+
Describe a file structure with a Ruby Hash. Supports files, file content,
|
16
|
+
directories and symlinks across the structure.
|
17
|
+
|
18
|
+
Mount and unmount the desired structured in a directory on the file system.
|
19
|
+
|
20
|
+
Useful for creating test environment for programs that manipulate
|
21
|
+
files but can be used as is for something else entirely.
|
22
|
+
TEXT
|
23
|
+
spec.homepage = 'https://github.com/durierem/file_structure'
|
24
|
+
spec.license = 'MIT'
|
25
|
+
spec.required_ruby_version = '>= 2.6.0'
|
26
|
+
|
27
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
28
|
+
spec.metadata['source_code_uri'] = spec.homepage
|
29
|
+
|
30
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
31
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
32
|
+
(f == __FILE__) || f.match(%r{\A(?:(?:bin|test|features)/|\.(?:git))})
|
33
|
+
end
|
34
|
+
end
|
35
|
+
spec.bindir = 'exe'
|
36
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
37
|
+
spec.require_paths = ['lib']
|
38
|
+
|
39
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
40
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class FileStructure
|
4
|
+
module Contract
|
5
|
+
module_function
|
6
|
+
|
7
|
+
class AssertionError < ArgumentError; end
|
8
|
+
|
9
|
+
# @param expression [Boolean] The expression to evaluate
|
10
|
+
# @param message [String] The message to attach to the raised error
|
11
|
+
#
|
12
|
+
# @raise [AssertionError] if the expression evaluates to false
|
13
|
+
#
|
14
|
+
# @api private
|
15
|
+
def assert(expression, message = '')
|
16
|
+
raise AssertionError, message unless expression
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class FileStructure
|
4
|
+
# @private
|
5
|
+
class Validator
|
6
|
+
def initialize(structure)
|
7
|
+
@structure = structure
|
8
|
+
end
|
9
|
+
|
10
|
+
def valid?
|
11
|
+
valid_structure?(@structure)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def valid_structure?(structure)
|
17
|
+
return false unless structure.is_a?(Array)
|
18
|
+
|
19
|
+
structure.all? do |elem|
|
20
|
+
return false unless elem.is_a?(Hash)
|
21
|
+
|
22
|
+
case elem[:type]
|
23
|
+
when :file
|
24
|
+
valid_file?(elem)
|
25
|
+
when :symlink
|
26
|
+
valid_symlink?(elem)
|
27
|
+
when :directory
|
28
|
+
valid_directory?(elem)
|
29
|
+
else
|
30
|
+
false
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def valid_file?(element)
|
36
|
+
attributes = %i[type name ref content]
|
37
|
+
element.key?(:name) && element.each_key.all? do |key|
|
38
|
+
attributes.include?(key)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def valid_symlink?(element)
|
43
|
+
attributes = %i[type name to]
|
44
|
+
element.key?(:name) && element.key?(:to) && element.each_key.all? do |key|
|
45
|
+
attributes.include?(key)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def valid_directory?(element)
|
50
|
+
attributes = %i[type name ref children]
|
51
|
+
element.key?(:name) &&
|
52
|
+
element.key?(:children) &&
|
53
|
+
element.each_key { |key| attributes.include?(key) } &&
|
54
|
+
valid_structure?(element[:children])
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
require_relative 'file_structure/contract'
|
5
|
+
require_relative 'file_structure/validator'
|
6
|
+
require_relative 'file_structure/version'
|
7
|
+
|
8
|
+
# Manage files, directories and links described with a file structure
|
9
|
+
# definition as a Ruby Hash. A valid file structure definition is an Array
|
10
|
+
# of Hashes with the following possible file definitions:
|
11
|
+
#
|
12
|
+
# rubocop:disable Layout/LineLength
|
13
|
+
# @example
|
14
|
+
# { name: 'myfile', type: :file, content: 'abc', ref: 'fileref'} # :content and :ref are optional
|
15
|
+
# { name: 'mydir' type: :directory, children: [<another valid file structure definition>], ref: 'dirref' } # :ref is optional
|
16
|
+
# { name: 'mylink', type: :link, to: 'fileref' } # link to 'myfile' refereced earlier by 'fileref'
|
17
|
+
# rubocop:enable Layout/LineLength
|
18
|
+
class FileStructure
|
19
|
+
attr_reader :structure, :mountpoint
|
20
|
+
|
21
|
+
# @param structure [Array<Hash>] a valid file structure definition.
|
22
|
+
# @raise [AssertionError] if the file structure is invalid
|
23
|
+
def initialize(structure)
|
24
|
+
Contract.assert(valid_file_structure?(structure), 'invalid file structure')
|
25
|
+
|
26
|
+
@structure = structure
|
27
|
+
@mountpoint = nil
|
28
|
+
end
|
29
|
+
|
30
|
+
# Effectively creates files and directories in the specified directory.
|
31
|
+
#
|
32
|
+
# @param dirname [String] the target directory
|
33
|
+
# @raise [AssertionError] if the FileStructure is already mounted
|
34
|
+
# @return void
|
35
|
+
# @see unmount
|
36
|
+
def mount(dirname)
|
37
|
+
Contract.assert(!mounted?, 'file structure is already mounted')
|
38
|
+
|
39
|
+
mountpoint = File.absolute_path(dirname)
|
40
|
+
FileUtils.mkdir_p(mountpoint) unless Dir.exist?(mountpoint)
|
41
|
+
begin
|
42
|
+
create_file_structure(mountpoint, @structure)
|
43
|
+
rescue StandardErrror => e
|
44
|
+
FileUtils.rm_r(Dir.glob("#{mountpoint}/*")) # clear residuals
|
45
|
+
raise e
|
46
|
+
end
|
47
|
+
@mountpoint = mountpoint
|
48
|
+
end
|
49
|
+
|
50
|
+
# Remove all files from the mountpoint.
|
51
|
+
#
|
52
|
+
# @return void
|
53
|
+
# @see mount
|
54
|
+
def unmount
|
55
|
+
Contract.assert(mounted?, 'file structure is not mounted')
|
56
|
+
|
57
|
+
FileUtils.rm_r(Dir.glob("#{@mountpoint}/*"))
|
58
|
+
@mountpoint = nil
|
59
|
+
end
|
60
|
+
|
61
|
+
def mounted?
|
62
|
+
!!@mountpoint
|
63
|
+
end
|
64
|
+
|
65
|
+
# Get the full path for a file in the mounted file structure.
|
66
|
+
#
|
67
|
+
# @example
|
68
|
+
# path_for(:foo, :bar, :file)
|
69
|
+
# # => "/path/to/mountpoint/foo/bar/file"
|
70
|
+
#
|
71
|
+
# @param args [Symbol, String Array<Symbol, String>] the recursive names to
|
72
|
+
# the desired file or directory
|
73
|
+
# @return [String] the full path to the specified file/directory
|
74
|
+
# @raise [AssertionError] if the file structure is not mounted
|
75
|
+
def path_for(*args)
|
76
|
+
Contract.assert(mounted?, 'file structure is not mounted')
|
77
|
+
|
78
|
+
finder = [*args].flatten.map(&:to_sym)
|
79
|
+
build_path(finder, @structure)
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
def valid_file_structure?(structure)
|
85
|
+
FileStructure::Validator.new(structure).valid?
|
86
|
+
end
|
87
|
+
|
88
|
+
# @param finder [Array] such as :foo, :bar
|
89
|
+
# @param structure [Array] file structure definition
|
90
|
+
# @param path [String] starting path (recursive accumulator)
|
91
|
+
def build_path(finder, structure, path = @mountpoint)
|
92
|
+
return path if finder.empty? || structure.nil?
|
93
|
+
|
94
|
+
base = structure.find { |item| item[:name].to_s == finder.first.to_s }
|
95
|
+
return nil if base.nil?
|
96
|
+
|
97
|
+
build_path(
|
98
|
+
finder[1..],
|
99
|
+
base[:children],
|
100
|
+
File.join(path, base[:name])
|
101
|
+
)
|
102
|
+
end
|
103
|
+
|
104
|
+
# @param dirname [String] root directory
|
105
|
+
# @param structure [Array] file structure definition
|
106
|
+
# @param symlinks [Hash] current symlinks refs (recursive accumulator)
|
107
|
+
def create_file_structure(dirname, structure, symlinks = {})
|
108
|
+
structure.each do |element|
|
109
|
+
path = File.join(File.absolute_path(dirname), element[:name])
|
110
|
+
case element[:type]
|
111
|
+
when :file
|
112
|
+
File.write(path, element[:content])
|
113
|
+
symlinks.merge!(element[:ref] => path) if element[:ref]
|
114
|
+
when :symlink
|
115
|
+
FileUtils.symlink(symlinks[element[:to]], path)
|
116
|
+
when :directory
|
117
|
+
FileUtils.mkdir(path)
|
118
|
+
create_file_structure(path, element[:children], symlinks)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
metadata
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: file_structure
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Rémi Durieu
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-02-26 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: |2
|
14
|
+
Describe a file structure with a Ruby Hash. Supports files, file content,
|
15
|
+
directories and symlinks across the structure.
|
16
|
+
|
17
|
+
Mount and unmount the desired structured in a directory on the file system.
|
18
|
+
|
19
|
+
Useful for creating test environment for programs that manipulate
|
20
|
+
files but can be used as is for something else entirely.
|
21
|
+
email:
|
22
|
+
- mail@remidurieu.dev
|
23
|
+
executables: []
|
24
|
+
extensions: []
|
25
|
+
extra_rdoc_files: []
|
26
|
+
files:
|
27
|
+
- ".rubocop.yml"
|
28
|
+
- Gemfile
|
29
|
+
- Gemfile.lock
|
30
|
+
- LICENSE.txt
|
31
|
+
- README.md
|
32
|
+
- Rakefile
|
33
|
+
- file_structure.gemspec
|
34
|
+
- lib/file_structure.rb
|
35
|
+
- lib/file_structure/contract.rb
|
36
|
+
- lib/file_structure/validator.rb
|
37
|
+
- lib/file_structure/version.rb
|
38
|
+
homepage: https://github.com/durierem/file_structure
|
39
|
+
licenses:
|
40
|
+
- MIT
|
41
|
+
metadata:
|
42
|
+
homepage_uri: https://github.com/durierem/file_structure
|
43
|
+
source_code_uri: https://github.com/durierem/file_structure
|
44
|
+
rubygems_mfa_required: 'true'
|
45
|
+
post_install_message:
|
46
|
+
rdoc_options: []
|
47
|
+
require_paths:
|
48
|
+
- lib
|
49
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 2.6.0
|
54
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '0'
|
59
|
+
requirements: []
|
60
|
+
rubygems_version: 3.3.7
|
61
|
+
signing_key:
|
62
|
+
specification_version: 4
|
63
|
+
summary: 'Manage file structures (ie: files and directories) on the file system.'
|
64
|
+
test_files: []
|