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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dae1876a15464dfd56776c428808812ccf15c3b8c8a3b95e75c2fe5da9d6421e
4
- data.tar.gz: 4e2d794364f2c8c9ea6179f7b8f4807394e9c0757c1ea8d4c443dc9b508c8730
3
+ metadata.gz: 92b6133564fb1000278be3e8551eb8ce5b04ed9001de9ea61ce30e66141c4ea8
4
+ data.tar.gz: 17558a2b2874346b2b36a2ee308c4fdef02ac5fa0797389ede81129191cd0ecd
5
5
  SHA512:
6
- metadata.gz: bd568fb6108962e88a0fa6f2300ed642e76f837d896f4d099f2250235e8f435f43168632d8b934be497090ef9c1ee2d2b3d9478b6fa49744c256aa6fefef7dfb
7
- data.tar.gz: 78822356b462ca915d8f57b2e080781d8a0b6ade7811b2701857a35a6628076acf08e36a21754e525e9c6e70a96363ff895d428dc3c99ce79df836e2ea46a6a7
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
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- file_structure (0.2.0)
4
+ file_structure (0.3.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
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 reacreated on the
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 -> /tmp/mydir/dir1/dir2/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
- fs.mount('/home/john/mydir') # also creates the directory if it doesn't exist
65
- fs.mounted? # => true
66
- fs.mountpoint # => "/home/john/mydir"
67
- fs.path_for(:dir1, :file3) # => /home/john/mydir/dir1/file3
68
- fs.unmount # deletes all files in /home/john/mydir
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
- # Bonus tip 1: can be mounted in a temporary directory
75
+ ```ruby
76
+ # Can be mounted in a temporary directory
71
77
  Dir.mktmpdir do |dirname|
72
- fs.mount(dir)
78
+ fs.mount(dirname)
73
79
  # do stuff
74
80
  fs.unmount
75
81
  end
76
82
 
77
- # Bonus tip 2: easily serializable structure (who knows what could be done with this :O)
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).
@@ -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 [Hash] the resulting file structure definition
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.
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class FileStructure
4
- VERSION = '0.2.0'
4
+ VERSION = '0.3.0'
5
5
  end
@@ -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 FileStructure is already mounted
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
- begin
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 full path for a file in the mounted file structure.
80
+ # Get the absolute path for a file in the mounted file structure.
78
81
  #
79
82
  # @example
80
- # path_for(:foo, :bar, :file)
83
+ # path_for('foo/bar/file')
81
84
  # # => "/path/to/mountpoint/foo/bar/file"
82
85
  #
83
- # @param args [Symbol, String Array<Symbol, String>] the recursive names to
84
- # the desired file or directory
85
- # @return [String] the full path to the specified file/directory if found
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(*args)
90
+ def path_for(target)
89
91
  assert(mounted?, 'file structure is not mounted')
90
92
 
91
- finder = [*args].flatten.map(&:to_sym)
92
- build_path(finder, @structure)
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.2.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-03-05 00:00:00.000000000 Z
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