contentful_bootstrap 3.1.1 → 3.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
  SHA1:
3
- metadata.gz: 707aaf25b774e94bc57a7a4fcbafca299a087c0b
4
- data.tar.gz: 931621f83a894b336f81fcd65b729dcd90c0e03f
3
+ metadata.gz: aed4d8f7790b4347e4b97050a049803f83ec1384
4
+ data.tar.gz: 91d3a12fd648ab548711294e39e9399bbb4c6e03
5
5
  SHA512:
6
- metadata.gz: 4c306b28133c2411c327b6ee266ad8ec04f9eaa1284dc40a82dd798b8c332f1571c856bd010c7ebb330e45696ef2f3bb483d9b1771e13bf8bca074edba074a90
7
- data.tar.gz: 20b2c92ab22e7b511fafb1cb9735e72a4fd8ec9ca0d37829d346245add717c80041dcc99594605dd72e1e4954a90ede31b5cb0110d4c372a7cba17f455e896a3
6
+ metadata.gz: a862d0a72856f0707f3ab2cd5920cef7484ea06b051cc308a6e03b45af3b60006dd86c86c4ffa23a9feaf8ed34e6811e813a24d5076bca28abe2d85e47ff2969
7
+ data.tar.gz: 31596e9e9211c8ec76daff969d3a79c2ea9aa6e7901ede6ab0b4b63ab7b1b4ecb7627664db8708c3841fc21fe425b96845a96a4eab0e43d519148fc0a5574faa
data/CHANGELOG.md CHANGED
@@ -2,6 +2,11 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## v3.2.0
6
+ ### Added
7
+ * Adds `update_space` command to update already existing spaces using JSON Templates
8
+ * Adds `--mark-processed` option to `create_space` and `update_space` to enforce marking which resources have already been processed
9
+
5
10
  ## v3.1.1
6
11
  ### Fixed
7
12
  * Fixes a bug where `display_field` was not properly populated when being generated from JSON templates [#35](https://github.com/contentful/contentful-bootstrap.rb/issues/35)
data/README.md CHANGED
@@ -26,7 +26,7 @@ $ gem install contentful_bootstrap
26
26
  You can create spaces by doing:
27
27
 
28
28
  ```bash
29
- $ contentful_bootstrap create_space <space_name> [--template template_name] [--json-template template_path] [--config CONFIG_PATH]
29
+ $ contentful_bootstrap create_space <space_name> [--template template_name] [--json-template template_path] [--mark-processed] [--config CONFIG_PATH]
30
30
  ```
31
31
 
32
32
  You can also generate new Delivery API Tokens by doing:
@@ -41,6 +41,12 @@ You can also generate JSON Templates from existing spaces by doing:
41
41
  $ contentful_bootstrap generate_json <space_id> <access_token> [--output-file OUTPUT PATH]
42
42
  ```
43
43
 
44
+ You can update existing spaces from JSON Templates by doing:
45
+
46
+ ```bash
47
+ $ contentful_bootstrap update_space <space_id> -j template_path [--mark-processed]
48
+ ```
49
+
44
50
  ### Built-in templates
45
51
 
46
52
  Just getting started with Contentful? We have included the following built-in templates:
@@ -81,11 +87,23 @@ Additionally, you can send an options hash with the following keys:
81
87
  options = {
82
88
  template: "blog", # Will use one of the predefined templates and create Content Types, Assets and Entries
83
89
  json_template: "/path/to/template.json", # Will use the JSON file specified as a Template
90
+ mark_processed: false, # if true will mark all resources as 'bootstrapProcessed' and will be avoided for update_space calls (doesnt affect create_space)
84
91
  trigger_oauth: true # if true will trigger OAuth process
85
92
  }
86
93
  Contentful::Bootstrap::CommandRunner.new.create_space("space_name", options)
87
94
  ```
88
95
 
96
+ To Update an existing Space
97
+
98
+ ```ruby
99
+ options = {
100
+ json_template: "/path/to/template.json", # Will use the JSON file specified as a Template
101
+ mark_processed: false, # if true will mark all resources as 'bootstrapProcessed and will be avoided on future update_space calls
102
+ trigger_oauth: true # if true will trigger OAuth process
103
+ }
104
+ Contentful::Bootstrap::CommandRunner.new.update_space("space_id", options)
105
+ ```
106
+
89
107
  To Create a new Delivery API Token
90
108
 
91
109
  ```ruby
@@ -147,6 +165,9 @@ Using the `--json-template` option, you can create spaces with your own predefin
147
165
  This can be useful for creating testing & development spaces or just starting new projects from
148
166
  a common baseline. You can find a complete example [here](./examples/templates/catalogue.json)
149
167
 
168
+ Using the `--mark-processed` option alongside `--json-template` will mark all resources as `bootstrapProcessed`,
169
+ which will make it so `update_space` calls avoid already created resources. (A resource being either a Content Type, Entry or Asset).
170
+
150
171
  ## Contributing
151
172
 
152
173
  Feel free to improve this tool by submitting a Pull Request. For more information,
@@ -7,13 +7,31 @@ options = {}
7
7
 
8
8
  subcommands = {
9
9
  'create_space' => OptionParser.new do |opts|
10
- opts.banner = "Usage: create_space <space_name> [--template TEMPLATE_NAME] [--json-template JSON_PATH] [--config CONFIG_PATH]"
10
+ opts.banner = "Usage: create_space <space_name> [--template TEMPLATE_NAME] [--json-template JSON_PATH] [--mark-processed] [--config CONFIG_PATH]"
11
11
  opts.on("-t TEMPLATE", "--template TEMPLATE", "Specify Template", "Available Templates: blog, catalogue, gallery") do |t|
12
12
  options[:template] = t
13
13
  end
14
14
  opts.on("-j JSON_PATH", "--json-template JSON_PATH", "Specify JSON Template Path") do |j|
15
15
  options[:json_template] = j
16
16
  end
17
+ opts.on('-m', '--mark-processed', "Mark Processed Items on JSON Templates") do |m|
18
+ options[:mark_processed] = m
19
+ end
20
+ opts.on("-c CONFIG_PATH", "--config CONFIG_PATH", "Specify Configuration Path") do |c|
21
+ options[:config_path] = c
22
+ end
23
+ opts.on_tail("-h", "--help", "Print this message") do
24
+ puts opts
25
+ end
26
+ end,
27
+ 'update_space' => OptionParser.new do |opts|
28
+ opts.banner = "Usage: update_space <space_id> --json-template JSON_PATH [--mark-processed] [--config CONFIG_PATH]"
29
+ opts.on("-j JSON_PATH", "--json-template JSON_PATH", "Specify JSON Template Path") do |j|
30
+ options[:json_template] = j
31
+ end
32
+ opts.on('-m', '--mark-processed', "Mark Processed Items on JSON Templates") do |m|
33
+ options[:mark_processed] = m
34
+ end
17
35
  opts.on("-c CONFIG_PATH", "--config CONFIG_PATH", "Specify Configuration Path") do |c|
18
36
  options[:config_path] = c
19
37
  end
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
- "content_types": [
3
+ "contentTypes": [
4
4
  {
5
5
  "id": "brand",
6
6
  "name": "Brand",
@@ -148,7 +148,7 @@
148
148
  "name": "Playsam, Inc",
149
149
  "website": "http://www.playsam.com",
150
150
  "logo": {
151
- "link_type": "Asset",
151
+ "linkType": "Asset",
152
152
  "id": "playsam_image"
153
153
  }
154
154
  }
@@ -14,10 +14,21 @@ module Contentful
14
14
  def create_space(space_name, options = {})
15
15
  template_name = options.fetch(:template, nil)
16
16
  json_template = options.fetch(:json_template, nil)
17
+ mark_processed = options.fetch(:mark_processed, false)
17
18
  trigger_oauth = options.fetch(:trigger_oauth, true)
18
19
 
19
20
  Contentful::Bootstrap::Commands::CreateSpace.new(
20
- @token, space_name, template_name, json_template, trigger_oauth
21
+ @token, space_name, template_name, json_template, mark_processed, trigger_oauth
22
+ ).run
23
+ end
24
+
25
+ def update_space(space_id, options = {})
26
+ json_template = options.fetch(:json_template, nil)
27
+ mark_processed = options.fetch(:mark_processed, false)
28
+ trigger_oauth = options.fetch(:trigger_oauth, true)
29
+
30
+ Contentful::Bootstrap::Commands::UpdateSpace.new(
31
+ @token, space_id, json_template, mark_processed, trigger_oauth
21
32
  ).run
22
33
  end
23
34
 
@@ -1,3 +1,4 @@
1
1
  require 'contentful/bootstrap/commands/create_space'
2
+ require 'contentful/bootstrap/commands/update_space'
2
3
  require 'contentful/bootstrap/commands/generate_token'
3
4
  require 'contentful/bootstrap/commands/generate_json'
@@ -9,10 +9,13 @@ module Contentful
9
9
  module Commands
10
10
  class CreateSpace < Base
11
11
  attr_reader :template_name, :json_template
12
- def initialize(token, space_name, template_name = nil, json_template = nil, trigger_oauth = true)
12
+ def initialize(
13
+ token, space_name, template_name = nil,
14
+ json_template = nil, mark_processed = false, trigger_oauth = true)
13
15
  super(token, space_name, trigger_oauth)
14
16
  @template_name = template_name
15
17
  @json_template = json_template
18
+ @mark_processed = mark_processed
16
19
  end
17
20
 
18
21
  def run
@@ -92,7 +95,7 @@ module Contentful
92
95
  def create_json_template(space)
93
96
  if ::File.exist?(@json_template)
94
97
  puts "Creating JSON Template '#{@json_template}'"
95
- Templates::JsonTemplate.new(space, @json_template).run
98
+ Templates::JsonTemplate.new(space, @json_template, @mark_processed).run
96
99
  puts "JSON Template '#{@json_template}' created!"
97
100
  else
98
101
  puts "JSON Template '#{@json_template}' does not exist. Please check that you specified the correct file name."
@@ -0,0 +1,59 @@
1
+ require 'contentful/management'
2
+ require 'contentful/management/error'
3
+ require 'contentful/bootstrap/templates'
4
+ require 'contentful/bootstrap/commands/base'
5
+
6
+ module Contentful
7
+ module Bootstrap
8
+ module Commands
9
+ class UpdateSpace < Base
10
+ attr_reader :json_template
11
+ def initialize(token, space_id, json_template = nil, mark_processed = false, trigger_oauth = true)
12
+ super(token, space_id, trigger_oauth)
13
+ @json_template = json_template
14
+ @mark_processed = mark_processed
15
+ end
16
+
17
+ def run
18
+ if @json_template.nil?
19
+ puts 'JSON Template not found. Exiting!'
20
+ exit(1)
21
+ end
22
+
23
+ puts "Updating Space '#{@space}'"
24
+
25
+ update_space = fetch_space
26
+
27
+ update_json_template(update_space)
28
+
29
+ puts
30
+ puts "Successfully updated Space #{@space}"
31
+
32
+ update_space
33
+ end
34
+
35
+ protected
36
+
37
+ def fetch_space
38
+ Contentful::Management::Space.find(@space)
39
+ rescue Contentful::Management::NotFound
40
+ puts 'Space Not Found. Exiting!'
41
+ exit(1)
42
+ end
43
+
44
+ private
45
+
46
+ def update_json_template(space)
47
+ if ::File.exist?(@json_template)
48
+ puts "Updating from JSON Template '#{@json_template}'"
49
+ Templates::JsonTemplate.new(space, @json_template, @mark_processed, false).run
50
+ puts "JSON Template '#{@json_template}' updated!"
51
+ else
52
+ puts "JSON Template '#{@json_template}' does not exist. Please check that you specified the correct file name."
53
+ exit(1)
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -16,6 +16,8 @@ module Contentful
16
16
  create_content_types
17
17
  create_assets
18
18
  create_entries
19
+
20
+ after_run
19
21
  rescue Contentful::Management::Error => e
20
22
  error = e.error
21
23
  puts "Error at: #{error[:url]}"
@@ -37,6 +39,9 @@ module Contentful
37
39
  []
38
40
  end
39
41
 
42
+ def after_run
43
+ end
44
+
40
45
  protected
41
46
 
42
47
  def create_image(name, url)
@@ -51,34 +56,40 @@ module Contentful
51
56
 
52
57
  def create_content_types
53
58
  content_types.each do |ct|
54
- puts "Creating Content Type '#{ct['name']}'"
55
-
56
- fields = []
57
- content_type = space.content_types.new
58
- content_type.id = ct['id']
59
- content_type.name = ct['name']
60
- content_type.display_field = ct['display_field']
61
-
62
- ct['fields'].each do |f|
63
- field = Contentful::Management::Field.new
64
- field.id = f['id']
65
- field.name = f['name']
66
- field.type = f['type']
67
- field.link_type = f['linkType'] if link?(f)
68
-
69
- if array?(f)
70
- array_field = Contentful::Management::Field.new
71
- array_field.type = f['items']['type']
72
- array_field.link_type = f['items']['linkType']
73
- field.items = array_field
59
+ begin
60
+ puts "Creating Content Type '#{ct['name']}'"
61
+
62
+ fields = []
63
+ content_type = space.content_types.new
64
+ content_type.id = ct['id']
65
+ content_type.name = ct['name']
66
+ content_type.display_field = ct['display_field']
67
+ content_type.description = ct['description']
68
+
69
+ ct['fields'].each do |f|
70
+ field = Contentful::Management::Field.new
71
+ field.id = f['id']
72
+ field.name = f['name']
73
+ field.type = f['type']
74
+ field.link_type = f['linkType'] if link?(f)
75
+
76
+ if array?(f)
77
+ array_field = Contentful::Management::Field.new
78
+ array_field.type = f['items']['type']
79
+ array_field.link_type = f['items']['linkType']
80
+ field.items = array_field
81
+ end
82
+
83
+ fields << field
74
84
  end
75
85
 
76
- fields << field
86
+ content_type.fields = fields
87
+ content_type.save
88
+ content_type.activate
89
+ rescue Contentful::Management::Conflict
90
+ puts "ContentType '#{ct['id']}' already created! Skipping"
91
+ next
77
92
  end
78
-
79
- content_type.fields = fields
80
- content_type.save
81
- content_type.activate
82
93
  end
83
94
  end
84
95
 
@@ -92,23 +103,28 @@ module Contentful
92
103
 
93
104
  def create_assets
94
105
  assets.each do |asset|
95
- puts "Creating Asset '#{asset['title']}'"
96
- asset = space.assets.create(
97
- id: asset['id'],
98
- title: asset['title'],
99
- file: asset['file']
100
- )
101
- asset.process_file
102
-
103
- attempts = 0
104
- while attempts < 10
105
- unless space.assets.find(asset.id).file.url.nil?
106
- asset.publish
107
- break
108
- end
106
+ begin
107
+ puts "Creating Asset '#{asset['title']}'"
108
+ asset = space.assets.create(
109
+ id: asset['id'],
110
+ title: asset['title'],
111
+ file: asset['file']
112
+ )
113
+ asset.process_file
114
+
115
+ attempts = 0
116
+ while attempts < 10
117
+ unless space.assets.find(asset.id).file.url.nil?
118
+ asset.publish
119
+ break
120
+ end
109
121
 
110
- sleep(1) # Wait for Process
111
- attempts += 1
122
+ sleep(1) # Wait for Process
123
+ attempts += 1
124
+ end
125
+ rescue Contentful::Management::Conflict
126
+ puts "Asset '#{asset['id']}' already created! Skipping"
127
+ next
112
128
  end
113
129
  end
114
130
  end
@@ -150,17 +166,23 @@ module Contentful
150
166
  e[rf.to_sym] = value
151
167
  end
152
168
 
153
- entry = content_type.entries.create({:id => e[:id]})
154
- entry.save
155
-
156
- e = e.clone
157
- e[:id] = entry.id # in case no ID was specified in template
158
- e
169
+ begin
170
+ puts "Creating Entry #{e[:id]}"
171
+ entry = content_type.entries.create({:id => e[:id]})
172
+ entry.save
173
+
174
+ e = e.clone
175
+ e[:id] = entry.id # in case no ID was specified in template
176
+ rescue Contentful::Management::Conflict
177
+ puts "Entry '#{e[:id]}' already exists! Skipping"
178
+ ensure
179
+ next e
180
+ end
159
181
  end
160
182
  end.flatten
161
183
 
162
184
  processed_entries = processed_entries.map do |e|
163
- puts "Creating Entry #{e[:id]}"
185
+ puts "Populating Entry #{e[:id]}"
164
186
 
165
187
  entry = space.entries.find(e[:id])
166
188
  e.delete(:id)
@@ -169,7 +191,7 @@ module Contentful
169
191
 
170
192
  10.times do
171
193
  break if space.entries.find(entry.id).sys[:version] >= 4
172
- sleep(1)
194
+ sleep(0.5)
173
195
  end
174
196
 
175
197
  entry.id
@@ -6,31 +6,53 @@ module Contentful
6
6
  module Bootstrap
7
7
  module Templates
8
8
  class JsonTemplate < Base
9
- def initialize(space, file)
9
+ CONTENT_TYPES_KEY = 'contentTypes'
10
+ ENTRIES_KEY = 'entries'
11
+ ASSETS_KEY = 'assets'
12
+ BOOTSTRAP_PROCCESSED_KEY = 'bootstrapProcessed'
13
+ DISPLAY_FIELD_KEY = 'display_field'
14
+ ALTERNATE_DISPLAY_FIELD_KEY = 'displayField'
15
+ SYS_KEY = 'sys'
16
+
17
+ attr_reader :assets, :entries, :content_types
18
+
19
+ def initialize(space, file, mark_processed = false, all = true)
10
20
  @space = space
11
21
  @file = file
12
- @assets = nil
13
- @entries = nil
22
+ @all = all
23
+ @mark_processed = mark_processed
24
+
14
25
  json
15
26
 
27
+ @assets = process_assets
28
+ @entries = process_entries
29
+ @content_types = process_content_types
30
+
16
31
  check_version
17
32
  end
18
33
 
19
- def content_types
20
- processed_content_types = json.fetch('contentTypes', [])
21
- processed_content_types.each do |content_type|
22
- content_type['display_field'] = content_type.key?('displayField') ? content_type.delete('displayField') : content_type['display_field']
34
+ def after_run
35
+ return unless mark_processed?
36
+
37
+ @json.fetch(CONTENT_TYPES_KEY, []).each do |content_type|
38
+ content_type[BOOTSTRAP_PROCCESSED_KEY] = true
23
39
  end
24
40
 
25
- processed_content_types
26
- end
41
+ @json.fetch(ASSETS_KEY, []).each do |asset|
42
+ asset[BOOTSTRAP_PROCCESSED_KEY] = true
43
+ end
27
44
 
28
- def assets
29
- @assets ||= process_assets
30
- end
45
+ @json.fetch(ENTRIES_KEY, {}).each do |_content_type_name, entry_list|
46
+ entry_list.each do |entry|
47
+ if entry.key?(SYS_KEY)
48
+ entry[SYS_KEY][BOOTSTRAP_PROCCESSED_KEY] = true
49
+ else
50
+ entry[SYS_KEY] = { BOOTSTRAP_PROCCESSED_KEY => true }
51
+ end
52
+ end
53
+ end
31
54
 
32
- def entries
33
- @entries ||= process_entries
55
+ ::File.write(@file, JSON.pretty_generate(@json))
34
56
  end
35
57
 
36
58
  private
@@ -45,10 +67,36 @@ module Contentful
45
67
 
46
68
  def json
47
69
  @json ||= ::JSON.parse(::File.read(@file))
70
+ rescue
71
+ puts 'File is not JSON. Exiting!'
72
+ exit(1)
73
+ end
74
+
75
+ def process_content_types
76
+ processed_content_types = json.fetch(CONTENT_TYPES_KEY, [])
77
+
78
+ unless all?
79
+ processed_content_types = processed_content_types.select do |content_type|
80
+ !content_type.fetch(BOOTSTRAP_PROCCESSED_KEY, false)
81
+ end
82
+ end
83
+
84
+ processed_content_types.each do |content_type|
85
+ content_type[DISPLAY_FIELD_KEY] = content_type.key?(ALTERNATE_DISPLAY_FIELD_KEY) ? content_type.delete(ALTERNATE_DISPLAY_FIELD_KEY) : content_type[DISPLAY_FIELD_KEY]
86
+ end
87
+
88
+ processed_content_types
48
89
  end
49
90
 
50
91
  def process_assets
51
- unprocessed_assets = json.fetch('assets', [])
92
+ unprocessed_assets = json.fetch(ASSETS_KEY, [])
93
+
94
+ unless all?
95
+ unprocessed_assets = unprocessed_assets.select do |asset|
96
+ !asset.fetch(BOOTSTRAP_PROCCESSED_KEY, false)
97
+ end
98
+ end
99
+
52
100
  unprocessed_assets.map do |asset|
53
101
  asset['file'] = create_image(
54
102
  asset['file']['filename'],
@@ -60,15 +108,22 @@ module Contentful
60
108
 
61
109
  def process_entries
62
110
  processed_entries = {}
63
- unprocessed_entries = json.fetch('entries', {})
111
+ unprocessed_entries = json.fetch(ENTRIES_KEY, {})
64
112
  unprocessed_entries.each do |content_type_id, entry_list|
65
113
  entries_for_content_type = []
114
+
115
+ unless all?
116
+ entry_list = entry_list.select do |entry|
117
+ !entry[SYS_KEY].fetch(BOOTSTRAP_PROCCESSED_KEY, false)
118
+ end
119
+ end
120
+
66
121
  entry_list.each do |entry|
67
122
  processed_entry = {}
68
123
  array_fields = []
69
124
  link_fields = []
70
125
 
71
- processed_entry['id'] = entry['sys']['id'] if entry.key?('sys') && entry['sys'].key?('id')
126
+ processed_entry['id'] = entry[SYS_KEY]['id'] if entry.key?(SYS_KEY) && entry[SYS_KEY].key?('id')
72
127
 
73
128
  entry.fetch('fields', {}).each do |field, value|
74
129
  link_fields << field if value.is_a? ::Hash
@@ -108,6 +163,14 @@ module Contentful
108
163
  Contentful::Bootstrap::Templates::Links::Asset.new(id)
109
164
  end
110
165
  end
166
+
167
+ def all?
168
+ @all
169
+ end
170
+
171
+ def mark_processed?
172
+ @mark_processed
173
+ end
111
174
  end
112
175
  end
113
176
  end
@@ -1,6 +1,6 @@
1
1
  module Contentful
2
2
  module Bootstrap
3
- VERSION = '3.1.1'
3
+ VERSION = '3.2.0'
4
4
 
5
5
  def self.major_version
6
6
  VERSION.split('.').first.to_i
@@ -5,8 +5,6 @@ describe Contentful::Bootstrap::CommandRunner do
5
5
  subject { Contentful::Bootstrap::CommandRunner.new(path) }
6
6
 
7
7
  describe 'instance methods' do
8
- before do
9
- end
10
8
  describe '#create_space' do
11
9
  before do
12
10
  allow_any_instance_of(Contentful::Bootstrap::Commands::CreateSpace).to receive(:run)
@@ -14,7 +12,7 @@ describe Contentful::Bootstrap::CommandRunner do
14
12
 
15
13
  it 'default values' do
16
14
  expect(Contentful::Bootstrap::Commands::CreateSpace).to receive(:new).with(
17
- subject.token, 'foo', nil, nil, true
15
+ subject.token, 'foo', nil, nil, false, true
18
16
  ).and_call_original
19
17
 
20
18
  subject.create_space('foo')
@@ -22,10 +20,10 @@ describe Contentful::Bootstrap::CommandRunner do
22
20
 
23
21
  it 'with options' do
24
22
  expect(Contentful::Bootstrap::Commands::CreateSpace).to receive(:new).with(
25
- subject.token, 'foo', 'bar', 'baz', false
23
+ subject.token, 'foo', 'bar', 'baz', true, false
26
24
  ).and_call_original
27
25
 
28
- subject.create_space('foo', template: 'bar', json_template: 'baz', trigger_oauth: false)
26
+ subject.create_space('foo', template: 'bar', json_template: 'baz', mark_processed: true, trigger_oauth: false)
29
27
  end
30
28
 
31
29
  it 'runs command' do
@@ -35,6 +33,34 @@ describe Contentful::Bootstrap::CommandRunner do
35
33
  end
36
34
  end
37
35
 
36
+ describe '#update_space' do
37
+ before do
38
+ allow_any_instance_of(Contentful::Bootstrap::Commands::UpdateSpace).to receive(:run)
39
+ end
40
+
41
+ it 'default values' do
42
+ expect(Contentful::Bootstrap::Commands::UpdateSpace).to receive(:new).with(
43
+ subject.token, 'foo', nil, false, true
44
+ ).and_call_original
45
+
46
+ subject.update_space('foo')
47
+ end
48
+
49
+ it 'with options' do
50
+ expect(Contentful::Bootstrap::Commands::UpdateSpace).to receive(:new).with(
51
+ subject.token, 'foo', 'bar', true, false
52
+ ).and_call_original
53
+
54
+ subject.update_space('foo', json_template: 'bar', mark_processed: true, trigger_oauth: false)
55
+ end
56
+
57
+ it 'runs command' do
58
+ expect_any_instance_of(Contentful::Bootstrap::Commands::UpdateSpace).to receive(:run)
59
+
60
+ subject.update_space('foo', json_template: 'bar', trigger_oauth: false)
61
+ end
62
+ end
63
+
38
64
  describe '#generate_token' do
39
65
  before do
40
66
  allow_any_instance_of(Contentful::Bootstrap::Commands::GenerateToken).to receive(:run)
@@ -3,9 +3,13 @@ require 'spec_helper'
3
3
  describe Contentful::Bootstrap::Commands::CreateSpace do
4
4
  let(:path) { File.expand_path(File.join('spec', 'fixtures', 'ini_fixtures', 'contentfulrc.ini')) }
5
5
  let(:token) { Contentful::Bootstrap::Token.new path }
6
- subject { Contentful::Bootstrap::Commands::CreateSpace.new token, 'foo', 'bar', 'baz', false }
6
+ subject { Contentful::Bootstrap::Commands::CreateSpace.new token, 'foo', 'bar', 'baz', false, false }
7
7
  let(:space_double) { SpaceDouble.new }
8
8
 
9
+ before do
10
+ allow(::File).to receive(:write)
11
+ end
12
+
9
13
  describe 'instance methods' do
10
14
  describe '#run' do
11
15
  it 'with all non nil attributes' do
@@ -18,7 +22,7 @@ describe Contentful::Bootstrap::Commands::CreateSpace do
18
22
  end
19
23
 
20
24
  it 'does not create template when template_name is nil' do
21
- create_space_command = described_class.new(token, 'foo', nil, 'baz', false)
25
+ create_space_command = described_class.new(token, 'foo', nil, 'baz', false, false)
22
26
 
23
27
  expect(create_space_command.template_name).to eq nil
24
28
 
@@ -31,7 +35,7 @@ describe Contentful::Bootstrap::Commands::CreateSpace do
31
35
  end
32
36
 
33
37
  it 'does not create json template when json_template is nil' do
34
- create_space_command = described_class.new(token, 'foo', 'bar', nil, false)
38
+ create_space_command = described_class.new(token, 'foo', 'bar', nil, false, false)
35
39
 
36
40
  expect(create_space_command.json_template).to eq nil
37
41
 
@@ -62,7 +66,7 @@ describe Contentful::Bootstrap::Commands::CreateSpace do
62
66
  allow_any_instance_of(described_class).to receive(:gets).and_return('y')
63
67
  allow_any_instance_of(Contentful::Bootstrap::Commands::GenerateToken).to receive(:gets).and_return('n')
64
68
 
65
- command = described_class.new(token, 'issue_22', nil, json_path)
69
+ command = described_class.new(token, 'issue_22', nil, json_path, false)
66
70
 
67
71
  vcr('issue_22') {
68
72
  command.run
@@ -0,0 +1,68 @@
1
+ require 'spec_helper'
2
+
3
+ describe Contentful::Bootstrap::Commands::UpdateSpace do
4
+ let(:path) { File.expand_path(File.join('spec', 'fixtures', 'ini_fixtures', 'contentfulrc.ini')) }
5
+ let(:token) { Contentful::Bootstrap::Token.new path }
6
+ subject { Contentful::Bootstrap::Commands::UpdateSpace.new token, 'foo', 'bar', false, false }
7
+ let(:space_double) { SpaceDouble.new }
8
+
9
+ before do
10
+ allow(::File).to receive(:write)
11
+ end
12
+
13
+ describe 'instance methods' do
14
+ describe '#run' do
15
+ it 'with all non nil attributes' do
16
+ expect(subject).to receive(:fetch_space) { space_double }
17
+ expect(subject).to receive(:update_json_template).with(space_double)
18
+
19
+ expect(subject.run).to eq(space_double)
20
+ end
21
+
22
+ it 'exits if JSON not sent' do
23
+ update_space_command = described_class.new(token, 'foo', nil, false)
24
+
25
+ expect { update_space_command.run }.to raise_error SystemExit
26
+ end
27
+
28
+ it 'exits if space is not found' do
29
+ update_space_command = described_class.new(token, 'foo', 'bar', false)
30
+
31
+ expect(::Contentful::Management::Space).to receive(:find).with('foo').and_raise(::Contentful::Management::NotFound.new(ErrorRequestDouble.new))
32
+
33
+ expect { update_space_command.run }.to raise_error SystemExit
34
+ end
35
+
36
+ it 'exits if JSON template is not an existing file' do
37
+ expect(subject).to receive(:fetch_space) { space_double }
38
+
39
+ expect { subject.run }.to raise_error SystemExit
40
+ end
41
+
42
+ describe 'runs JSON Template without already processed elements' do
43
+ [true, false].each do |mark_processed|
44
+ it (mark_processed ? 'marks as processed after run' : 'doesnt modify input file after done') do
45
+ subject = described_class.new token, 'foo', 'bar', mark_processed, false
46
+
47
+ allow(::File).to receive(:exist?) { true }
48
+
49
+ mock_template = Object.new
50
+
51
+ expect(subject).to receive(:fetch_space) { space_double }
52
+ expect(mock_template).to receive(:run)
53
+
54
+ expect(::Contentful::Bootstrap::Templates::JsonTemplate).to receive(:new).with(space_double, 'bar', mark_processed, false) { mock_template }
55
+
56
+ subject.run
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ describe 'attributes' do
64
+ it ':json_template' do
65
+ expect(subject.json_template).to eq 'bar'
66
+ end
67
+ end
68
+ end
@@ -17,12 +17,20 @@ describe Contentful::Bootstrap::Templates::Base do
17
17
  expect(subject.assets).to eq []
18
18
  end
19
19
 
20
- it '#run' do
21
- ['content_types', 'assets', 'entries'].each do |name|
22
- expect(subject).to receive("create_#{name}".to_sym)
20
+ describe '#run' do
21
+ it 'calls create for each kind of object' do
22
+ ['content_types', 'assets', 'entries'].each do |name|
23
+ expect(subject).to receive("create_#{name}".to_sym)
24
+ end
25
+
26
+ subject.run
23
27
  end
24
28
 
25
- subject.run
29
+ it 'calls after_run when done' do
30
+ expect(subject).to receive(:after_run)
31
+
32
+ subject.run
33
+ end
26
34
  end
27
35
  end
28
36
 
@@ -2,9 +2,13 @@ require 'spec_helper'
2
2
 
3
3
  describe Contentful::Bootstrap::Templates::JsonTemplate do
4
4
  let(:space) { Contentful::Management::Space.new }
5
- let(:path) { File.expand_path(File.join('spec', 'fixtures', 'json_fixtures', 'simple.json')) }
5
+ let(:path) { json_path('simple') }
6
6
  subject { described_class.new space, path }
7
7
 
8
+ before do
9
+ allow(::File).to receive(:write)
10
+ end
11
+
8
12
  describe 'instance methods' do
9
13
  describe '#content_types' do
10
14
  it 'fetches content types' do
@@ -63,10 +67,10 @@ describe Contentful::Bootstrap::Templates::JsonTemplate do
63
67
  end
64
68
 
65
69
  describe 'template version check' do
66
- let(:invalid_version_path) { File.expand_path(File.join('spec', 'fixtures', 'json_fixtures', 'invalid.json')) }
67
- let(:low_version_path) { File.expand_path(File.join('spec', 'fixtures', 'json_fixtures', 'low.json')) }
68
- let(:high_version_path) { File.expand_path(File.join('spec', 'fixtures', 'json_fixtures', 'high.json')) }
69
- let(:ok_version_path) { File.expand_path(File.join('spec', 'fixtures', 'json_fixtures', 'ok_version.json')) }
70
+ let(:invalid_version_path) { json_path('invalid') }
71
+ let(:low_version_path) { json_path('low') }
72
+ let(:high_version_path) { json_path('high') }
73
+ let(:ok_version_path) { json_path('ok_version') }
70
74
 
71
75
  it 'rejects templates without version' do
72
76
  expect { described_class.new space, invalid_version_path }.to raise_error "JSON Templates Version Mismatch. Current Version: 3"
@@ -86,7 +90,7 @@ describe Contentful::Bootstrap::Templates::JsonTemplate do
86
90
  end
87
91
 
88
92
  describe 'issues' do
89
- let(:link_entry_path) { File.expand_path(File.join('spec', 'fixtures', 'json_fixtures', 'links.json')) }
93
+ let(:link_entry_path) { json_path('links') }
90
94
 
91
95
  it 'links are not properly getting processed - #33' do
92
96
  subject = described_class.new space, link_entry_path
@@ -99,4 +103,69 @@ describe Contentful::Bootstrap::Templates::JsonTemplate do
99
103
  )
100
104
  end
101
105
  end
106
+
107
+ describe 'bootstrap processed' do
108
+ let(:processed_path) { json_path('processed') }
109
+
110
+ it 'filters content types that were already processed' do
111
+ json_fixture('processed') { |json|
112
+ expect(json['contentTypes'].size).to eq(2)
113
+ expect(json['contentTypes'].last['id']).to eq('dog')
114
+
115
+ subject = described_class.new(space, processed_path, false, false)
116
+
117
+ expect(subject.content_types.size).to eq(1)
118
+ expect(subject.content_types.first['id']).to eq('cat')
119
+ }
120
+ end
121
+
122
+ it 'filters assets that were already processed' do
123
+ json_fixture('processed') { |json|
124
+ expect(json['assets'].size).to eq(2)
125
+ expect(json['assets'].last['id']).to eq('dog_asset')
126
+
127
+ subject = described_class.new(space, processed_path, false, false)
128
+
129
+ expect(subject.assets.size).to eq(1)
130
+ expect(subject.assets.first['id']).to eq('cat_asset')
131
+ }
132
+ end
133
+
134
+ it 'filters entries that were already processed' do
135
+ json_fixture('processed') { |json|
136
+ expect(json['entries']['dog'].size).to eq(1)
137
+ expect(json['entries']['dog'].first['sys']['id']).to eq('doge')
138
+
139
+ subject = described_class.new(space, processed_path, false, false)
140
+
141
+ expect(subject.entries['dog'].size).to eq(0)
142
+ }
143
+ end
144
+ end
145
+
146
+ describe 'mark processed' do
147
+ it 'does not write file after run if not mark_processed' do
148
+ subject = described_class.new(space, path, false, false)
149
+ ['content_types', 'assets', 'entries'].each do |n|
150
+ allow(subject).to receive("create_#{n}".to_sym)
151
+ end
152
+
153
+ expect(subject).to receive(:after_run).and_call_original
154
+ expect(::File).not_to receive(:write)
155
+
156
+ subject.run
157
+ end
158
+
159
+ it 'writes file after run if mark_processed' do
160
+ subject = described_class.new(space, path, true, false)
161
+ ['content_types', 'assets', 'entries'].each do |n|
162
+ allow(subject).to receive("create_#{n}".to_sym)
163
+ end
164
+
165
+ expect(subject).to receive(:after_run).and_call_original
166
+ expect(::File).to receive(:write)
167
+
168
+ subject.run
169
+ end
170
+ end
102
171
  end
@@ -0,0 +1,72 @@
1
+ {
2
+ "version": 3,
3
+ "contentTypes": [
4
+ {
5
+ "id": "cat",
6
+ "name": "Cat",
7
+ "displayField": "name",
8
+ "fields": [
9
+ {
10
+ "id": "name",
11
+ "name": "Name",
12
+ "type": "Symbol"
13
+ }
14
+ ]
15
+ },
16
+ {
17
+ "id": "dog",
18
+ "bootstrapProcessed": true,
19
+ "name": "Dog",
20
+ "displayField": "name",
21
+ "fields": [
22
+ {
23
+ "id": "name",
24
+ "name": "Name",
25
+ "type": "Symbol"
26
+ }
27
+ ]
28
+ }
29
+ ],
30
+ "assets": [
31
+ {
32
+ "id": "cat_asset",
33
+ "title": "Cat",
34
+ "file": {
35
+ "filename": "cat",
36
+ "url": "https://somecat.com/my_cat.jpeg"
37
+ }
38
+ },
39
+ {
40
+ "id": "dog_asset",
41
+ "bootstrapProcessed": true,
42
+ "title": "Dog",
43
+ "file": {
44
+ "filename": "Dog",
45
+ "url": "https://somedog.com/my_dog.jpeg"
46
+ }
47
+ }
48
+ ],
49
+ "entries": {
50
+ "cat": [
51
+ {
52
+ "sys": {
53
+ "id": "nyancat"
54
+ },
55
+ "fields": {
56
+ "name": "Nyan Cat"
57
+ }
58
+ }
59
+ ],
60
+ "dog": [
61
+ {
62
+ "sys": {
63
+ "id": "doge",
64
+ "bootstrapProcessed": true
65
+ },
66
+ "fields": {
67
+ "name": "Doge"
68
+ }
69
+ }
70
+ ]
71
+ }
72
+ }
data/spec/spec_helper.rb CHANGED
@@ -5,12 +5,16 @@ require 'vcr'
5
5
  require 'json'
6
6
 
7
7
  VCR.configure do |config|
8
- config.cassette_library_dir = "spec/fixtures/vcr_fixtures"
8
+ config.cassette_library_dir = File.join('spec', 'fixtures', 'vcr_fixtures')
9
9
  config.hook_into :webmock
10
10
  end
11
11
 
12
+ def json_path(name)
13
+ File.join('spec', 'fixtures', 'json_fixtures', "#{name}.json")
14
+ end
15
+
12
16
  def json_fixture(name)
13
- json = JSON.load(File.read("spec/fixtures/json_fixtures/#{name}.json"))
17
+ json = JSON.load(File.read(File.expand_path(json_path(name))))
14
18
  yield json if block_given?
15
19
  json
16
20
  end
@@ -42,6 +46,14 @@ class ServerDouble
42
46
  end
43
47
  end
44
48
 
49
+ class ErrorRequestDouble
50
+ def request; self; end
51
+ def endpoint; self; end
52
+ def error_message; self; end
53
+ def raw; self; end
54
+ def body; self; end
55
+ end
56
+
45
57
  class RequestDouble
46
58
  attr_accessor :query
47
59
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: contentful_bootstrap
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.1
4
+ version: 3.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Litvak Bruno
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-05-02 00:00:00.000000000 Z
11
+ date: 2016-05-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -221,6 +221,7 @@ files:
221
221
  - lib/contentful/bootstrap/commands/create_space.rb
222
222
  - lib/contentful/bootstrap/commands/generate_json.rb
223
223
  - lib/contentful/bootstrap/commands/generate_token.rb
224
+ - lib/contentful/bootstrap/commands/update_space.rb
224
225
  - lib/contentful/bootstrap/constants.rb
225
226
  - lib/contentful/bootstrap/generator.rb
226
227
  - lib/contentful/bootstrap/management.rb
@@ -243,6 +244,7 @@ files:
243
244
  - spec/contentful/bootstrap/commands/create_space_spec.rb
244
245
  - spec/contentful/bootstrap/commands/generate_json_spec.rb
245
246
  - spec/contentful/bootstrap/commands/generate_token_spec.rb
247
+ - spec/contentful/bootstrap/commands/update_space_spec.rb
246
248
  - spec/contentful/bootstrap/generator_spec.rb
247
249
  - spec/contentful/bootstrap/management_spec.rb
248
250
  - spec/contentful/bootstrap/server_spec.rb
@@ -268,6 +270,7 @@ files:
268
270
  - spec/fixtures/json_fixtures/low.json
269
271
  - spec/fixtures/json_fixtures/no_ids.json
270
272
  - spec/fixtures/json_fixtures/ok_version.json
273
+ - spec/fixtures/json_fixtures/processed.json
271
274
  - spec/fixtures/json_fixtures/simple.json
272
275
  - spec/fixtures/json_fixtures/wl1z0pal05vy.json
273
276
  - spec/fixtures/vcr_fixtures/create_space.yml
@@ -309,6 +312,7 @@ test_files:
309
312
  - spec/contentful/bootstrap/commands/create_space_spec.rb
310
313
  - spec/contentful/bootstrap/commands/generate_json_spec.rb
311
314
  - spec/contentful/bootstrap/commands/generate_token_spec.rb
315
+ - spec/contentful/bootstrap/commands/update_space_spec.rb
312
316
  - spec/contentful/bootstrap/generator_spec.rb
313
317
  - spec/contentful/bootstrap/management_spec.rb
314
318
  - spec/contentful/bootstrap/server_spec.rb
@@ -334,6 +338,7 @@ test_files:
334
338
  - spec/fixtures/json_fixtures/low.json
335
339
  - spec/fixtures/json_fixtures/no_ids.json
336
340
  - spec/fixtures/json_fixtures/ok_version.json
341
+ - spec/fixtures/json_fixtures/processed.json
337
342
  - spec/fixtures/json_fixtures/simple.json
338
343
  - spec/fixtures/json_fixtures/wl1z0pal05vy.json
339
344
  - spec/fixtures/vcr_fixtures/create_space.yml