wcc-contentful 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +1 -1
  3. data/.gitignore +5 -0
  4. data/.rubocop.yml +3 -0
  5. data/CHANGELOG.md +8 -1
  6. data/Guardfile +23 -1
  7. data/app/controllers/wcc/contentful/application_controller.rb +7 -0
  8. data/app/controllers/wcc/contentful/webhook_controller.rb +30 -0
  9. data/app/jobs/wcc/contentful/delayed_sync_job.rb +14 -0
  10. data/bin/rails +14 -0
  11. data/config/initializers/mime_types.rb +3 -0
  12. data/config/routes.rb +5 -0
  13. data/lib/generators/wcc/menu_generator.rb +4 -4
  14. data/lib/generators/wcc/templates/contentful_shell_wrapper +109 -68
  15. data/lib/generators/wcc/templates/menu/menu.rb +4 -6
  16. data/lib/generators/wcc/templates/menu/menu_button.rb +4 -6
  17. data/lib/generators/wcc/templates/release +2 -2
  18. data/lib/generators/wcc/templates/wcc_contentful.rb +0 -1
  19. data/lib/wcc/contentful/client_ext.rb +1 -1
  20. data/lib/wcc/contentful/configuration.rb +76 -35
  21. data/lib/wcc/contentful/engine.rb +13 -0
  22. data/lib/wcc/contentful/exceptions.rb +6 -0
  23. data/lib/wcc/contentful/graphql/builder.rb +8 -3
  24. data/lib/wcc/contentful/helpers.rb +6 -0
  25. data/lib/wcc/contentful/indexed_representation.rb +31 -0
  26. data/lib/wcc/contentful/model.rb +82 -1
  27. data/lib/wcc/contentful/model_builder.rb +18 -8
  28. data/lib/wcc/contentful/model_validators.rb +69 -18
  29. data/lib/wcc/contentful/simple_client/http_adapter.rb +15 -0
  30. data/lib/wcc/contentful/simple_client/typhoeus_adapter.rb +30 -0
  31. data/lib/wcc/contentful/simple_client.rb +67 -18
  32. data/lib/wcc/contentful/store/base.rb +89 -0
  33. data/lib/wcc/contentful/store/cdn_adapter.rb +13 -19
  34. data/lib/wcc/contentful/store/lazy_cache_store.rb +76 -0
  35. data/lib/wcc/contentful/store/memory_store.rb +17 -23
  36. data/lib/wcc/contentful/store/postgres_store.rb +32 -19
  37. data/lib/wcc/contentful/store.rb +62 -0
  38. data/lib/wcc/contentful/version.rb +1 -1
  39. data/lib/wcc/contentful.rb +113 -24
  40. data/wcc-contentful.gemspec +4 -0
  41. metadata +75 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5a48cb096dc5f511308f9ac747349bde4b79fe43
4
- data.tar.gz: 981ea6e61c9af9f2da0f9a590ec70f9563d0303b
3
+ metadata.gz: 00a9e00e55f441463939d98fd8b8542120976dc4
4
+ data.tar.gz: 5eac07eb53c3e3a8b943c56c072c2f0cde90afe0
5
5
  SHA512:
6
- metadata.gz: 05fdef20e3e9efce2dcda906059b815fa360a34caa7733d4b1cd6170ef31ab4ca3f0989517c05c5a0970aea0ec4aa08b8f1dfe625d452bbf354a468145a9fde3
7
- data.tar.gz: 52e05e8c6f6011f9c3387e5e721b3459d31b92547b49f8c944eba2aef4a78ab87542fd36e7b5dd8fad18b4420dbe2190a3e3d15cfef337e5c5b75d80f59d27c6
6
+ metadata.gz: a9bc2e68d9d4159a87284d8c90a7262539a057962682b605e608a602344e2d5aff2d3e1738961324175b93423c6fa82a221fca9b36277172d50c6a246e36eed9
7
+ data.tar.gz: d5458f48090f6a234d035e6cd4b0887ffeab7024ebff4502a49559d0f98c9e5a969bbfc7516d4b61d6067e68f74ada91b9bd389393ebb3c36b2b12f921ed0dd0
data/.circleci/config.yml CHANGED
@@ -6,7 +6,7 @@ jobs:
6
6
  environment:
7
7
  RAILS_ENV: test
8
8
  POSTGRES_CONNECTION: postgresql://ubuntu:@127.0.0.1:5432/circle_ruby_test
9
- - image: postgres:9.5
9
+ - image: postgres:10
10
10
  environment:
11
11
  - POSTGRES_USER: ubuntu
12
12
  - POSTGRES_DB: circle_ruby_test
data/.gitignore CHANGED
@@ -19,3 +19,8 @@ contentful-*-error-log-*
19
19
  # User local env
20
20
  .envrc
21
21
  .env*
22
+
23
+ node_modules
24
+
25
+ log/
26
+ tmp/
data/.rubocop.yml CHANGED
@@ -20,6 +20,9 @@ AllCops:
20
20
  - '**/templates/**/*'
21
21
  - 'tmp/**/*'
22
22
 
23
+ # dummy app for testing
24
+ - 'spec/dummy/**/*'
25
+
23
26
  Style/Documentation:
24
27
  Enabled: false
25
28
 
data/CHANGELOG.md CHANGED
@@ -16,4 +16,11 @@
16
16
 
17
17
  * Models are built dynamically from downloading the content_types via Contentful CDN
18
18
  * 'Menu' and 'MenuItem' are defined and their structures are enforced via validation
19
- * A GraphQL schema can optionally be generated to execute queries against Contentful
19
+ * A GraphQL schema can optionally be generated to execute queries against Contentful
20
+
21
+ # v0.2.0
22
+
23
+ * Application models can be registered to be instantiated for a given content type
24
+ * New 'lazy sync' delivery method acts as a cache that is kept up to date by the sync API
25
+ * 'eager sync' is now hooked up to a webhook which can be mounted to receive publish events
26
+ * Major changes to configuration methods
data/Guardfile CHANGED
@@ -11,13 +11,35 @@ group :red_green_refactor, halt_on_fail: true do
11
11
  # RSpec files
12
12
  rspec = dsl.rspec
13
13
  watch(rspec.spec_helper) { rspec.spec_dir }
14
- watch(rspec.spec_support) { rspec.spec_dir }
14
+ # watch(rspec.spec_support) { rspec.spec_dir }
15
15
  watch(rspec.spec_files)
16
16
 
17
17
  # Ruby files
18
18
  ruby = dsl.ruby
19
19
  watch(%r{lib/wcc/(.+)\.rb$}) { |m| rspec.spec.call("wcc/#{m[1]}") }
20
20
  watch(%r{lib/generators/(.+)\.rb$}) { |m| rspec.spec.call("generators/#{m[1]}") }
21
+
22
+ # Rails files
23
+ rails = dsl.rails(view_extensions: %w[erb haml slim])
24
+ dsl.watch_spec_files_for(rails.app_files)
25
+ dsl.watch_spec_files_for(rails.views)
26
+
27
+ watch(rails.controllers) do |m|
28
+ [
29
+ rspec.spec.call("routing/#{m[1]}_routing"),
30
+ rspec.spec.call("controllers/#{m[1]}_controller"),
31
+ rspec.spec.call("acceptance/#{m[1]}")
32
+ ]
33
+ end
34
+
35
+ # Rails config changes
36
+ watch(rails.spec_helper) { rspec.spec_dir }
37
+ watch(rails.routes) { "#{rspec.spec_dir}/routing" }
38
+ watch(rails.app_controller) { "#{rspec.spec_dir}/controllers" }
39
+
40
+ # Capybara features specs
41
+ watch(rails.view_dirs) { |m| rspec.spec.call("features/#{m[1]}") }
42
+ watch(rails.layouts) { |m| rspec.spec.call("features/#{m[1]}") }
21
43
  end
22
44
 
23
45
  guard :rubocop, cli: ['--display-cop-names'] do
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WCC::Contentful
4
+ class ApplicationController < ActionController::Base
5
+ protect_from_forgery with: :exception
6
+ end
7
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_dependency 'wcc/contentful/application_controller'
4
+
5
+ module WCC::Contentful
6
+ class WebhookController < ApplicationController
7
+ before_action :authorize_contentful
8
+
9
+ def receive
10
+ WCC::Contentful.sync!(up_to_id: params.dig('sys', 'id'))
11
+ end
12
+
13
+ def authorize_contentful
14
+ config = WCC::Contentful.configuration
15
+
16
+ if config.webhook_username.present? && config.webhook_password.present?
17
+ unless authenticate_with_http_basic do |u, p|
18
+ u == config.webhook_username &&
19
+ p == config.webhook_password
20
+ end
21
+ request_http_basic_authentication
22
+ return
23
+ end
24
+ end
25
+
26
+ return if request.content_type == 'application/vnd.contentful.management.v1+json'
27
+ render json: { msg: 'This endpoint only responds to webhooks from Contentful' }, status: 406
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_job'
4
+
5
+ module WCC::Contentful
6
+ class DelayedSyncJob < ActiveJob::Base
7
+ queue_as :default
8
+
9
+ def perform(*args)
10
+ sync_options = args.first || {}
11
+ WCC::Contentful.sync!(**sync_options)
12
+ end
13
+ end
14
+ end
data/bin/rails ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails gems
3
+ # installed from the root of your application.
4
+
5
+ ENGINE_ROOT = File.expand_path('../..', __FILE__)
6
+ ENGINE_PATH = File.expand_path('../../lib/wcc/contentful/engine', __FILE__)
7
+ APP_PATH = File.expand_path('../../spec/dummy/config/application', __FILE__)
8
+
9
+ # Set up gems listed in the Gemfile.
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
11
+ require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
12
+
13
+ require 'rails/all'
14
+ require 'rails/engine/commands'
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ Mime::Type.register 'application/vnd.contentful.management.v1+json', :json
data/config/routes.rb ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ WCC::Contentful::Engine.routes.draw do
4
+ post 'webhook/receive', to: 'webhook#receive'
5
+ end
@@ -17,7 +17,7 @@ module Wcc
17
17
  deps = package['dependencies']
18
18
 
19
19
  unless deps.try(:[], 'contentful-migration-cli').present?
20
- run 'npm install --save watermarkchurch/migration-cli'
20
+ run 'npm install --save watermarkchurch/migration-cli ts-node typescript'
21
21
  end
22
22
  end
23
23
  end
@@ -59,9 +59,9 @@ module Wcc
59
59
  copy_file 'wcc_contentful.rb', 'config/initializers/wcc_contentful.rb'
60
60
  end
61
61
 
62
- def drop_model_overrides_in_lib_dir
63
- copy_file 'menu/menu.rb', 'lib/wcc/contentful/model/menu.rb'
64
- copy_file 'menu/menu_button.rb', 'lib/wcc/contentful/model/menu_button.rb'
62
+ def drop_model_overrides_in_app_models
63
+ copy_file 'menu/menu.rb', 'app/models/menu.rb'
64
+ copy_file 'menu/menu_button.rb', 'app/models/menu_button.rb'
65
65
  end
66
66
  end
67
67
  end
@@ -8,13 +8,26 @@ COLOR_YELLOW='\033[1;33m'
8
8
  COLOR_LGREEN='\033[1;32m'
9
9
 
10
10
  logv() {
11
- ([[ ! -z "$VERBOSE" ]] && >&2 echo -e "${COLOR_GRAY}$@${COLOR_NC}") || true
11
+ [[ -z "$VERBOSE" ]] && return 0;
12
+
13
+ local msg=$(echo "$@" | sed "s/$CONTENTFUL_MANAGEMENT_TOKEN/\*\*\*\*\*/" )
14
+ >&2 echo -e "${COLOR_GRAY}$msg${COLOR_NC}" || true
12
15
  }
13
16
 
14
17
  logerr() {
15
18
  >&2 echo -e "${COLOR_RED}$@${COLOR_NC}"
16
19
  }
17
20
 
21
+ curlv() {
22
+ logv "curl" $@
23
+ curl "$@"
24
+ }
25
+
26
+ execv() {
27
+ logv "$@"
28
+ "$@"
29
+ }
30
+
18
31
  ## *** Argument Parsing & validation ***
19
32
 
20
33
  usage() {
@@ -41,10 +54,9 @@ usage() {
41
54
  restores a given backup file into the current space
42
55
  * [file] optional - default: the most recent backup file in the current directory
43
56
 
44
- restore_from -s [to space ID] <from space ID>
45
- restores all data from the given space into the current space
46
- * <space ID> required - the ID of the space to receive data from
47
- * -s [to space ID] optional - the current working space. Default: \$CONTENTFUL_SPACE_ID
57
+ new_env
58
+ deletes the current working environment if it exists and makes a new clone of 'master'.
59
+ * -e [to environment ID] optional - the current working environment. Default: \$USER
48
60
 
49
61
  generate [name]
50
62
  Creates a sample migration in the db/migrate directory
@@ -61,14 +73,14 @@ parse_args() {
61
73
  OPTIND=1
62
74
  local s=$(echo "$1" | tr '[:upper:]' '[:lower:]')
63
75
  case "$s" in
64
- migrate|setup|backup|export|restore|restore_from|import|generate|clean|help|h|\?)
76
+ migrate|setup|backup|export|restore|new_env|import|generate|clean|help|h|\?)
65
77
  export subcommand=$s
66
78
  OPTIND=2
67
79
  ;;
68
80
  esac
69
81
 
70
82
  # Parse flags
71
- while getopts ":hyvs:a:" arg; do
83
+ while getopts ":hyvse:a:" arg; do
72
84
  case $arg in
73
85
  y) # Yes - skip prompts
74
86
  export YES="-y"
@@ -79,6 +91,9 @@ parse_args() {
79
91
  a) # Contentful Mgmt Token - overrides env var CONTENTFUL_MANAGEMENT_TOKEN
80
92
  export CONTENTFUL_MANAGEMENT_TOKEN=$OPTARG
81
93
  ;;
94
+ e) # Contentful environment ID - overrides env var CONTENTFUL_ENVIRONMENT
95
+ export CONTENTFUL_ENVIRONMENT=$OPTARG
96
+ ;;
82
97
  v) # Verbose mode - extra output
83
98
  export VERBOSE=true
84
99
  ;;
@@ -106,8 +121,7 @@ require_environment() {
106
121
  [[ -z "$CONTENTFUL_MANAGEMENT_TOKEN" ]] && logerr "Please set CONTENTFUL_MANAGEMENT_TOKEN environment variable or use '-a' flag." && exit -1;
107
122
  if [[ ! -f node_modules/.bin/contentful-migration ]]; then
108
123
  command -v npm >/dev/null 2>&1 || (logerr "I require 'npm' but it's not installed. Please install nodejs."; exit -1)
109
- logv "npm install"
110
- npm install
124
+ execv npm install
111
125
  [[ -f node_modules/.bin/contentful-migration ]] || (logerr "Failed installing node modules - please ensure contentful CLI is installed"; exit -1)
112
126
  fi
113
127
  }
@@ -133,8 +147,20 @@ confirm() {
133
147
  }
134
148
 
135
149
  get_space_name() {
136
- logv "curl -s https://api.contentful.com/spaces/$1?access_token=****"
137
- curl -s https://api.contentful.com/spaces/$1?access_token=$CONTENTFUL_MANAGEMENT_TOKEN | jq -r .name | tr '[:upper:]' '[:lower:]'
150
+ curlv -s https://api.contentful.com/spaces/$1?access_token=$CONTENTFUL_MANAGEMENT_TOKEN | jq -r .name | tr '[:upper:]' '[:lower:]'
151
+ }
152
+
153
+ # Man I wish I understood sed... https://stackoverflow.com/a/29060802
154
+ # $1 File
155
+ # $2 Find
156
+ # $3 Replace / Append
157
+ replace_append() {
158
+ if grep -q "^$2" "$1"
159
+ then
160
+ sed -i.bak "s/^$2.*$/$3/" "$1"
161
+ else
162
+ echo "\n$3" >> "$1"
163
+ fi
138
164
  }
139
165
 
140
166
  set -e
@@ -150,14 +176,12 @@ migrate() {
150
176
 
151
177
  require_environment
152
178
 
153
- logv "contentful-migration -s $CONTENTFUL_SPACE_ID -a ***** $YES -p $ARG"
154
- node_modules/.bin/ts-node node_modules/.bin/contentful-migration \
179
+ execv node_modules/.bin/ts-node node_modules/.bin/contentful-migration \
155
180
  -s $CONTENTFUL_SPACE_ID -a $CONTENTFUL_MANAGEMENT_TOKEN \
156
181
  $YES -p $ARG
157
182
 
158
183
  mkdir -p db
159
- logv "contentful-export -s --export-dir db --content-file contentful-schema.json --space-id $CONTENTFUL_SPACE_ID --management-token ***** --query-entries 'content_type=migrationHistory' --query-assets 'sys.id=false'"
160
- node_modules/.bin/contentful-export --export-dir db --content-file contentful-schema.json \
184
+ execv node_modules/.bin/contentful-export --export-dir db --content-file contentful-schema.json \
161
185
  --space-id $CONTENTFUL_SPACE_ID --management-token $CONTENTFUL_MANAGEMENT_TOKEN \
162
186
  --query-entries 'content_type=migrationHistory' \
163
187
  --query-assets 'sys.id=false'
@@ -177,9 +201,10 @@ backup() {
177
201
 
178
202
  require_environment
179
203
 
180
- logv "contentful-export $FILE --space-id $CONTENTFUL_SPACE_ID --management-token ***** $@"
181
- node_modules/.bin/contentful-export $FILE \
182
- --space-id $CONTENTFUL_SPACE_ID --management-token $CONTENTFUL_MANAGEMENT_TOKEN \
204
+ [[ ! -z "$CONTENTFUL_ENVIRONMENT" ]] && ENV="--environment-id $CONTENTFUL_ENVIRONMENT"
205
+
206
+ execv node_modules/.bin/contentful-export $FILE \
207
+ --space-id $CONTENTFUL_SPACE_ID $ENV --management-token $CONTENTFUL_MANAGEMENT_TOKEN \
183
208
  $@
184
209
  }
185
210
 
@@ -192,13 +217,17 @@ restore() {
192
217
  [[ -z "$FILE" ]] && logerr "No file given on command line" && exit -1
193
218
  fi
194
219
 
195
- confirm "Import $FILE into $CONTENTFUL_SPACE_ID?" || exit -1
220
+ name=$(get_space_name $CONTENTFUL_SPACE_ID)
221
+ if [[ ! -z "$CONTENTFUL_ENVIRONMENT" ]]; then
222
+ ENV="--environment-id $CONTENTFUL_ENVIRONMENT"
223
+ name="$name/$CONTENTFUL_ENVIRONMENT"
224
+ fi
225
+ confirm "Import $FILE into $name?" || exit -1
196
226
 
197
227
  require_environment
198
228
 
199
- logv "contentful-import --space-id $CONTENTFUL_SPACE_ID --management-token ***** --content-file $FILE"
200
- node_modules/.bin/contentful-import \
201
- --space-id $CONTENTFUL_SPACE_ID --management-token $CONTENTFUL_MANAGEMENT_TOKEN \
229
+ execv node_modules/.bin/contentful-import \
230
+ --space-id $CONTENTFUL_SPACE_ID $ENV --management-token $CONTENTFUL_MANAGEMENT_TOKEN \
202
231
  --content-file $FILE
203
232
  }
204
233
 
@@ -208,13 +237,18 @@ setup() {
208
237
  FILE="$1"
209
238
  [[ -z "$FILE" ]] && FILE=db/contentful-schema.json
210
239
 
211
- confirm "Initialize space $CONTENTFUL_SPACE_ID from seed file $FILE?" || exit -1
240
+ name=$(get_space_name $CONTENTFUL_SPACE_ID)
241
+ if [[ ! -z "$CONTENTFUL_ENVIRONMENT" ]]; then
242
+ ENV="--environment-id $CONTENTFUL_ENVIRONMENT"
243
+ name="$name/$CONTENTFUL_ENVIRONMENT"
244
+ fi
245
+
246
+ confirm "Initialize space $name from seed file $FILE?" || exit -1
212
247
 
213
248
  require_environment
214
249
 
215
- logv "contentful-import --space-id $CONTENTFUL_SPACE_ID --management-token ***** --content-file $FILE"
216
- node_modules/.bin/contentful-import \
217
- --space-id $CONTENTFUL_SPACE_ID --management-token $CONTENTFUL_MANAGEMENT_TOKEN \
250
+ execv node_modules/.bin/contentful-import \
251
+ --space-id $CONTENTFUL_SPACE_ID $ENV --management-token $CONTENTFUL_MANAGEMENT_TOKEN \
218
252
  --content-file $FILE
219
253
 
220
254
  migrate
@@ -226,60 +260,67 @@ clean() {
226
260
 
227
261
  require_environment
228
262
 
263
+ [[ -z "$CONTENTFUL_ENVIRONMENT" ]] && CONTENTFUL_ENVIRONMENT="$USER"
264
+ [[ "$CONTENTFUL_ENVIRONMENT" == "master" ]] && logerr "cannot delete the master environment" && exit -1
265
+
229
266
  name=$(get_space_name $CONTENTFUL_SPACE_ID)
267
+ code=$(curlv -s -o /dev/null -w "%{http_code}" https://api.contentful.com/spaces/$CONTENTFUL_SPACE_ID/environments/$CONTENTFUL_ENVIRONMENT\?access_token\=$CONTENTFUL_MANAGEMENT_TOKEN)
268
+ [[ $code == "404" ]] && logerr "$CONTENTFUL_ENVIRONMENT does not exist in $name" && return 0;
230
269
 
231
- confirm "This will delete all data and content types from $name. Are you sure?" || exit -1
232
- [[ "$name" != *staging ]] && [[ "$name" != *test ]] && confirm "$name is not a staging or test environment! Are you really sure?" dangerous!
233
-
234
- local bkup_file="contentful-export-$CONTENTFUL_SPACE_ID-`date +"%Y-%m-%dT%H-%M-%S"`.json"
270
+ confirm "This will delete the '$CONTENTFUL_ENVIRONMENT' environment from $name. Are you sure?" || exit -1
271
+
272
+ local bkup_file="contentful-export-$CONTENTFUL_SPACE_ID-${CONTENTFUL_ENVIRONMENT}-`date +"%Y-%m-%dT%H-%M-%S"`.json"
235
273
  backup $bkup_file
236
- content_types=$(cat $bkup_file | jq -r '.contentTypes[].sys.id')
237
- entries=$(cat $bkup_file | jq -r '.entries[].sys.id')
238
- assets=$(cat $bkup_file | jq -r '.assets[].sys.id')
239
-
240
- delete() {
241
- logv "curl -XDELETE https://api.contentful.com/spaces/$CONTENTFUL_SPACE_ID/$1/$2/published\?access_token\=*****"
242
- curl -s --fail -XDELETE https://api.contentful.com/spaces/$CONTENTFUL_SPACE_ID/$1/$2/published\?access_token\=$CONTENTFUL_MANAGEMENT_TOKEN > /dev/null
243
- logv "curl -XDELETE https://api.contentful.com/spaces/$CONTENTFUL_SPACE_ID/$1/$2\?access_token\=*****"
244
- curl -s --fail -XDELETE https://api.contentful.com/spaces/$CONTENTFUL_SPACE_ID/$1/$2\?access_token\=$CONTENTFUL_MANAGEMENT_TOKEN > /dev/null
245
- }
246
-
247
- [[ ! -z "$assets" ]] && while read -r id; do delete 'assets' $id; done <<< "${assets}"
248
- [[ ! -z "$entries" ]] && while read -r id; do delete 'entries' $id; done <<< "${entries}"
249
- [[ ! -z "$content_types" ]] && while read -r id; do delete 'content_types' $id; done <<< "${content_types}"
250
-
251
- echo -e "${COLOR_LGREEN}All content deleted - prior content saved at${COLOR_NC} $bkup_file"
252
- [[ "$1" == "no-init" ]] || (setup || logerr "Error setting up space $name!")
274
+
275
+ curlv --fail -XDELETE https://api.contentful.com/spaces/$CONTENTFUL_SPACE_ID/environments/$CONTENTFUL_ENVIRONMENT\?access_token\=$CONTENTFUL_MANAGEMENT_TOKEN
253
276
  }
254
277
 
255
- # Example: bin/contentful restore_from -s $staging_space_id -a $MY_TOKEN $production_space_id
256
- restore_from() {
278
+ # Example: bin/contentful new_env -e gordon_dev
279
+ new_env() {
257
280
  command -v jq >/dev/null 2>&1 || (logerr "I require 'jq' but it's not installed. Please run 'brew install jq'"; exit -1)
258
281
 
259
282
  require_environment
283
+ name=$(get_space_name $CONTENTFUL_SPACE_ID)
284
+ [[ -z "$CONTENTFUL_ENVIRONMENT" ]] && CONTENTFUL_ENVIRONMENT="$USER"
285
+ [[ "$CONTENTFUL_ENVIRONMENT" == "master" ]] && logerr "cannot delete the master environment" && exit -1
260
286
 
261
- from_space_id=$1
262
- [[ -z "$from_space_id" ]] && logerr "Please provide the space ID from which to restore data" && exit -1
263
- to_space_id=$CONTENTFUL_SPACE_ID
264
-
265
- from_name=$(get_space_name $from_space_id)
266
- to_name=$(get_space_name $CONTENTFUL_SPACE_ID)
267
-
268
- echo -e "${COLOR_LCYAN}This will backup all data from $from_name, delete all data in $to_name, and then write the $from_name data over it.${COLOR_NC}"
287
+ echo -e "${COLOR_LCYAN}This will delete '$CONTENTFUL_ENVIRONMENT' and recreate it from master.${COLOR_NC}"
269
288
  confirm "Continue?" || exit -1
270
289
  export YES='-y' # don't keep bugging the user
271
290
 
272
- export CONTENTFUL_SPACE_ID=$from_space_id
273
- local bkup_file="contentful-export-$from_space_id-`date +"%Y-%m-%dT%H-%M-%S"`.json"
274
- logv "bin/contentful backup -s $CONTENTFUL_SPACE_ID $bkup_file"
275
- backup $bkup_file --skip-roles --skip-webhooks
291
+ clean
292
+
293
+ # make the environment
294
+ resp=$(curlv -s --fail -XPUT https://api.contentful.com/spaces/$CONTENTFUL_SPACE_ID/environments/$CONTENTFUL_ENVIRONMENT \
295
+ -H "Authorization: Bearer ${CONTENTFUL_MANAGEMENT_TOKEN}" \
296
+ -H "Content-Type: application/vnd.contentful.management.v1+json" \
297
+ -d "{ \"name\": \"${CONTENTFUL_ENVIRONMENT}\" }")
298
+
299
+ while [ ! $(echo "$resp" | jq -r .sys.status.sys.id) == "ready" ]
300
+ do
301
+ logv "waiting for environment $CONTENTFUL_ENVIRONMENT to be ready..."
302
+ sleep 1
303
+ resp=$(curlv -s https://api.contentful.com/spaces/$CONTENTFUL_SPACE_ID/environments/$CONTENTFUL_ENVIRONMENT \
304
+ -H "Authorization: Bearer ${CONTENTFUL_MANAGEMENT_TOKEN}")
305
+ done
306
+
307
+ logv "get the API keys and update the one matching ours to point to the new environment"
308
+ keys=$(curlv -s --fail https://api.contentful.com/spaces/$CONTENTFUL_SPACE_ID/api_keys\?access_token\=$CONTENTFUL_MANAGEMENT_TOKEN)
309
+ my_key=$(echo "$keys" | jq -r ".items[] | select(.accessToken == \"$CONTENTFUL_ACCESS_TOKEN\")")
310
+ my_key_id=$(echo "$my_key" | jq -r ".sys.id")
311
+ my_key_version=$(echo "$my_key" | jq -r ".sys.version")
312
+ new_env_links=$(echo "$my_key" | jq ".environments + [{ \"sys\": { \"id\": \"$CONTENTFUL_ENVIRONMENT\", \"type\": \"Link\", \"linkType\": \"Environment\" } }] | { \"environments\": . }")
313
+
314
+ curlv -s -o /dev/null --fail -XPUT https://api.contentful.com/spaces/$CONTENTFUL_SPACE_ID/api_keys/$my_key_id \
315
+ -H "Authorization: Bearer ${CONTENTFUL_MANAGEMENT_TOKEN}" \
316
+ -H "Content-Type: application/vnd.contentful.management.v1+json" \
317
+ -H "X-Contentful-Version: ${my_key_version}" \
318
+ -d "${new_env_links}"
276
319
 
277
- export CONTENTFUL_SPACE_ID=$to_space_id
278
- logv "bin/contentful clean -s $CONTENTFUL_SPACE_ID"
279
- clean no-init
320
+ execv replace_append .env.local "CONTENTFUL_ENVIRONMENT\=" "CONTENTFUL_ENVIRONMENT=$CONTENTFUL_ENVIRONMENT"
321
+ execv replace_append .env.test.local "CONTENTFUL_ENVIRONMENT\=" "CONTENTFUL_ENVIRONMENT=$CONTENTFUL_ENVIRONMENT"
280
322
 
281
- logv "bin/contentful restore -s $CONTENTFUL_SPACE_ID $bkup_file"
282
- restore $bkup_file
323
+ echo "Environment ${CONTENTFUL_ENVIRONMENT} successfully created!"
283
324
  }
284
325
 
285
326
  # Example: bin/contentful generate add content type dog
@@ -328,8 +369,8 @@ case $subcommand in
328
369
  clean)
329
370
  clean $@
330
371
  ;;
331
- restore_from)
332
- restore_from $@
372
+ new_env)
373
+ new_env $@
333
374
  ;;
334
375
  help|h|\?)
335
376
  usage
@@ -1,11 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # This file reopens the "Menu" class which was dynamically
4
- # created by the WCC::Contentful gem. This class does not need to do anything,
5
- # the attributes have already been defined based on the `content_type` returned
6
- # from the Contentful API. However you can reopen the class to add functionality.
7
- class WCC::Contentful::Model::Menu < WCC::Contentful::Model
8
-
3
+ # This model represents the 'menu' content type in Contentful. Any linked
4
+ # entries of the 'menu' content type will be resolved as instances of this class.
5
+ # It exposes #find, #find_by, and #find_all methods to query Contentful.
6
+ class Menu < WCC::Contentful::Model::Menu
9
7
  # Add custom validations to ensure that app-specific properties exist:
10
8
  # validate_field :foo, :String, :required
11
9
  # validate_field :bar_links, :Array, link_to: %w[bar baz]
@@ -1,11 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # This file reopens the "MenuButton" class which was dynamically
4
- # created by the WCC::Contentful gem. This class does not need to do anything,
5
- # the attributes have already been defined based on the `content_type` returned
6
- # from the Contentful API. However you can reopen the class to add functionality.
7
- class WCC::Contentful::Model::MenuButton < WCC::Contentful::Model
8
-
3
+ # This model represents the 'menuButton' content type in Contentful. Any linked
4
+ # entries of the 'menuButton' content type will be resolved as instances of this class.
5
+ # It exposes #find, #find_by, and #find_all methods to query Contentful.
6
+ class MenuButton < WCC::Contentful::Model::MenuButton
9
7
  # Add custom validations to ensure that app-specific properties exist:
10
8
  # validate_field :foo, :String, :required
11
9
  # validate_field :bar_links, :Array, link_to: %w[bar baz]
@@ -1,4 +1,4 @@
1
- #!/bin/bash
1
+ #!/bin/sh
2
2
 
3
3
  set -e
4
4
 
@@ -6,4 +6,4 @@ echo "Migrating database..."
6
6
  bundle exec rake db:migrate
7
7
 
8
8
  DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
9
- $DIR/contentful migrate -y
9
+ $DIR/contentful migrate -y
@@ -8,7 +8,6 @@ WCC::Contentful.configure do |config|
8
8
  config.management_token = # Contentful API management token
9
9
  config.default_locale = # Set default locale, if left blank this is 'en-US'
10
10
  config.content_delivery = # :direct, :eager_sync, or :lazy_sync
11
- config.sync_store = # :memory, :postgres, or a custom implementation
12
11
  end
13
12
 
14
13
  # Download content types, build models, and sync content
@@ -6,7 +6,7 @@ class Contentful::Client
6
6
  end
7
7
 
8
8
  def self.get_http(url, query, headers = {}, proxy = {})
9
- if override = WCC::Contentful.configuration.override_get_http
9
+ if override = WCC::Contentful.configuration.http_adapter
10
10
  override.call(url, query, headers, proxy)
11
11
  else
12
12
  old_get_http(url, query, headers, proxy)