apstrings 0.3.6 → 0.3.7

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
  SHA1:
3
- metadata.gz: 0b3af4ecc14954ccb8d078fb52ae98475c7722a1
4
- data.tar.gz: 312bc33483fdc872f0ecdc8e0fdcb669557549c0
3
+ metadata.gz: 214c6ebcd43ed72910ca02d269eceb66a9638407
4
+ data.tar.gz: 2def09e490405096cbb85edbe0ba3d61b8e9ca53
5
5
  SHA512:
6
- metadata.gz: 4aa46cc5d37810c4415687400f4cc344d95b359d5614f330fb2befea07a9db4c77688d5e18d81aa2397cdec42f8be73e8db9acaff462001ea5ae0b1a2411f8a6
7
- data.tar.gz: 8023ddeffd9cd371b6bfc6cd3c3478ff23f526bc0d3443583e65bd7e25c3e4e5c85e47884ba9d5feddd487eb916273c803c98fd5b7bd6a25f4ac4b578a71d584
6
+ metadata.gz: 74c27433007ed1dfaa1486b58a8a1b2cc0f0300d52538ea5ecef08aff5de2c5f9f408d2e320fa480fb1dd207354e733191268cfdf75471ae99dcae7edb1738bb
7
+ data.tar.gz: 18643aff518885079e3ed02b2165a6bbeb5711b65e147bd66b1b50fc25db28581e2a71ade167b3794bcaa5a823b84f2a9e2e0dc22bbc1502af2f1897be27d39c
Binary file
data/bin/apstrings CHANGED
@@ -1,6 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
-
3
- require "bundler/setup"
4
2
  require "apstrings"
5
3
 
6
4
  # You can add fixtures and/or initialization code here to make experimenting
@@ -12,8 +10,10 @@ require "apstrings"
12
10
 
13
11
 
14
12
  $ROOT = ARGV[0]
15
-
13
+ $VALID = true
14
+ $SUMMARYS = []
16
15
  Dir::chdir($ROOT)
16
+ Apstrings::log_info("\n----------------\n Entering #{$ROOT}...")
17
17
  files_to_validate = {"master"=> nil,"files" => []}
18
18
  Dir.glob(File.join("**", "*.strings")) { |file|
19
19
  p File.basename(file)
@@ -28,20 +28,22 @@ success = true
28
28
  any_file = false
29
29
  files_to_validate["files"].each { |file|
30
30
  any_file = true
31
- if !Apstrings::validate(file,files_to_validate["master"])
31
+ $VALID,summary = Apstrings::validate(file,files_to_validate["master"])
32
+ $SUMMARYS << summary
33
+ if !$VALID
32
34
  success = false
33
35
  end
34
36
  }
35
37
 
36
38
  if success && any_file
37
- Apstrings::log_info("Well done! 🍻 🍻\n")
39
+ Apstrings::log_info("Validate passed. Well done! 🍻 🍻 \n ----------------")
38
40
  exit(0)
39
41
  else if !any_file
40
- Apstrings::log_info("Nothing to validate.")
41
- exit(0)
42
- else
43
- Apstrings::log_error("Validate failed, See above for details\n")
44
- exit(1)
45
- end
42
+ Apstrings::log_info("Nothing to validate. \n ----------------")
43
+ exit(0)
44
+ else
45
+ Apstrings::log_error("Validate failed, See above for details.\n ----------------")
46
+ exit(1)
47
+ end
46
48
  end
47
49
 
@@ -2,9 +2,10 @@ module Apstrings
2
2
  require 'json'
3
3
  class DotStringFile
4
4
  attr_accessor :kv_pairs
5
-
6
- def initialize
5
+ attr_accessor :raw_file
6
+ def initialize(raw_file='')
7
7
  @kv_pairs = []
8
+ @raw_file = raw_file
8
9
  end
9
10
 
10
11
  def key_values
@@ -8,11 +8,12 @@ module Apstrings
8
8
  end
9
9
 
10
10
  def key
11
- line.key.strip unless line.key.nil?
11
+ line.key unless line.key.nil?
12
12
  end
13
13
 
14
14
  def value
15
- line.value.strip unless line.key.nil?
15
+ # puts line
16
+ line.value unless line.key.nil?
16
17
  end
17
18
 
18
19
  def comment
@@ -6,13 +6,17 @@ module Apstrings
6
6
  def initialize(line)
7
7
  @content = line
8
8
  @in_comment = false
9
- raise "ERROR : Line does not end with `;`, #{line}" unless valid?
9
+ raise "ERROR : Line does not end with `;`, Line => {#{line}}" unless valid?
10
10
  end
11
11
 
12
12
  def empty_line?
13
13
  /^\s*$/.match(content) || false
14
14
  end
15
15
 
16
+ def slash_comment?
17
+ content.strip.start_with?("//")
18
+ end
19
+
16
20
  def whole_comment
17
21
  /((^\/\*(.+)\*\/)|(^\/\/(.+)))/.match(content).to_s
18
22
  end
@@ -61,12 +65,15 @@ module Apstrings
61
65
 
62
66
  def value
63
67
  if key_value_pair?
64
- cleaned_content.partition(/"\s*=\s*"/)[2].gsub!(/(^"|"$)/, "")
68
+ # puts cleaned_content.partition(/"\s*=\s*"/)[2]
69
+ # Bugfix : 去掉引号后、冒号前的多余空格
70
+ # "key" = "value" ;
71
+ cleaned_content.partition(/"\s*=\s*"/)[2].rstrip.gsub!(/(^"|"$)/, "")
65
72
  end
66
73
  end
67
74
 
68
75
  def is_comment?
69
- whole_comment? || open_comment? || close_comment? || in_comment
76
+ whole_comment? || open_comment? || close_comment? || in_comment || slash_comment?
70
77
  end
71
78
  end
72
79
  end
@@ -16,8 +16,9 @@ module Apstrings
16
16
  current_comment = nil
17
17
  comments_for_keys = {}
18
18
  @read_file.each do |content_line|
19
+
19
20
  current_line = Line.new(content_line)
20
- next if current_line.empty_line? && current_line.in_comment == false
21
+ next if (current_line.empty_line? && current_line.in_comment == false) || !content_line.strip.start_with?("\"")
21
22
 
22
23
  #State machine
23
24
  case state
@@ -3,13 +3,59 @@ module Apstrings
3
3
  require 'apstrings/strings_parser'
4
4
  require 'apstrings/logger'
5
5
 
6
+ class ValidateResult
7
+
8
+ attr_accessor :master_special_character_error
9
+ attr_accessor :file_special_character_errors
10
+ attr_accessor :missing_keys
11
+ attr_accessor :dup_keys
12
+ attr_accessor :file_format_errors
13
+ attr_accessor :valid_file_format
14
+
15
+
16
+ def initialize(file,masterFile,
17
+ file_special_character_errors=[],
18
+ master_special_character_error=[],
19
+ missing_keys=[],
20
+ dup_keys=[],file_format_errors=[],
21
+ valid_file_format=true)
22
+
23
+ @file = file
24
+ @masterFile = masterFile
25
+ @file_special_character_errors = file_special_character_errors
26
+ @master_special_character_error = master_special_character_error
27
+ @missing_keys = missing_keys
28
+ @dup_keys = dup_keys
29
+ @file_format_errors = file_format_errors
30
+ @valid_file_format = valid_file_format
31
+ end
32
+
33
+ def to_hash
34
+ { :file=> File.basename(@file),
35
+ :masterFile => File.basename(@masterFile),
36
+ :master_special_character_error => @master_special_character_error,
37
+ :file_special_character_errors => @file_special_character_errors ,
38
+ :missing_keys => @missing_keys ,
39
+ :dup_keys => @dup_keys,
40
+ :file_format_errors => @file_format_errors,
41
+ :valid_file_format => @valid_file_format
42
+ }
43
+ end
44
+ end
45
+
46
+
6
47
  class Validator
7
48
 
49
+ class << self; attr_accessor :result end
50
+
51
+
8
52
  def self.validate(file,masterFile)
53
+ @result = ValidateResult.new(file,masterFile);
54
+ @file = file
9
55
  @master = nil
10
- puts "\n-----------------------------------------"
11
- puts "apstrings: start validate strings file : #{file} ..."
12
- puts "-----------------------------------------"
56
+ puts "-----------------------------------------\n\n"
57
+ puts "-----------------------------------------"
58
+ puts "apstrings: start validate strings file : #{@file} ..."
13
59
  if nil == masterFile
14
60
  Log::warn("No master file provided, validating file format only ...")
15
61
  else
@@ -18,41 +64,57 @@ module Apstrings
18
64
 
19
65
  valid_master, valid_file , no_missing_key = true,true,true
20
66
 
21
- valid_file = Validator::validate_format(file)
67
+ begin
68
+ @string_file = Validator::paredFile(file);
69
+ rescue Exception => e
70
+ Log::error(e)
71
+ @result.valid_file_format = false
72
+ @result.file_format_errors << e
73
+ return false,@result.to_hash
74
+ end
75
+
76
+ valid_file = Validator::validate_format(@string_file)
22
77
  if masterFile != nil
23
- valid_master = Validator::validate_format(masterFile)
24
- no_missing_key = Validator::validate_missing(file,masterFile)
78
+ valid_master = Validator::validate_format(@master)
79
+ no_missing_key = Validator::validate_missing(@string_file,@master)
25
80
  end
26
81
 
27
82
  if valid_master && valid_file && no_missing_key
28
83
  # Log::info("Yeah! 🍻 🍻 ")
29
- return true
84
+ return true,@result.to_hash
30
85
  else if valid_master && valid_file && !no_missing_key
31
86
  # Log::warn("Missing keys found.")
32
- return true
87
+ return true,@result.to_hash
33
88
  else
34
89
  # Log::error("Invalid file.")
35
- return false
90
+ return false,@result.to_hash
36
91
  end
37
92
  end
38
93
  end
39
94
 
40
- def self.validate_format(file)
95
+ def self.validate_format(sf)
41
96
  is_valid = true
42
97
  # puts "apstrings: start validate format for #{file} ..."
43
- dup_keys_in_file = Validator::validate_duplicates(file)
44
- mismatchs_in_file = Validator::validate_special_characters(file)
98
+ dup_keys_in_file = Validator::validate_duplicates(sf)
99
+ mismatchs_in_file = Validator::validate_special_characters(sf)
100
+ @result.dup_keys = dup_keys_in_file
101
+ if sf == @master
102
+ @result.master_special_character_error = @result.master_special_character_error + mismatchs_in_file
103
+ else
104
+ @result.file_special_character_errors = @result.file_special_character_errors + mismatchs_in_file
105
+ end
45
106
  if nil != dup_keys_in_file && !dup_keys_in_file.empty?
46
- Log::warn("Dup-keys found in #{file}: \n `#{dup_keys_in_file}`.")
107
+ Log::warn("Dup-keys found in #{sf.raw_file}: \n `#{dup_keys_in_file}`.")
47
108
  else
48
109
  # Log::info("OK . .")
49
110
  end
50
111
 
51
112
  if !mismatchs_in_file.empty?
52
113
  is_valid = false
114
+ @result.valid_file_format = false
53
115
  mismatchs_in_file.each { |e| e.each_pair {
54
116
  |key,value|
55
- Log::error("Mismatch format found in `#{file}`: \n `#{key}` ====> `#{value}`")
117
+ Log::error("Mismatch format found in `#{sf.raw_file}`: \n `#{key}` ====> `#{value}`")
56
118
  }
57
119
  }
58
120
  else
@@ -61,45 +123,47 @@ module Apstrings
61
123
  is_valid
62
124
  end
63
125
 
64
- def self.validate_missing(file,masterFile)
126
+ def self.validate_missing(sf,sf_masterFile)
65
127
  # puts "apstrings: checking missing keys for #{file}..."
66
- sf = Validator::paredFile(file)
67
- sf_masterFile = Validator::paredFile(masterFile)
68
128
  no_missing = true
69
129
  missing_keys = sf_masterFile.keys - sf.keys
130
+ @result.missing_keys = missing_keys;
70
131
  if !missing_keys.empty?
71
132
  no_missing =false
72
- Log::warn("#{missing_keys.count.to_s} missing keys found in #{file} comparing to master file: #{masterFile} : \n #{missing_keys.to_s}")
133
+ Log::warn("#{missing_keys.count.to_s} missing keys found in #{sf.raw_file} comparing to master file: #{sf_masterFile.raw_file} : \n #{missing_keys.to_s}")
73
134
  else
74
135
  # Log::info("OK...")
75
136
  end
76
137
  no_missing
77
138
  end
78
139
 
79
- def self.validate_duplicates(file)
140
+ def self.validate_duplicates(sf)
80
141
  # puts "apstrings: checking dup-keys for #{file}..."
81
- sf = Validator::paredFile(file)
82
142
  sf.keys.detect {
83
143
  |e| sf.keys.count(e) > 1
84
144
  }
85
145
  end
86
146
 
87
147
 
88
- def self.validate_special_characters(file)
148
+ def self.validate_special_characters(sf)
89
149
  # puts "apstrings: checking syntax for #{file}..."
90
- sf = Validator::paredFile(file)
91
150
  variables_regex = /%[hlqLztj]?[@%dDuUxXoOfeEgGcCsSpaAF]/
92
151
  mismatchs = []
93
152
  sf.key_values.each {
94
153
  |e| e.each_pair {
95
154
  |key,value|
96
155
  fixed_key = Validator::value_in_master(key)
97
- striped_key = fixed_key.gsub(/%\d\$/,'%') # Strip numbered format placeholders , e.g. %1$@ --> %@
98
- striped_value = value.gsub(/%\d\$/,'%')
99
- key_variables = striped_key.scan(variables_regex)
100
- value_variables = striped_value.scan(variables_regex)
101
- if !(key_variables.sort == value_variables.sort)
102
- mismatchs << {key => value}
156
+ if fixed_key != nil
157
+ striped_key = fixed_key.gsub(/%\d\$/,'%') # Strip numbered format placeholders , e.g. %1$@ --> %@
158
+ striped_value = value.gsub(/%\d\$/,'%')
159
+ key_variables = striped_key.scan(variables_regex)
160
+ value_variables = striped_value.scan(variables_regex)
161
+ if !(key_variables.sort == value_variables.sort)
162
+ mismatchs << {key => value}
163
+ end
164
+ else
165
+ # key in slavor file but does not exist in master file .
166
+ Log.warn("There is missing key in master file comparing to slavor. As we only check missing keys in slavor file, just ignore. \n ");
103
167
  end
104
168
  }
105
169
  }
@@ -107,8 +171,8 @@ module Apstrings
107
171
  end
108
172
 
109
173
  def self.paredFile(file)
110
- file = Reader.read(file)
111
- StringsParser.new(file).parse_file
174
+ read_file = Reader.read(file)
175
+ StringsParser.new(read_file,DotStringFile.new(file)).parse_file
112
176
  end
113
177
 
114
178
  def self.value_in_master(key)
@@ -1,3 +1,3 @@
1
1
  module Apstrings
2
- VERSION = "0.3.6"
2
+ VERSION = "0.3.7"
3
3
  end
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Formats validate.
3
+ *
4
+ * Example
5
+ * var master = 'Amount: %d Object: %@ String: %s Other: %u ';
6
+ * var slave = '数值: %d OC对象: %@ 字符串: %s 其它: %u ';
7
+ * var slave_err = '数值: % OC对象: %@ 字符串: %s 其它: %u ';
8
+ * var result = validate(master, slave) // true
9
+ * var result = validate(master, slave_err) // false
10
+ *
11
+ * Created by Jason Kaer on 6/17/16.
12
+ *
13
+ */
14
+
15
+ /***
16
+ * Add equals method to Array
17
+ */
18
+ (function () {
19
+ if (Array.prototype.equals)
20
+ console.warn("Overriding existing Array.prototype.equals. Possible causes: New API defines the method, there's a framework conflict or you've got double inclusions in your code.");
21
+ // attach the .equals method to Array's prototype to call it on any array
22
+ Array.prototype.equals = function (array) {
23
+ // if the other array is a falsy value, return
24
+ if (!array)
25
+ return false;
26
+
27
+ // compare lengths - can save a lot of time
28
+ if (this.length != array.length)
29
+ return false;
30
+
31
+ for (var i = 0, l = this.length; i < l; i++) {
32
+ // Check if we have nested arrays
33
+ if (this[i] instanceof Array && array[i] instanceof Array) {
34
+ // recurse into the nested arrays
35
+ if (!this[i].equals(array[i]))
36
+ return false;
37
+ }
38
+ else if (this[i] != array[i]) {
39
+ // Warning - two different object instances will never be equal: {x:20} != {x:20}
40
+ return false;
41
+ }
42
+ }
43
+ return true;
44
+ };
45
+ // Hide method from for-in loops
46
+ Object.defineProperty(Array.prototype, "equals", {enumerable: false});
47
+ }());
48
+
49
+
50
+ /***
51
+ * Validate formats(i.e. %d %s ...) in slave according to master .
52
+ * @param master The reference standard string in validate.
53
+ * @param slave The string to be validated.
54
+ * @returns {boolean}
55
+ */
56
+ function formats_validate(master, slave) {
57
+ try {
58
+ var format_m = formats_in_string(master);
59
+ var format_s = formats_in_string(slave);
60
+ return format_m.sort().equals(format_s.sort());
61
+ } catch (err) {
62
+ console.log(err);
63
+ return false;
64
+ }
65
+ }
66
+
67
+
68
+ /***
69
+ * Find all formats in a string
70
+ * @param input String to scan.
71
+ * @returns {Array}
72
+ */
73
+ function formats_in_string(input) {
74
+
75
+ var fix_regex = /%\d\$/g ;
76
+ var scan_regex = /%[hlqLztj]?[@%dDuUxXoOfeEgGcCsSpaAF]/g ;
77
+
78
+ //Strip numbered format placeholders , e.g. %1$@ --> %@
79
+ var fixed_input = input.replace(fix_regex, "%");
80
+ var m;
81
+ var result = [];
82
+ while ((m = scan_regex.exec(fixed_input)) !== null) {
83
+ if (m.index === scan_regex.lastIndex) {
84
+ scan_regex.lastIndex++;
85
+ }
86
+ result.push(m[0])
87
+ }
88
+
89
+ return result;
90
+ }
data/lib/test.rb ADDED
@@ -0,0 +1,6 @@
1
+ require './apstrings.rb'
2
+
3
+ puts Apstrings.parse('/Users/Jason/Desktop/test.strings').to_json
4
+
5
+
6
+ puts "aa : \" ".rstrip
metadata CHANGED
@@ -1,83 +1,83 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: apstrings
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.6
4
+ version: 0.3.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - JasonWorking
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-03 00:00:00.000000000 Z
11
+ date: 2016-06-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.10'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.10'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: '10.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ~>
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '10.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: 'true'
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ~>
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ~>
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: colored
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ~>
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ~>
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: json
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ~>
73
+ - - "~>"
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ~>
80
+ - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  description: An easy to use Apple dot strings file parser with encoding handled.
@@ -85,22 +85,19 @@ email:
85
85
  - 331314708@qq.com
86
86
  executables:
87
87
  - apstrings
88
- - console
89
- - setup
90
88
  extensions: []
91
89
  extra_rdoc_files: []
92
90
  files:
93
- - .gitignore
94
- - .travis.yml
91
+ - ".gitignore"
92
+ - ".travis.yml"
95
93
  - CODE_OF_CONDUCT.md
96
94
  - Gemfile
97
95
  - LICENSE.txt
98
96
  - README.md
99
97
  - Rakefile
98
+ - apstrings-0.3.7.gem
100
99
  - apstrings.gemspec
101
100
  - bin/apstrings
102
- - bin/console
103
- - bin/setup
104
101
  - lib/apstrings.rb
105
102
  - lib/apstrings/dot_string_file.rb
106
103
  - lib/apstrings/kv_pair.rb
@@ -111,6 +108,8 @@ files:
111
108
  - lib/apstrings/strings_validator.rb
112
109
  - lib/apstrings/tester.rb
113
110
  - lib/apstrings/version.rb
111
+ - lib/js/formatValidate.js
112
+ - lib/test.rb
114
113
  homepage: https://github.com/JasonWorking
115
114
  licenses:
116
115
  - MIT
@@ -121,17 +120,17 @@ require_paths:
121
120
  - lib
122
121
  required_ruby_version: !ruby/object:Gem::Requirement
123
122
  requirements:
124
- - - '>='
123
+ - - ">="
125
124
  - !ruby/object:Gem::Version
126
125
  version: '0'
127
126
  required_rubygems_version: !ruby/object:Gem::Requirement
128
127
  requirements:
129
- - - '>='
128
+ - - ">="
130
129
  - !ruby/object:Gem::Version
131
130
  version: '0'
132
131
  requirements: []
133
132
  rubyforge_project:
134
- rubygems_version: 2.0.14
133
+ rubygems_version: 2.0.14.1
135
134
  signing_key:
136
135
  specification_version: 4
137
136
  summary: Apple dot strings file parser.
data/bin/console DELETED
@@ -1,14 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "bundler/setup"
4
- require "apstrings"
5
-
6
- # You can add fixtures and/or initialization code here to make experimenting
7
- # with your gem easier. You can also use a different console, if you like.
8
-
9
- # (If you use this, don't forget to add pry to your Gemfile!)
10
- # require "pry"
11
- # Pry.start
12
-
13
- require "irb"
14
- IRB.start
data/bin/setup DELETED
@@ -1,7 +0,0 @@
1
- #!/bin/bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
-
5
- bundle install
6
-
7
- # Do any other automated setup that you need to do here