wcc-contentful 0.2.2 → 0.3.0.pre.rc

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +0 -1
  3. data/README.md +181 -8
  4. data/app/controllers/wcc/contentful/webhook_controller.rb +42 -2
  5. data/app/jobs/wcc/contentful/delayed_sync_job.rb +52 -3
  6. data/app/jobs/wcc/contentful/webhook_enable_job.rb +43 -0
  7. data/bin/console +4 -3
  8. data/bin/rails +2 -0
  9. data/config/initializers/mime_types.rb +10 -1
  10. data/lib/wcc/contentful.rb +14 -142
  11. data/lib/wcc/contentful/client_ext.rb +17 -4
  12. data/lib/wcc/contentful/configuration.rb +25 -84
  13. data/lib/wcc/contentful/engine.rb +19 -0
  14. data/lib/wcc/contentful/exceptions.rb +25 -28
  15. data/lib/wcc/contentful/graphql.rb +0 -1
  16. data/lib/wcc/contentful/graphql/types.rb +1 -1
  17. data/lib/wcc/contentful/helpers.rb +3 -2
  18. data/lib/wcc/contentful/indexed_representation.rb +6 -0
  19. data/lib/wcc/contentful/model.rb +68 -34
  20. data/lib/wcc/contentful/model_builder.rb +65 -67
  21. data/lib/wcc/contentful/model_methods.rb +189 -0
  22. data/lib/wcc/contentful/model_singleton_methods.rb +83 -0
  23. data/lib/wcc/contentful/services.rb +146 -0
  24. data/lib/wcc/contentful/simple_client.rb +35 -33
  25. data/lib/wcc/contentful/simple_client/http_adapter.rb +9 -0
  26. data/lib/wcc/contentful/simple_client/management.rb +81 -0
  27. data/lib/wcc/contentful/simple_client/response.rb +61 -37
  28. data/lib/wcc/contentful/simple_client/typhoeus_adapter.rb +12 -0
  29. data/lib/wcc/contentful/store.rb +45 -18
  30. data/lib/wcc/contentful/store/base.rb +128 -8
  31. data/lib/wcc/contentful/store/cdn_adapter.rb +92 -22
  32. data/lib/wcc/contentful/store/lazy_cache_store.rb +94 -9
  33. data/lib/wcc/contentful/store/memory_store.rb +13 -8
  34. data/lib/wcc/contentful/store/postgres_store.rb +44 -11
  35. data/lib/wcc/contentful/sys.rb +28 -0
  36. data/lib/wcc/contentful/version.rb +1 -1
  37. data/wcc-contentful.gemspec +3 -9
  38. metadata +87 -107
  39. data/.circleci/config.yml +0 -51
  40. data/.gitignore +0 -26
  41. data/.rubocop.yml +0 -243
  42. data/.rubocop_todo.yml +0 -13
  43. data/.travis.yml +0 -5
  44. data/CHANGELOG.md +0 -45
  45. data/CODE_OF_CONDUCT.md +0 -74
  46. data/Guardfile +0 -58
  47. data/LICENSE.txt +0 -21
  48. data/Rakefile +0 -8
  49. data/lib/generators/wcc/USAGE +0 -24
  50. data/lib/generators/wcc/model_generator.rb +0 -90
  51. data/lib/generators/wcc/templates/.keep +0 -0
  52. data/lib/generators/wcc/templates/Procfile +0 -3
  53. data/lib/generators/wcc/templates/contentful_shell_wrapper +0 -385
  54. data/lib/generators/wcc/templates/menu/generated_add_menus.ts +0 -90
  55. data/lib/generators/wcc/templates/menu/models/menu.rb +0 -23
  56. data/lib/generators/wcc/templates/menu/models/menu_button.rb +0 -23
  57. data/lib/generators/wcc/templates/page/generated_add_pages.ts +0 -50
  58. data/lib/generators/wcc/templates/page/models/page.rb +0 -23
  59. data/lib/generators/wcc/templates/release +0 -9
  60. data/lib/generators/wcc/templates/wcc_contentful.rb +0 -17
  61. data/lib/wcc/contentful/model/menu.rb +0 -7
  62. data/lib/wcc/contentful/model/menu_button.rb +0 -15
  63. data/lib/wcc/contentful/model/page.rb +0 -8
  64. data/lib/wcc/contentful/model/redirect.rb +0 -19
  65. data/lib/wcc/contentful/model_validators.rb +0 -115
  66. data/lib/wcc/contentful/model_validators/dsl.rb +0 -165
data/.rubocop_todo.yml DELETED
@@ -1,13 +0,0 @@
1
- # This configuration was generated by
2
- # `rubocop --auto-gen-config`
3
- # on 2018-02-23 09:06:45 -0600 using RuboCop version 0.52.1.
4
- # The point is for the user to remove these configuration records
5
- # one by one as the offenses are removed from the code base.
6
- # Note that changes in the inspected code, or installation of new
7
- # versions of RuboCop, may require this file to be generated again.
8
-
9
- # Offense count: 49
10
- # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
11
- # URISchemes: http, https
12
- Metrics/LineLength:
13
- Max: 105
data/.travis.yml DELETED
@@ -1,5 +0,0 @@
1
- sudo: false
2
- language: ruby
3
- rvm:
4
- - 2.4.1
5
- before_install: gem install bundler -v 1.16.1
data/CHANGELOG.md DELETED
@@ -1,45 +0,0 @@
1
- ## v0.0.1
2
-
3
- * initial release
4
-
5
- ## v0.0.2
6
-
7
- * Will now return nil if the Redirect model's pageReference does not include a url
8
- * Add test coverage for the Configuration class
9
- * Add tests for the valid_page_reference? method
10
-
11
- ## v0.0.3
12
-
13
- * Can now fetch Redirect models via slug, regardless of slug lettercase (uppercase or lowercase).
14
-
15
- # v0.1.0
16
-
17
- * Models are built dynamically from downloading the content_types via Contentful CDN
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
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
27
-
28
- # v0.2.2
29
-
30
- * Add preview_client for doing contentful calls to their preview api
31
- * 'find_by' can now receive a preview param set to a boolean value
32
- * Can configure your preview_api by passing a preview_token to configure block
33
- * The Redirect model provides a 'href' method that will give you the url it points to
34
-
35
- # v0.3.0
36
-
37
- * Now neccesary to require the engine in a Gemfile when using in Rails:
38
-
39
- `gem 'wcc-contentful', require: 'wcc/contentful/rails'`
40
-
41
- * The gem can be configured to point to a non-master environment with the following configuration parameter:
42
-
43
- `config.environment = 'my_environment'`
44
-
45
- * When a model is not found in contentful, `Model.find_by` returns `nil` rather than raising an error.
data/CODE_OF_CONDUCT.md DELETED
@@ -1,74 +0,0 @@
1
- # Contributor Covenant Code of Conduct
2
-
3
- ## Our Pledge
4
-
5
- In the interest of fostering an open and welcoming environment, we as
6
- contributors and maintainers pledge to making participation in our project and
7
- our community a harassment-free experience for everyone, regardless of age, body
8
- size, disability, ethnicity, gender identity and expression, level of experience,
9
- nationality, personal appearance, race, religion, or sexual identity and
10
- orientation.
11
-
12
- ## Our Standards
13
-
14
- Examples of behavior that contributes to creating a positive environment
15
- include:
16
-
17
- * Using welcoming and inclusive language
18
- * Being respectful of differing viewpoints and experiences
19
- * Gracefully accepting constructive criticism
20
- * Focusing on what is best for the community
21
- * Showing empathy towards other community members
22
-
23
- Examples of unacceptable behavior by participants include:
24
-
25
- * The use of sexualized language or imagery and unwelcome sexual attention or
26
- advances
27
- * Trolling, insulting/derogatory comments, and personal or political attacks
28
- * Public or private harassment
29
- * Publishing others' private information, such as a physical or electronic
30
- address, without explicit permission
31
- * Other conduct which could reasonably be considered inappropriate in a
32
- professional setting
33
-
34
- ## Our Responsibilities
35
-
36
- Project maintainers are responsible for clarifying the standards of acceptable
37
- behavior and are expected to take appropriate and fair corrective action in
38
- response to any instances of unacceptable behavior.
39
-
40
- Project maintainers have the right and responsibility to remove, edit, or
41
- reject comments, commits, code, wiki edits, issues, and other contributions
42
- that are not aligned to this Code of Conduct, or to ban temporarily or
43
- permanently any contributor for other behaviors that they deem inappropriate,
44
- threatening, offensive, or harmful.
45
-
46
- ## Scope
47
-
48
- This Code of Conduct applies both within project spaces and in public spaces
49
- when an individual is representing the project or its community. Examples of
50
- representing a project or community include using an official project e-mail
51
- address, posting via an official social media account, or acting as an appointed
52
- representative at an online or offline event. Representation of a project may be
53
- further defined and clarified by project maintainers.
54
-
55
- ## Enforcement
56
-
57
- Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
- reported by contacting the project team at glyde06@hotmail.com. All
59
- complaints will be reviewed and investigated and will result in a response that
60
- is deemed necessary and appropriate to the circumstances. The project team is
61
- obligated to maintain confidentiality with regard to the reporter of an incident.
62
- Further details of specific enforcement policies may be posted separately.
63
-
64
- Project maintainers who do not follow or enforce the Code of Conduct in good
65
- faith may face temporary or permanent repercussions as determined by other
66
- members of the project's leadership.
67
-
68
- ## Attribution
69
-
70
- This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
- available at [http://contributor-covenant.org/version/1/4][version]
72
-
73
- [homepage]: http://contributor-covenant.org
74
- [version]: http://contributor-covenant.org/version/1/4/
data/Guardfile DELETED
@@ -1,58 +0,0 @@
1
- # A guardfile for making Danger Plugins
2
- # For more info see https://github.com/guard/guard#readme
3
-
4
- # To run, use `bundle exec guard`.
5
-
6
- group :red_green_refactor, halt_on_fail: true do
7
- guard :rspec, cmd: 'bundle exec rspec' do
8
- require 'guard/rspec/dsl'
9
- dsl = Guard::RSpec::Dsl.new(self)
10
-
11
- # RSpec files
12
- rspec = dsl.rspec
13
- watch(rspec.spec_helper) { rspec.spec_dir }
14
- # watch(rspec.spec_support) { rspec.spec_dir }
15
- watch(rspec.spec_files)
16
-
17
- # Ruby files
18
- ruby = dsl.ruby
19
- watch(%r{lib/wcc/(.+)\.rb$}) { |m| rspec.spec.call("wcc/#{m[1]}") }
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]}") }
43
- end
44
-
45
- guard :rubocop, cli: ['--display-cop-names'] do
46
- watch(%r{.+\.rb$})
47
- watch(%r{(?:.+/)?\.rubocop(?:_todo)?\.yml$}) { |m| File.dirname(m[0]) }
48
- end
49
- end
50
-
51
- group :autofix do
52
- guard :rubocop, all_on_start: false, cli: ['--auto-correct', '--display-cop-names'] do
53
- watch(%r{.+\.rb$})
54
- watch(%r{(?:.+/)?\.rubocop(?:_todo)?\.yml$}) { |m| File.dirname(m[0]) }
55
- end
56
- end
57
-
58
- scope group: :red_green_refactor
data/LICENSE.txt DELETED
@@ -1,21 +0,0 @@
1
- The MIT License (MIT)
2
-
3
- Copyright (c) 2018 jeremy perez
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in
13
- all copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- THE SOFTWARE.
data/Rakefile DELETED
@@ -1,8 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'bundler/gem_tasks'
4
- require 'rspec/core/rake_task'
5
-
6
- RSpec::Core::RakeTask.new(:spec)
7
-
8
- task default: :spec
@@ -1,24 +0,0 @@
1
- Description:
2
- Generates the necessary migrations and initializers to add WCC Menus
3
- to your contentful space.
4
-
5
- Example:
6
- rails generate wcc:model MODEL
7
-
8
- This will install:
9
- https://www.github.com/watermarkchurch/migration-cli
10
-
11
- This will create:
12
- db/migrate/[date]_generated_add_[MODEL].ts -
13
- this migration is run by the migration CLI to create MODEL in your
14
- contentful space
15
- bin/release -
16
- Adds a release command to your rails app which runs migrations.
17
- bin/contentful -
18
- This bash script is a wrapper around various Contentful CLI tools, and
19
- is invoked by bin/release to run migrations
20
- Procfile -
21
- Adds a release command to be invoked by Heroku which runs the script
22
- in bin/release
23
- config/initializers/wcc_contentful.rb -
24
- This file will initialize the wcc_contentful gem with default options
@@ -1,90 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Wcc
4
- class ModelGenerator < Rails::Generators::Base
5
- source_root File.expand_path('templates', __dir__)
6
- argument :model, type: :string
7
-
8
- VALID_MODELS = %w[menu page].freeze
9
-
10
- def initialize(*)
11
- super
12
-
13
- return if VALID_MODELS.include?(singular)
14
-
15
- raise ArgumentError, "Model must be #{VALID_MODELS.to_sentence}"
16
- end
17
-
18
- def ensure_migration_tools_installed
19
- in_root do
20
- run 'npm init -y' unless File.exist?('package.json')
21
- package = JSON.parse(File.read('package.json'))
22
- deps = package['dependencies']
23
-
24
- unless deps.try(:[], 'contentful-migration-cli').present?
25
- run 'npm install --save watermarkchurch/migration-cli ts-node typescript contentful-export'
26
- end
27
- end
28
- end
29
-
30
- def ensure_wrapper_script_in_bin_dir
31
- unless inside('bin') { File.exist?('contentful') }
32
- copy_file 'contentful_shell_wrapper', 'bin/contentful'
33
- end
34
-
35
- if inside('bin') { File.exist?('release') }
36
- release = inside('bin') { File.read('release') }
37
- unless release.include?('contentful migrate')
38
- insert_into_file('bin/release', after: 'bundle exec rake db:migrate') do
39
- <<~HEREDOC
40
- DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
41
- $DIR/contentful migrate -y
42
- HEREDOC
43
- end
44
- end
45
- else
46
- copy_file 'release', 'bin/release'
47
- end
48
-
49
- if in_root { File.exist?('Procfile') }
50
- procfile = in_root { File.read('Procfile') }
51
- unless procfile.include?('release:')
52
- insert_into_file('Procfile') do
53
- 'release: bin/release'
54
- end
55
- end
56
- else
57
- copy_file 'Procfile'
58
- end
59
- end
60
-
61
- def ensure_initializer_exists
62
- return if inside('config/initializers') { File.exist?('wcc_contentful.rb') }
63
-
64
- copy_file 'wcc_contentful.rb', 'config/initializers/wcc_contentful.rb'
65
- end
66
-
67
- def create_model_migration
68
- copy_file "#{singular}/generated_add_#{plural}.ts",
69
- "db/migrate/#{timestamp}01_generated_add_#{plural}.ts"
70
- end
71
-
72
- def drop_model_overrides_in_app_models
73
- directory "#{singular}/models", 'app/models'
74
- end
75
-
76
- private
77
-
78
- def singular
79
- model.downcase.singularize
80
- end
81
-
82
- def plural
83
- model.downcase.pluralize
84
- end
85
-
86
- def timestamp
87
- Time.now.strftime('%Y%m%d%H%M')
88
- end
89
- end
90
- end
File without changes
@@ -1,3 +0,0 @@
1
- web: bundle exec puma -C config/puma.rb
2
- worker: bundle exec sidekiq
3
- release: bin/release
@@ -1,385 +0,0 @@
1
- #!/bin/bash
2
-
3
- COLOR_NC='\033[0m' # No Color
4
- COLOR_GRAY='\033[1;30m'
5
- COLOR_RED='\033[0;31m'
6
- COLOR_LCYAN='\033[1;36m'
7
- COLOR_YELLOW='\033[1;33m'
8
- COLOR_LGREEN='\033[1;32m'
9
-
10
- logv() {
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
15
- }
16
-
17
- logerr() {
18
- >&2 echo -e "${COLOR_RED}$@${COLOR_NC}"
19
- }
20
-
21
- curlv() {
22
- logv "curl" $@
23
- curl "$@"
24
- }
25
-
26
- execv() {
27
- logv "$@"
28
- "$@"
29
- }
30
-
31
- ## *** Argument Parsing & validation ***
32
-
33
- usage() {
34
- echo "$0 <command> [opts]
35
- Commands:
36
- migrate [dir|file]
37
- runs pending migration files in the given directory
38
- * [dir|file] optional - Default: db/migrate
39
-
40
- setup [file]
41
- initializes a space with bare-minimum schema and seeds
42
- * [file] optional - default: db/contentful-schema.json
43
-
44
- backup [file]
45
- downloads a backup of the current space to the given file
46
- * [file] optional - default: timestamped file in current directory
47
-
48
- clean [no-init]
49
- Deletes all data in a given space and optionally sets it up again
50
- using 'bin/contentful setup'.
51
- * [no-init] optional - Skips the 'setup' step at the end.
52
-
53
- restore [file]
54
- restores a given backup file into the current space
55
- * [file] optional - default: the most recent backup file in the current directory
56
-
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
60
-
61
- generate [name]
62
- Creates a sample migration in the db/migrate directory
63
- * [name] optional - default: 'contentful_migration'
64
-
65
- Flags:" && \
66
- grep " .)\ #" $0
67
- echo "
68
- Examples:" && \
69
- grep -i "#\ example:" $0 | awk '{$1=""; $2=""; print " "$0}'
70
- }
71
-
72
- parse_args() {
73
- OPTIND=1
74
- local s=$(echo "$1" | tr '[:upper:]' '[:lower:]')
75
- case "$s" in
76
- migrate|setup|backup|export|restore|new_env|import|generate|clean|help|h|\?)
77
- export subcommand=$s
78
- OPTIND=2
79
- ;;
80
- esac
81
-
82
- # Parse flags
83
- while getopts ":hyvse:a:" arg; do
84
- case $arg in
85
- y) # Yes - skip prompts
86
- export YES="-y"
87
- ;;
88
- s) # Contentful Space ID - overrides env var CONTENTFUL_SPACE_ID
89
- export CONTENTFUL_SPACE_ID=$OPTARG
90
- ;;
91
- a) # Contentful Mgmt Token - overrides env var CONTENTFUL_MANAGEMENT_TOKEN
92
- export CONTENTFUL_MANAGEMENT_TOKEN=$OPTARG
93
- ;;
94
- e) # Contentful environment ID - overrides env var CONTENTFUL_ENVIRONMENT
95
- export CONTENTFUL_ENVIRONMENT=$OPTARG
96
- ;;
97
- v) # Verbose mode - extra output
98
- export VERBOSE=true
99
- ;;
100
- h) # Display help.
101
- usage
102
- exit 0
103
- ;;
104
- *)
105
- logerr "Unknown option: '$OPTARG'"
106
- usage
107
- exit -1
108
- ;;
109
- esac
110
- done
111
-
112
- export OPTIND
113
- }
114
-
115
- parse_args $@ && shift $(($OPTIND - 1))
116
- # If they put args before the command like 'bin/contentful -s 1xab migrate -y', try parsing again
117
- [[ -z "$subcommand" ]] && parse_args $@ && shift $(($OPTIND - 1))
118
-
119
- require_environment() {
120
- [[ -z "$CONTENTFUL_SPACE_ID" ]] && logerr "Please set CONTENTFUL_SPACE_ID environment variable or use '-s' flag." && exit -1;
121
- [[ -z "$CONTENTFUL_MANAGEMENT_TOKEN" ]] && logerr "Please set CONTENTFUL_MANAGEMENT_TOKEN environment variable or use '-a' flag." && exit -1;
122
- if [[ ! -f node_modules/.bin/contentful-migration ]]; then
123
- command -v npm >/dev/null 2>&1 || (logerr "I require 'npm' but it's not installed. Please install nodejs."; exit -1)
124
- execv npm install
125
- [[ -f node_modules/.bin/contentful-migration ]] || (logerr "Failed installing node modules - please ensure contentful CLI is installed"; exit -1)
126
- fi
127
- }
128
-
129
- ## *** Utility functions ***
130
-
131
- confirm() {
132
- [[ -z "$2" ]] && [[ ! -z "$YES" ]] && logv "$1 (y/n): confirmed by -y flag" && return 0;
133
-
134
- while true; do
135
- if [[ -z "$2" ]]; then
136
- read -p $'\033[1;36m'"$1"' (y/n): '$'\033[0m' yn
137
- else
138
- # double confirm - extra dangerous.
139
- read -p $'\033[0;31m'"$1"' (y/n): '$'\033[0m' yn
140
- fi
141
- case $yn in
142
- [Yy]* ) return 0;;
143
- [Nn]* ) return 1;;
144
- * ) echo "Please answer yes or no.";;
145
- esac
146
- done
147
- }
148
-
149
- get_space_name() {
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
164
- }
165
-
166
- set -e
167
-
168
- # *** Commands ***
169
-
170
- # Example: bin/contentful migrate -y -s 1xab -a $MY_TOKEN db/migrate/20180101120000_add_content_type_dog.ts
171
- # equivalent to: bin/rake db:migrate
172
- migrate() {
173
- ARG="$1"
174
- [[ -z "$ARG" ]] && ARG="db/migrate"
175
- [[ -d "$ARG" ]] && ARG="batch $ARG"
176
-
177
- require_environment
178
-
179
- [[ ! -z "$CONTENTFUL_ENVIRONMENT" ]] && ENV="--environment-id $CONTENTFUL_ENVIRONMENT"
180
-
181
- execv node_modules/.bin/ts-node node_modules/.bin/contentful-migration \
182
- -s $CONTENTFUL_SPACE_ID $ENV -a $CONTENTFUL_MANAGEMENT_TOKEN \
183
- $YES -p $ARG
184
-
185
- mkdir -p db
186
- execv node_modules/.bin/contentful-export --export-dir db --content-file contentful-schema.json \
187
- --space-id $CONTENTFUL_SPACE_ID $ENV --management-token $CONTENTFUL_MANAGEMENT_TOKEN \
188
- --query-entries 'content_type=migrationHistory' \
189
- --query-assets 'sys.id=false'
190
-
191
- if [[ $(git diff-index --name-only HEAD | grep 'db/contentful-schema.json') == "" ]]; then
192
- echo -e "${COLOR_LGREEN}✓ Schema in contentful space is equivalent to stored schema${COLOR_NC}"
193
- else
194
- echo -e "${COLOR_YELLOW}⚠️ Schema changed after running migrations${COLOR_NC}"
195
- fi
196
- }
197
-
198
- # Example: bin/contentful backup -s 1xab -a $MY_TOKEN 2018_01_01.1xab.dump.json
199
- # equivalent to: bin/rake db:dump[2018_01_01.dump]
200
- backup() {
201
- FILE="$1"
202
- [[ ! -z "$FILE" ]] && FILE="--content-file $FILE" && shift
203
-
204
- require_environment
205
-
206
- [[ ! -z "$CONTENTFUL_ENVIRONMENT" ]] && ENV="--environment-id $CONTENTFUL_ENVIRONMENT"
207
-
208
- execv node_modules/.bin/contentful-export $FILE \
209
- --space-id $CONTENTFUL_SPACE_ID $ENV --management-token $CONTENTFUL_MANAGEMENT_TOKEN \
210
- $@
211
- }
212
-
213
- # Example: bin/contentful restore -y -s 1xab -a $MY_TOKEN 2018_01_01.1xab.dump.json
214
- # equivalent to: bin/rake db:restore[2018_01_01.dump]
215
- restore() {
216
- FILE="$1"
217
- if [[ -z "$FILE" ]]; then
218
- FILE=$(ls contentful-export-$CONTENTFUL_SPACE_ID-* | sort -r | head -n 1)
219
- [[ -z "$FILE" ]] && logerr "No file given on command line" && exit -1
220
- fi
221
-
222
- name=$(get_space_name $CONTENTFUL_SPACE_ID)
223
- if [[ ! -z "$CONTENTFUL_ENVIRONMENT" ]]; then
224
- ENV="--environment-id $CONTENTFUL_ENVIRONMENT"
225
- name="$name/$CONTENTFUL_ENVIRONMENT"
226
- fi
227
- confirm "Import $FILE into $name?" || exit -1
228
-
229
- require_environment
230
-
231
- execv node_modules/.bin/contentful-import \
232
- --space-id $CONTENTFUL_SPACE_ID $ENV --management-token $CONTENTFUL_MANAGEMENT_TOKEN \
233
- --content-file $FILE
234
- }
235
-
236
- # Example: bin/contentful setup -y -s 1xab -a $MY_TOKEN db/my-schema.json
237
- # equivalent to: bin/rake db:setup
238
- setup() {
239
- FILE="$1"
240
- [[ -z "$FILE" ]] && FILE=db/contentful-schema.json
241
-
242
- name=$(get_space_name $CONTENTFUL_SPACE_ID)
243
- if [[ ! -z "$CONTENTFUL_ENVIRONMENT" ]]; then
244
- ENV="--environment-id $CONTENTFUL_ENVIRONMENT"
245
- name="$name/$CONTENTFUL_ENVIRONMENT"
246
- fi
247
-
248
- confirm "Initialize space $name from seed file $FILE?" || exit -1
249
-
250
- require_environment
251
-
252
- execv node_modules/.bin/contentful-import \
253
- --space-id $CONTENTFUL_SPACE_ID $ENV --management-token $CONTENTFUL_MANAGEMENT_TOKEN \
254
- --content-file $FILE
255
-
256
- migrate
257
- }
258
-
259
- # Example: bin/contentful clean -s 1xab -a $MY_TOKEN
260
- clean() {
261
- command -v jq >/dev/null 2>&1 || (logerr "I require 'jq' but it's not installed. Please run 'brew install jq'"; exit -1)
262
-
263
- require_environment
264
-
265
- [[ -z "$CONTENTFUL_ENVIRONMENT" ]] && CONTENTFUL_ENVIRONMENT="$USER"
266
- [[ "$CONTENTFUL_ENVIRONMENT" == "master" ]] && logerr "cannot delete the master environment" && exit -1
267
-
268
- name=$(get_space_name $CONTENTFUL_SPACE_ID)
269
- 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)
270
- [[ $code == "404" ]] && logerr "$CONTENTFUL_ENVIRONMENT does not exist in $name" && return 0;
271
-
272
- confirm "This will delete the '$CONTENTFUL_ENVIRONMENT' environment from $name. Are you sure?" || exit -1
273
-
274
- local bkup_file="contentful-export-$CONTENTFUL_SPACE_ID-${CONTENTFUL_ENVIRONMENT}-`date +"%Y-%m-%dT%H-%M-%S"`.json"
275
- backup $bkup_file
276
-
277
- curlv --fail -XDELETE https://api.contentful.com/spaces/$CONTENTFUL_SPACE_ID/environments/$CONTENTFUL_ENVIRONMENT\?access_token\=$CONTENTFUL_MANAGEMENT_TOKEN
278
- }
279
-
280
- # Example: bin/contentful new_env -e gordon_dev
281
- new_env() {
282
- command -v jq >/dev/null 2>&1 || (logerr "I require 'jq' but it's not installed. Please run 'brew install jq'"; exit -1)
283
-
284
- require_environment
285
- name=$(get_space_name $CONTENTFUL_SPACE_ID)
286
- [[ -z "$CONTENTFUL_ENVIRONMENT" ]] && CONTENTFUL_ENVIRONMENT="$USER"
287
- [[ "$CONTENTFUL_ENVIRONMENT" == "master" ]] && logerr "cannot delete the master environment" && exit -1
288
-
289
- echo -e "${COLOR_LCYAN}This will delete '$CONTENTFUL_ENVIRONMENT' and recreate it from master.${COLOR_NC}"
290
- confirm "Continue?" || exit -1
291
- export YES='-y' # don't keep bugging the user
292
-
293
- clean
294
-
295
- # make the environment
296
- resp=$(curlv -s --fail -XPUT https://api.contentful.com/spaces/$CONTENTFUL_SPACE_ID/environments/$CONTENTFUL_ENVIRONMENT \
297
- -H "Authorization: Bearer ${CONTENTFUL_MANAGEMENT_TOKEN}" \
298
- -H "Content-Type: application/vnd.contentful.management.v1+json" \
299
- -d "{ \"name\": \"${CONTENTFUL_ENVIRONMENT}\" }")
300
-
301
- while [ ! $(echo "$resp" | jq -r .sys.status.sys.id) == "ready" ]
302
- do
303
- logv "waiting for environment $CONTENTFUL_ENVIRONMENT to be ready..."
304
- sleep 1
305
- resp=$(curlv -s https://api.contentful.com/spaces/$CONTENTFUL_SPACE_ID/environments/$CONTENTFUL_ENVIRONMENT \
306
- -H "Authorization: Bearer ${CONTENTFUL_MANAGEMENT_TOKEN}")
307
- done
308
-
309
- logv "get the API keys and update the one matching ours to point to the new environment"
310
- keys=$(curlv -s --fail https://api.contentful.com/spaces/$CONTENTFUL_SPACE_ID/api_keys\?access_token\=$CONTENTFUL_MANAGEMENT_TOKEN)
311
- my_key=$(echo "$keys" | jq -r ".items[] | select(.accessToken == \"$CONTENTFUL_ACCESS_TOKEN\")")
312
- my_key_id=$(echo "$my_key" | jq -r ".sys.id")
313
- my_key_version=$(echo "$my_key" | jq -r ".sys.version")
314
- new_env_links=$(echo "$my_key" | jq ".environments + [{ \"sys\": { \"id\": \"$CONTENTFUL_ENVIRONMENT\", \"type\": \"Link\", \"linkType\": \"Environment\" } }] | { \"environments\": . }")
315
-
316
- curlv -s -o /dev/null --fail -XPUT https://api.contentful.com/spaces/$CONTENTFUL_SPACE_ID/api_keys/$my_key_id \
317
- -H "Authorization: Bearer ${CONTENTFUL_MANAGEMENT_TOKEN}" \
318
- -H "Content-Type: application/vnd.contentful.management.v1+json" \
319
- -H "X-Contentful-Version: ${my_key_version}" \
320
- -d "${new_env_links}"
321
-
322
- execv replace_append .env.local "CONTENTFUL_ENVIRONMENT\=" "CONTENTFUL_ENVIRONMENT=$CONTENTFUL_ENVIRONMENT"
323
- execv replace_append .env.test.local "CONTENTFUL_ENVIRONMENT\=" "CONTENTFUL_ENVIRONMENT=$CONTENTFUL_ENVIRONMENT"
324
-
325
- echo "Environment ${CONTENTFUL_ENVIRONMENT} successfully created!"
326
- }
327
-
328
- # Example: bin/contentful generate add content type dog
329
- # equivalent to: bin/rails generate migration add_content_type_dog
330
- generate() {
331
- migration="
332
- import Migration from 'contentful-migration-cli'
333
-
334
- export = function (migration: Migration) {
335
- const dog = migration.createContentType('dog', {
336
- name: 'Dog'
337
- })
338
-
339
- const name = dog.createField('name')
340
- name.name('Name')
341
- .type('Symbol')
342
- .required(true)
343
- }
344
- "
345
-
346
- timestamp=$(date +%Y%m%d%H%M%S)
347
- filename="$@"
348
- [[ -z "$filename" ]] && filename="contentful_migration"
349
- filename=${filename// /\_}
350
- filename="db/migrate/${timestamp}_${filename}.ts"
351
- echo "$migration" > $filename
352
- echo "generated file $filename"
353
- }
354
-
355
- case $subcommand in
356
- migrate)
357
- migrate $@
358
- ;;
359
- backup|export)
360
- backup $@
361
- ;;
362
- restore|import)
363
- restore $@
364
- ;;
365
- setup)
366
- setup $@
367
- ;;
368
- generate)
369
- generate $@
370
- ;;
371
- clean)
372
- clean $@
373
- ;;
374
- new_env)
375
- new_env $@
376
- ;;
377
- help|h|\?)
378
- usage
379
- ;;
380
- *)
381
- logerr "Unknown command: '$1'"
382
- usage
383
- exit -1
384
- ;;
385
- esac