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 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