file_structure 0.2.0 → 0.3.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 +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
|
+
[](https://github.com/durierem/file_structure/blob/main/LICENSE.txt)
|
3
4
|
[](https://badge.fury.io/rb/file_structure)
|
4
5
|
[](https://github.com/durierem/file_structure/actions/workflows/test.yml)
|
5
6
|
[](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
|