apstrings 0.3.6 → 0.3.7

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