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.
- checksums.yaml +4 -4
- data/.rspec +0 -1
- data/README.md +181 -8
- data/app/controllers/wcc/contentful/webhook_controller.rb +42 -2
- data/app/jobs/wcc/contentful/delayed_sync_job.rb +52 -3
- data/app/jobs/wcc/contentful/webhook_enable_job.rb +43 -0
- data/bin/console +4 -3
- data/bin/rails +2 -0
- data/config/initializers/mime_types.rb +10 -1
- data/lib/wcc/contentful.rb +14 -142
- data/lib/wcc/contentful/client_ext.rb +17 -4
- data/lib/wcc/contentful/configuration.rb +25 -84
- data/lib/wcc/contentful/engine.rb +19 -0
- data/lib/wcc/contentful/exceptions.rb +25 -28
- data/lib/wcc/contentful/graphql.rb +0 -1
- data/lib/wcc/contentful/graphql/types.rb +1 -1
- data/lib/wcc/contentful/helpers.rb +3 -2
- data/lib/wcc/contentful/indexed_representation.rb +6 -0
- data/lib/wcc/contentful/model.rb +68 -34
- data/lib/wcc/contentful/model_builder.rb +65 -67
- data/lib/wcc/contentful/model_methods.rb +189 -0
- data/lib/wcc/contentful/model_singleton_methods.rb +83 -0
- data/lib/wcc/contentful/services.rb +146 -0
- data/lib/wcc/contentful/simple_client.rb +35 -33
- data/lib/wcc/contentful/simple_client/http_adapter.rb +9 -0
- data/lib/wcc/contentful/simple_client/management.rb +81 -0
- data/lib/wcc/contentful/simple_client/response.rb +61 -37
- data/lib/wcc/contentful/simple_client/typhoeus_adapter.rb +12 -0
- data/lib/wcc/contentful/store.rb +45 -18
- data/lib/wcc/contentful/store/base.rb +128 -8
- data/lib/wcc/contentful/store/cdn_adapter.rb +92 -22
- data/lib/wcc/contentful/store/lazy_cache_store.rb +94 -9
- data/lib/wcc/contentful/store/memory_store.rb +13 -8
- data/lib/wcc/contentful/store/postgres_store.rb +44 -11
- data/lib/wcc/contentful/sys.rb +28 -0
- data/lib/wcc/contentful/version.rb +1 -1
- data/wcc-contentful.gemspec +3 -9
- metadata +87 -107
- data/.circleci/config.yml +0 -51
- data/.gitignore +0 -26
- data/.rubocop.yml +0 -243
- data/.rubocop_todo.yml +0 -13
- data/.travis.yml +0 -5
- data/CHANGELOG.md +0 -45
- data/CODE_OF_CONDUCT.md +0 -74
- data/Guardfile +0 -58
- data/LICENSE.txt +0 -21
- data/Rakefile +0 -8
- data/lib/generators/wcc/USAGE +0 -24
- data/lib/generators/wcc/model_generator.rb +0 -90
- data/lib/generators/wcc/templates/.keep +0 -0
- data/lib/generators/wcc/templates/Procfile +0 -3
- data/lib/generators/wcc/templates/contentful_shell_wrapper +0 -385
- data/lib/generators/wcc/templates/menu/generated_add_menus.ts +0 -90
- data/lib/generators/wcc/templates/menu/models/menu.rb +0 -23
- data/lib/generators/wcc/templates/menu/models/menu_button.rb +0 -23
- data/lib/generators/wcc/templates/page/generated_add_pages.ts +0 -50
- data/lib/generators/wcc/templates/page/models/page.rb +0 -23
- data/lib/generators/wcc/templates/release +0 -9
- data/lib/generators/wcc/templates/wcc_contentful.rb +0 -17
- data/lib/wcc/contentful/model/menu.rb +0 -7
- data/lib/wcc/contentful/model/menu_button.rb +0 -15
- data/lib/wcc/contentful/model/page.rb +0 -8
- data/lib/wcc/contentful/model/redirect.rb +0 -19
- data/lib/wcc/contentful/model_validators.rb +0 -115
- 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
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
data/lib/generators/wcc/USAGE
DELETED
@@ -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,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
|