lexicon-common 0.1.0 → 0.2.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: bb97bec1598709b8fefb46c28055ac8291edd138177995e08616de3b06dfbdb8
4
- data.tar.gz: 20db194da73907714cb53ae861bd650ded613f71ef99ae1c93db370c8547c830
3
+ metadata.gz: 67f0a5454bbfd0be7a918086e92beb80d00adfbc5ad5e018619dc28198a9be39
4
+ data.tar.gz: 63da11d671ced447b6c9f78acabdcdf0dbab6c620fc7f88b6e8e28ecd7ffeb36
5
5
  SHA512:
6
- metadata.gz: aa5b4f83c9647382dabdaa4dd09250fd4e165476ca3984740763bd4b2cd8f54ac41e73379a5988391a3336d31e9928ca9332598216b102829dff1efe28ab14dd
7
- data.tar.gz: 296628e759a78533b06160d653ab6e1299d0d1378964ac20d5350c7b83892d0b385b4d78f1569c1844591c014db2a0130f9249e423946e7d3e38095f28029f5a
6
+ metadata.gz: b7e1f34a8a91a980156eaabe9456d0c08ddbac1cc4c231f73905dace76c40d095cccd158f8406f9f28e51b7ebb70c6d98b4c27a1dca2b4eacaa75f916b41145c
7
+ data.tar.gz: 627de86d02381a2ec9ab550b4c384d7d084860c7c18ab7f0f9863cf928c5f6867e5e418183a06540bf75fca21dbd667c42e6cf97a9b4921e7300041f06f285ea
@@ -20,6 +20,8 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.add_dependency 'aws-sdk-s3', '~> 1.84'
22
22
  spec.add_dependency 'colored', '~> 1.2'
23
+ spec.add_dependency 'concurrent-ruby', '~> 1.1'
24
+ spec.add_dependency 'corindon', '~> 0.8.0'
23
25
  spec.add_dependency 'json_schemer', '~> 0.2.16'
24
26
  spec.add_dependency 'pg', '~> 1.2'
25
27
  spec.add_dependency 'semantic', '~> 1.6'
@@ -3,10 +3,13 @@
3
3
  # require 'lexicon/common'
4
4
  require 'aws-sdk-s3'
5
5
  require 'colored'
6
+ require 'concurrent-ruby'
7
+ require 'corindon'
6
8
  require 'logger'
7
9
  require 'json_schemer'
8
10
  require 'pg'
9
11
  require 'semantic'
12
+ require 'shellwords'
10
13
  require 'zeitwerk'
11
14
 
12
15
  # Require the common file as loading the version first through the gemspec prevents Zeitwerk to load it.
@@ -3,5 +3,6 @@
3
3
  module Lexicon
4
4
  module Common
5
5
  LEXICON_SCHEMA_RELATIVE_PATH = 'resources/lexicon.schema.json'
6
+ LEXICON_SCHEMA_ABSOLUTE_PATH = Pathname.new(__dir__).join('..', '..', LEXICON_SCHEMA_RELATIVE_PATH).freeze
6
7
  end
7
8
  end
@@ -16,8 +16,8 @@ module Lexicon
16
16
  def log_error(error)
17
17
  if error.nil?
18
18
  log('Error (nil)')
19
- else
20
- log([error.message, *error.backtrace].join("\n"))
19
+ elsif !logger.nil?
20
+ logger.error([error.message, *error.backtrace].join("\n"))
21
21
  end
22
22
  end
23
23
  end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ using Corindon::Guards::Ext
4
+
5
+ module Lexicon
6
+ module Common
7
+ module Mixin
8
+ module Nameable
9
+ # @return [String]
10
+ def name
11
+ unimplemented!
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -17,7 +17,7 @@ module Lexicon
17
17
  end
18
18
 
19
19
  # @param [String] name
20
- # @return [Package, nil]
20
+ # @return [Package::Package, nil]
21
21
  def load_package(name)
22
22
  package_dir = root_dir.join(name.to_s)
23
23
 
@@ -40,18 +40,17 @@ module Lexicon
40
40
  json = JSON.parse(spec_file.read)
41
41
 
42
42
  if @schema_validator.valid?(json)
43
- version = Semantic::Version.new(json.fetch('version'))
44
- file_sets = json.fetch('content').map do |id, values|
45
- SourceFileSet.new(
46
- id: id,
47
- name: values.fetch('name'),
48
- structure: values.fetch('structure'),
49
- data: values.fetch('data', nil),
50
- tables: values.fetch('tables', [])
51
- )
52
- end
43
+ package_version = json.fetch('schema_version', 1)
44
+ case package_version
45
+ when 1
46
+ load_v1(dir: dir, spec_file: spec_file, checksum_file: checksum_file, json: json)
47
+ when 2
48
+ load_v2(dir: dir, spec_file: spec_file, checksum_file: checksum_file, json: json)
49
+ else
50
+ log("Package version #{package_version} is not supported")
53
51
 
54
- Package.new(file_sets: file_sets, version: version, dir: dir, checksum_file: checksum_file, spec_file: spec_file)
52
+ nil
53
+ end
55
54
  else
56
55
  log("Package at path #{dir} has invalid manifest")
57
56
 
@@ -61,6 +60,51 @@ module Lexicon
61
60
  nil
62
61
  end
63
62
  end
63
+
64
+ # @param [Pathname] checksum_file
65
+ # @param [Pathname] dir
66
+ # @param [Hash] json
67
+ # @param [Pathname] spec_file
68
+ # @return [V1::Package]
69
+ def load_v1(dir:, spec_file:, checksum_file:, json:)
70
+ version = Semantic::Version.new(json.fetch('version'))
71
+ file_sets = json.fetch('content').map do |id, values|
72
+ V1::SourceFileSet.new(
73
+ id: id,
74
+ name: values.fetch('name'),
75
+ structure: values.fetch('structure'),
76
+ data: values.fetch('data', nil),
77
+ tables: values.fetch('tables', [])
78
+ )
79
+ end
80
+
81
+ V1::Package.new(file_sets: file_sets, version: version, dir: dir, checksum_file: checksum_file, spec_file: spec_file)
82
+ end
83
+
84
+ # @param [Pathname] checksum_file
85
+ # @param [Pathname] dir
86
+ # @param [Hash] json
87
+ # @param [Pathname] spec_file
88
+ # @return [V2::Package]
89
+ def load_v2(dir:, spec_file:, checksum_file:, json:)
90
+ version = Semantic::Version.new(json.fetch('version'))
91
+ file_sets = json.fetch('content').map do |id, values|
92
+ V2::SourceFileSet.new(
93
+ id: id,
94
+ name: values.fetch('name'),
95
+ structure: values.fetch('structure'),
96
+ tables: values.fetch('tables', {})
97
+ )
98
+ end
99
+
100
+ V2::Package.new(
101
+ file_sets: file_sets,
102
+ version: version,
103
+ dir: dir,
104
+ checksum_file: checksum_file,
105
+ spec_file: spec_file
106
+ )
107
+ end
64
108
  end
65
109
  end
66
110
  end
@@ -11,65 +11,33 @@ module Lexicon
11
11
  attr_reader :checksum_file, :spec_file
12
12
  # @return [Pathname]
13
13
  attr_reader :dir
14
- # @return [Array<SourceFileSet>]
15
- attr_reader :file_sets
16
14
  # @return [Semantic::Version]
17
15
  attr_reader :version
16
+ # @return [Integer]
17
+ attr_reader :schema_version
18
18
 
19
- # @param [Array<SourceFileSet>] file_sets
20
- # @param [Pathname] dir
21
19
  # @param [Pathname] checksum_file
20
+ # @param [Pathname] dir
21
+ # @param [Integer] schema_version
22
+ # @param [Pathname] spec_file
22
23
  # @param [Semantic::Version] version
23
- def initialize(file_sets:, version:, dir:, checksum_file:, spec_file:)
24
+ def initialize(checksum_file:, dir:, schema_version:, spec_file:, version:)
24
25
  @checksum_file = checksum_file
25
26
  @dir = dir
26
- @file_sets = file_sets
27
+ @schema_version = schema_version
27
28
  @spec_file = spec_file
28
29
  @version = version
29
30
  end
30
31
 
31
32
  # @return [Boolean]
32
33
  def valid?
33
- checksum_file.exist? && dir.directory? && data_dir.directory? && all_sets_valid?
34
- end
35
-
36
- # @return [Array<Pathname>]
37
- def structure_files
38
- file_sets.map { |fs| dir.join(relative_structure_path(fs)) }
34
+ checksum_file.exist? && dir.directory? && files.all? { |f| f.path.exist? rescue false }
39
35
  end
40
36
 
41
- # @param [SourceFileSet] file_set
42
- # @return [Pathname]
43
- def data_path(file_set)
44
- dir.join(relative_data_path(file_set))
45
- end
46
-
47
- # @return [Pathname]
48
- def data_dir
49
- dir.join('data')
37
+ # @return [Array<PackageFile>] Array of File of the package
38
+ def files
39
+ []
50
40
  end
51
-
52
- # @return [Pathname, nil]
53
- def relative_data_path(file_set)
54
- if file_set.data_path.nil?
55
- nil
56
- else
57
- data_dir.basename.join(file_set.data_path)
58
- end
59
- end
60
-
61
- # @return [Pathname]
62
- def relative_structure_path(file_set)
63
- data_dir.basename.join(file_set.structure_path)
64
- end
65
-
66
- private
67
-
68
- def all_sets_valid?
69
- file_sets.all? do |set|
70
- data_dir.join(set.structure_path).exist? && !set.data_path.nil? && data_dir.join(set.data_path).exist?
71
- end
72
- end
73
41
  end
74
42
  end
75
43
  end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lexicon
4
+ module Common
5
+ module Package
6
+ class PackageFile
7
+ class << self
8
+ def new_structure(path)
9
+ new(path, type: STRUCTURE)
10
+ end
11
+
12
+ def new_data(path)
13
+ new(path, type: DATA)
14
+ end
15
+ end
16
+
17
+ # @return [Pathname]
18
+ attr_reader :path
19
+
20
+ # @return [String]
21
+ def to_s
22
+ path.to_s
23
+ end
24
+
25
+ # @return [Boolean]
26
+ def data?
27
+ type == DATA
28
+ end
29
+
30
+ # @return [Boolean]
31
+ def structure?
32
+ type == STRUCTURE
33
+ end
34
+
35
+ private
36
+
37
+ attr_reader :type
38
+
39
+ DATA = 'data'
40
+ STRUCTURE = 'structure'
41
+
42
+ def initialize(path, type:)
43
+ @path = path
44
+ @type = type
45
+ end
46
+
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lexicon
4
+ module Common
5
+ module Package
6
+ module V1
7
+ class Package < Common::Package::Package
8
+ # @return [Array<SourceFileSet>]
9
+ attr_reader :file_sets
10
+
11
+ # @param [Array<SourceFileSet>] file_sets
12
+ # @param [Pathname] dir
13
+ # @param [Pathname] checksum_file
14
+ # @param [Semantic::Version] version
15
+ def initialize(version:, spec_file:, checksum_file:, dir:, file_sets:)
16
+ super(
17
+ checksum_file: checksum_file,
18
+ dir: dir,
19
+ spec_file: spec_file,
20
+ schema_version: 1,
21
+ version: version,
22
+ )
23
+
24
+ @file_sets = file_sets
25
+ end
26
+
27
+ # @return [Boolean]
28
+ def valid?
29
+ super && data_dir.directory? && all_sets_valid?
30
+ end
31
+
32
+ def files
33
+ structures = file_sets.map { |fs| PackageFile.new_structure(relative_structure_path(fs)) }
34
+ data = file_sets.flat_map do |fs|
35
+ data_path = relative_data_path(fs)
36
+
37
+ if data_path.nil?
38
+ []
39
+ else
40
+ [PackageFile.new_data(data_path)]
41
+ end
42
+ end
43
+
44
+ [*structures, *data]
45
+ end
46
+
47
+ # @param [SourceFileSet] file_set
48
+ # @return [Pathname]
49
+ def data_path(file_set)
50
+ dir.join(relative_data_path(file_set))
51
+ end
52
+
53
+ # @return [Pathname]
54
+ def data_dir
55
+ dir.join('data')
56
+ end
57
+
58
+ # @return [Pathname, nil]
59
+ def relative_data_path(file_set)
60
+ if file_set.data_path.nil?
61
+ nil
62
+ else
63
+ data_dir.basename.join(file_set.data_path)
64
+ end
65
+ end
66
+
67
+ # @return [Pathname]
68
+ def relative_structure_path(file_set)
69
+ data_dir.basename.join(file_set.structure_path)
70
+ end
71
+
72
+ private
73
+
74
+ def all_sets_valid?
75
+ file_sets.all? do |set|
76
+ data_dir.join(set.structure_path).exist? && !set.data_path.nil? && data_dir.join(set.data_path).exist?
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lexicon
4
+ module Common
5
+ module Package
6
+ module V1
7
+ class PackageBuilder < Package
8
+ def initialize(version:, dir:)
9
+ super(
10
+ file_sets: [],
11
+ version: version,
12
+ dir: dir,
13
+ checksum_file: dir.join(CHECKSUM_FILE_NAME),
14
+ spec_file: dir.join(SPEC_FILE_NAME)
15
+ )
16
+
17
+ FileUtils.mkdir_p(data_dir)
18
+ end
19
+
20
+ # @param [String] id
21
+ # @param [String] name
22
+ # @param [Pathname] structure
23
+ # Takes ownership of the file (moves it to the correct folder)
24
+ # @param [Array<String>] tables
25
+ # @param [Pathname] data
26
+ # Takes ownership of the file (moves it to the correct folder)
27
+ # @param [String] data_ext
28
+ def add_file_set(id, name:, structure:, tables:, data: nil, data_ext: '.sql')
29
+ # @type [Pathname] structure_file_path
30
+ structure_file_path = data_dir.join(structure_file_name(id))
31
+ FileUtils.mv(structure.to_s, structure_file_path.to_s)
32
+
33
+ # @type [Pathname] data_file_path
34
+ data_name = if data.nil?
35
+ nil
36
+ else
37
+ dname = data_file_name(id, data_ext)
38
+ path = data_dir.join(dname)
39
+ FileUtils.mv(data, path)
40
+
41
+ dname
42
+ end
43
+
44
+ file_sets << SourceFileSet.new(
45
+ id: id,
46
+ name: name,
47
+ structure: structure_file_name(id),
48
+ data: data.nil? ? nil : data_name,
49
+ tables: tables
50
+ )
51
+ end
52
+
53
+ def as_package
54
+ Package.new(version: version, dir: dir, file_sets: file_sets, checksum_file: checksum_file, spec_file: spec_file)
55
+ end
56
+
57
+ private
58
+
59
+ def data_file_name(id, ext)
60
+ "#{id}#{ext}"
61
+ end
62
+
63
+ def structure_file_name(id)
64
+ "#{id}__structure.sql"
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end