file_structure 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +32 -0
- data/Gemfile.lock +1 -1
- data/README.md +22 -12
- data/lib/file_structure/dsl.rb +1 -3
- data/lib/file_structure/version.rb +1 -1
- data/lib/file_structure.rb +19 -33
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 92b6133564fb1000278be3e8551eb8ce5b04ed9001de9ea61ce30e66141c4ea8
|
4
|
+
data.tar.gz: 17558a2b2874346b2b36a2ee308c4fdef02ac5fa0797389ede81129191cd0ecd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9e10b2ac0de13bff81acc8b7f7d7fb3d90b71dc0a524d59ede4c23b9e5f08faa09326d3d0ef8ba6443ef03b4338c973fd0f879d6d312735ddb99c8d3b8b5e2ab
|
7
|
+
data.tar.gz: b01504789e95ddf2d13a96a79e73395c05527b7e65a6d3b60733d0a616cd142ae5acaa3be2af19831d28102232ed852f66529b40523bd32277285b4c29627e6d
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
All notable changes to this project will be documented in this file.
|
4
|
+
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
|
+
|
8
|
+
# Unreleased
|
9
|
+
(nothing yet!)
|
10
|
+
|
11
|
+
## [0.3.0] - 2022-09-09
|
12
|
+
### Changed
|
13
|
+
- `FileStructure#path_for` is more efficient and the API is simpler, expecting
|
14
|
+
the argument to be a relative path instead of a list of recursive names.
|
15
|
+
- `FileStructure#mount` does not handle cleaning "residuals" anymore and
|
16
|
+
requires the target directory to be empty upon mounting.
|
17
|
+
|
18
|
+
## [0.2.0] - 2022-03-05
|
19
|
+
### Added
|
20
|
+
- New DSL to more easily describe file structure (`FileStructure::DSL`).
|
21
|
+
- New method `FileStructure.build` to use the DSL.
|
22
|
+
### Fixed
|
23
|
+
- Incorrect error handling preventing cleaning of residual files when `FileStructure#mount` fails.
|
24
|
+
|
25
|
+
## [0.1.0] - 2022-02-26
|
26
|
+
### Added
|
27
|
+
- Initial working set of functionalities.
|
28
|
+
|
29
|
+
[Unreleased]: https://github.com/durierem/file_structure/compare/v0.3.0...HEAD
|
30
|
+
[0.3.0]: https://github.com/durierem/file_structure/compare/v0.2.0...v0.3.0
|
31
|
+
[0.2.0]: https://github.com/durierem/file_structure/compare/v0.1.0...v0.2.0
|
32
|
+
[0.1.0]: https://github.com/durierem/file_structure/releases/tag/v0.1.0
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# file_structure
|
2
2
|
|
3
|
+
[![MIT License](https://img.shields.io/github/license/durierem/file_structure)](https://github.com/durierem/file_structure/blob/main/LICENSE.txt)
|
3
4
|
[![Gem Version](https://badge.fury.io/rb/file_structure.svg)](https://badge.fury.io/rb/file_structure)
|
4
5
|
[![Test](https://github.com/durierem/file_structure/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/durierem/file_structure/actions/workflows/test.yml)
|
5
6
|
[![Lint](https://github.com/durierem/file_structure/actions/workflows/lint.yml/badge.svg?branch=main)](https://github.com/durierem/file_structure/actions/workflows/lint.yml)
|
@@ -10,7 +11,7 @@ Describe a file hierarchy and mount it in a directory on the file system.
|
|
10
11
|
## About
|
11
12
|
|
12
13
|
This gem was extracted from another project tests for which structures
|
13
|
-
containing files, directories and symlinks had to be easily
|
14
|
+
containing files, directories and symlinks had to be easily recreated on the
|
14
15
|
fly.
|
15
16
|
|
16
17
|
Though it *is* useful in the context of testing, `file_structure` does not make
|
@@ -44,9 +45,9 @@ for more details.
|
|
44
45
|
# /home/john/mydir
|
45
46
|
# ├── dir1
|
46
47
|
# │ ├── dir2
|
47
|
-
# │ │ └── file2
|
48
|
+
# │ │ └── file2 (containing "Hello, World!")
|
48
49
|
# │ ├── file3
|
49
|
-
# │ └── link_to_file2 -> /
|
50
|
+
# │ └── link_to_file2 -> /home/john/mydir/dir1/dir2/file2
|
50
51
|
# └── file1
|
51
52
|
|
52
53
|
# Use the DSL to easily describe the structure
|
@@ -54,30 +55,39 @@ fs = FileStructure.build do
|
|
54
55
|
file 'file1'
|
55
56
|
directory 'dir1' do
|
56
57
|
directory 'dir2' do
|
57
|
-
file 'file2'
|
58
|
+
file 'file2', content: 'Hello, World!'
|
58
59
|
end
|
59
60
|
file 'file3'
|
60
61
|
symlink 'link_to_file2', to: 'file2'
|
61
62
|
end
|
62
63
|
end
|
63
64
|
|
64
|
-
|
65
|
-
fs.
|
66
|
-
fs.
|
67
|
-
fs.
|
68
|
-
fs.
|
65
|
+
# Operations on file structures
|
66
|
+
fs.mount('/home/john/mydir') # also creates the directory if it doesn't exist
|
67
|
+
fs.mounted? # => true
|
68
|
+
fs.mountpoint # => "/home/john/mydir"
|
69
|
+
fs.path_for('dir1/file3') # => "/home/john/mydir/dir1/file3"
|
70
|
+
fs.unmount # deletes all files in /home/john/mydir
|
71
|
+
```
|
72
|
+
|
73
|
+
## Bonus
|
69
74
|
|
70
|
-
|
75
|
+
```ruby
|
76
|
+
# Can be mounted in a temporary directory
|
71
77
|
Dir.mktmpdir do |dirname|
|
72
|
-
fs.mount(
|
78
|
+
fs.mount(dirname)
|
73
79
|
# do stuff
|
74
80
|
fs.unmount
|
75
81
|
end
|
76
82
|
|
77
|
-
#
|
83
|
+
# Easily serializable structure (who knows what could be done with this :O)
|
78
84
|
JSON.dump(fs.structure)
|
79
85
|
```
|
80
86
|
|
87
|
+
## Changelog
|
88
|
+
|
89
|
+
See [CHANGELOG.md](https://github.com/durierem/file_structure/blob/main/CHANGELOG.md).
|
90
|
+
|
81
91
|
## License
|
82
92
|
|
83
93
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/lib/file_structure/dsl.rb
CHANGED
@@ -3,8 +3,6 @@
|
|
3
3
|
class FileStructure
|
4
4
|
# Provide a DSL to easily create file structure definitions.
|
5
5
|
#
|
6
|
-
#
|
7
|
-
#
|
8
6
|
# @example
|
9
7
|
# structure = FileStructure::DSL.eval do
|
10
8
|
# directory 'dir_a' do
|
@@ -18,7 +16,7 @@ class FileStructure
|
|
18
16
|
# end
|
19
17
|
# # => [{ type: :directory, name: 'dir_a', children: [ ... ] }]
|
20
18
|
class DSL
|
21
|
-
# @return [
|
19
|
+
# @return [Array] the resulting file structure definition
|
22
20
|
attr_reader :structure
|
23
21
|
|
24
22
|
# Return the file structure definition builded with the given block.
|
data/lib/file_structure.rb
CHANGED
@@ -30,7 +30,7 @@ class FileStructure
|
|
30
30
|
new(FileStructure::DSL.eval(&block))
|
31
31
|
end
|
32
32
|
|
33
|
-
# @param structure [Array<Hash>] a valid file structure definition
|
33
|
+
# @param structure [Array<Hash>] a valid file structure definition (see {DSL})
|
34
34
|
# @raise [AssertionError] if the file structure is invalid
|
35
35
|
def initialize(structure)
|
36
36
|
assert(valid_file_structure?(structure), 'invalid file structure')
|
@@ -42,26 +42,26 @@ class FileStructure
|
|
42
42
|
# Effectively creates files and directories in the specified directory.
|
43
43
|
#
|
44
44
|
# @param dirname [String] the target directory
|
45
|
-
# @raise [AssertionError] if the
|
45
|
+
# @raise [AssertionError] if the file structure is already mounted
|
46
|
+
# @raise [AssertionError] if the target directory is not empty
|
46
47
|
# @return void
|
47
48
|
# @see unmount
|
48
49
|
def mount(dirname)
|
49
50
|
assert(!mounted?, 'file structure is already mounted')
|
51
|
+
if Dir.exist?(dirname)
|
52
|
+
assert(Dir.empty?(dirname), 'target directory is not empty')
|
53
|
+
end
|
50
54
|
|
51
55
|
mountpoint = File.absolute_path(dirname)
|
52
56
|
FileUtils.mkdir_p(mountpoint) unless Dir.exist?(mountpoint)
|
53
|
-
|
54
|
-
create_file_structure(mountpoint, @structure)
|
55
|
-
rescue StandardError => e
|
56
|
-
FileUtils.rm_r(Dir.glob("#{mountpoint}/*")) # clear residuals
|
57
|
-
raise e
|
58
|
-
end
|
57
|
+
create_file_structure(mountpoint, @structure)
|
59
58
|
@mountpoint = mountpoint
|
60
59
|
end
|
61
60
|
|
62
61
|
# Remove all files from the mountpoint.
|
63
62
|
#
|
64
63
|
# @return void
|
64
|
+
# @raise [AssertionError] if the file structure is not mounted
|
65
65
|
# @see mount
|
66
66
|
def unmount
|
67
67
|
assert(mounted?, 'file structure is not mounted')
|
@@ -70,26 +70,28 @@ class FileStructure
|
|
70
70
|
@mountpoint = nil
|
71
71
|
end
|
72
72
|
|
73
|
+
# Check if the file structure is currently mounted.
|
74
|
+
#
|
75
|
+
# @return [Boolean]
|
73
76
|
def mounted?
|
74
77
|
!!@mountpoint
|
75
78
|
end
|
76
79
|
|
77
|
-
# Get the
|
80
|
+
# Get the absolute path for a file in the mounted file structure.
|
78
81
|
#
|
79
82
|
# @example
|
80
|
-
# path_for(
|
83
|
+
# path_for('foo/bar/file')
|
81
84
|
# # => "/path/to/mountpoint/foo/bar/file"
|
82
85
|
#
|
83
|
-
# @param
|
84
|
-
#
|
85
|
-
# @return [
|
86
|
-
# @return [nil] if no file/directory has been found
|
86
|
+
# @param target [String] the relative path of the target in the file structure
|
87
|
+
# @return [String] the full path to the target
|
88
|
+
# @return [nil] if no target has been found
|
87
89
|
# @raise [AssertionError] if the file structure is not mounted
|
88
|
-
def path_for(
|
90
|
+
def path_for(target)
|
89
91
|
assert(mounted?, 'file structure is not mounted')
|
90
92
|
|
91
|
-
|
92
|
-
|
93
|
+
absolute_path = File.join(@mountpoint, target)
|
94
|
+
File.exist?(absolute_path) ? absolute_path : nil
|
93
95
|
end
|
94
96
|
|
95
97
|
private
|
@@ -98,22 +100,6 @@ class FileStructure
|
|
98
100
|
FileStructure::Validator.new(structure).valid?
|
99
101
|
end
|
100
102
|
|
101
|
-
# @param finder [Array] such as :foo, :bar
|
102
|
-
# @param structure [Array] file structure definition
|
103
|
-
# @param path [String] starting path (recursive accumulator)
|
104
|
-
def build_path(finder, structure, path = @mountpoint)
|
105
|
-
return path if finder.empty? || structure.nil?
|
106
|
-
|
107
|
-
base = structure.find { |item| item[:name].to_s == finder.first.to_s }
|
108
|
-
return nil if base.nil?
|
109
|
-
|
110
|
-
build_path(
|
111
|
-
finder[1..],
|
112
|
-
base[:children],
|
113
|
-
File.join(path, base[:name])
|
114
|
-
)
|
115
|
-
end
|
116
|
-
|
117
103
|
# @param dirname [String] root directory
|
118
104
|
# @param structure [Array] file structure definition
|
119
105
|
# @param symlinks [Hash<ref, path>] symlinks map (don't use directly)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: file_structure
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rémi Durieu
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-09-09 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Describe a file hierarchy and mount it in a directory on the file system.
|
14
14
|
email:
|
@@ -19,6 +19,7 @@ extra_rdoc_files: []
|
|
19
19
|
files:
|
20
20
|
- ".rubocop.yml"
|
21
21
|
- ".yardopts"
|
22
|
+
- CHANGELOG.md
|
22
23
|
- Gemfile
|
23
24
|
- Gemfile.lock
|
24
25
|
- LICENSE.txt
|