effective_developer 0.6.7 → 0.6.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/models/effective/form_upgrader.rb +32 -8
- data/lib/effective_developer/engine.rb +0 -3
- data/lib/effective_developer/version.rb +1 -1
- data/lib/tasks/hatchbox.rake +11 -0
- data/lib/tasks/pg_pull.rake +5 -6
- data/lib/tasks/sidekiq_clear.rake +22 -0
- metadata +4 -8
- data/app/jobs/effective/asset_replacer_job.rb +0 -17
- data/app/jobs/effective/snippet_replacer_job.rb +0 -17
- data/app/models/effective/asset_replacer.rb +0 -156
- data/app/models/effective/snippet_replacer.rb +0 -67
- data/lib/tasks/replace_effective_assets.rake +0 -5
- data/lib/tasks/replace_effective_snippets.rake +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ce8857439e77912b69f4d782989c25125a30adfa38bdfa098a0ee099d45b5158
|
4
|
+
data.tar.gz: 8c81459bbbc23a9e582cb3e18789bf8923e35744e1d851b6cc282d01d32019c2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4fb7415f3045e979db76b27025696b4c891624813accec70e9832c65dce0d0a639f2b82ff7f39ce1b18ebb4ad233d7ae09df12a2de37adbecdcc5319aa284aab
|
7
|
+
data.tar.gz: 68b07f9aeb57b8c0c0a3b4ec1211bdb645920c3f78ac733fdaedfb16e008dba4efe3642a3697c2ae6d34c26f3f2920b50540441b0ff332f96721c7d359e1df61
|
@@ -38,6 +38,8 @@ module Effective
|
|
38
38
|
private
|
39
39
|
|
40
40
|
SIMPLE_FORM_FOR_REGEX = /simple_form_for( |\()(\[:[^,]+, ?[^,]+\])?(([^,]+),)?.+do \|(\w+)\|/
|
41
|
+
SIMPLE_FORM_FOR_REGEX2 = /simple_form_for\((\w+).+?\) do \|(\w+)\|/
|
42
|
+
|
41
43
|
SIMPLE_FORM_INPUT_ATTRIBUTE = /\.input( |\():(\w+)/
|
42
44
|
SIMPLE_FORM_INPUT_AS_ONE = /(as: :(\w+))/
|
43
45
|
SIMPLE_FORM_INPUT_AS_TWO = /(:as => :(\w+))/
|
@@ -53,17 +55,38 @@ module Effective
|
|
53
55
|
# Replace simple_form_for
|
54
56
|
writer.all { |line| line.include?('simple_form_for') }.each do |line|
|
55
57
|
content = writer.lines[line]
|
58
|
+
|
59
|
+
# Try first time
|
56
60
|
matched = content.match(SIMPLE_FORM_FOR_REGEX)
|
57
|
-
raise("unable to match simple_form_for from:\n#{content}") unless matched.present?
|
58
61
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
+
if matched.present?
|
63
|
+
original = matched[0]
|
64
|
+
model = matched[2] || matched[4]
|
65
|
+
letter = matched[5]
|
62
66
|
|
63
|
-
|
67
|
+
if original && model && letter
|
68
|
+
content.sub!(original, "effective_form_with(model: #{model}) do |#{letter}|")
|
69
|
+
writer.replace(line, content)
|
70
|
+
next
|
71
|
+
end
|
72
|
+
end
|
64
73
|
|
65
|
-
|
66
|
-
|
74
|
+
# Try second time
|
75
|
+
matched = content.match(SIMPLE_FORM_FOR_REGEX2)
|
76
|
+
|
77
|
+
if matched.present?
|
78
|
+
original = matched[0]
|
79
|
+
model = matched[1]
|
80
|
+
letter = matched[2]
|
81
|
+
|
82
|
+
if original && model && letter
|
83
|
+
content.sub!(original, "effective_form_with(model: #{model}) do |#{letter}|")
|
84
|
+
writer.replace(line, content)
|
85
|
+
next
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
puts("unable to determine simple_form_for subject from:\n#{content}")
|
67
90
|
end
|
68
91
|
|
69
92
|
# Try to figure out klass again if its missing from filename
|
@@ -189,7 +212,8 @@ module Effective
|
|
189
212
|
when 'text' then 'text_area'
|
190
213
|
when 'url' then 'url_field'
|
191
214
|
else
|
192
|
-
|
215
|
+
puts("unknown input type #{input_type} (for attribute :#{attribute})")
|
216
|
+
'text_field'
|
193
217
|
end
|
194
218
|
end
|
195
219
|
|
@@ -2,9 +2,6 @@ module EffectiveDeveloper
|
|
2
2
|
class Engine < ::Rails::Engine
|
3
3
|
engine_name 'effective_developer'
|
4
4
|
|
5
|
-
config.autoload_paths += Dir["#{config.root}/models/jobs/"]
|
6
|
-
config.eager_load_paths += Dir["#{config.root}/models/jobs/"]
|
7
|
-
|
8
5
|
# Set up our default configuration options.
|
9
6
|
initializer 'effective_developer.defaults', before: :load_config_initializers do |app|
|
10
7
|
# Set up our defaults, as per our initializer template
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# bundle exec rake hb:ssh
|
2
|
+
# bundle exec rake hb:staging
|
3
|
+
namespace :hb do
|
4
|
+
task :ssh do
|
5
|
+
system("ssh -t deploy@#{ENV.fetch('HATCHBOX_IP')} \"cd ~/arta/current ; bash --login\"")
|
6
|
+
end
|
7
|
+
|
8
|
+
task :staging do
|
9
|
+
system("ssh -t deploy@#{ENV.fetch('HATCHBOX_IP')} \"cd ~/arta-staging/current ; bash --login\"")
|
10
|
+
end
|
11
|
+
end
|
data/lib/tasks/pg_pull.rake
CHANGED
@@ -18,8 +18,8 @@ namespace :pg do
|
|
18
18
|
args.with_defaults(defaults.compact.merge(env_keys.compact).merge(keywords))
|
19
19
|
|
20
20
|
# Validate Config
|
21
|
-
config = ActiveRecord::Base.configurations[Rails.env]
|
22
21
|
configs = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env)
|
22
|
+
config = configs.first
|
23
23
|
|
24
24
|
if configs.length > 1 && args.database.blank?
|
25
25
|
puts "Multiple database configs exist for #{Rails.env} environment."
|
@@ -102,8 +102,8 @@ namespace :pg do
|
|
102
102
|
end
|
103
103
|
|
104
104
|
# Validate Config
|
105
|
-
config = ActiveRecord::Base.configurations[Rails.env]
|
106
105
|
configs = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env)
|
106
|
+
config = configs.first
|
107
107
|
|
108
108
|
if configs.length > 1 && args.database.blank?
|
109
109
|
puts "Multiple database configs exist for #{Rails.env} environment."
|
@@ -151,8 +151,8 @@ namespace :pg do
|
|
151
151
|
{ username: uri.user, password: uri.password, host: uri.host, port: (uri.port || 5432), database: uri.path.sub('/', '') }
|
152
152
|
else
|
153
153
|
# Validate Config
|
154
|
-
config = ActiveRecord::Base.configurations[Rails.env]
|
155
154
|
configs = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env)
|
155
|
+
config = configs.first
|
156
156
|
|
157
157
|
if configs.length > 1 && args.database.blank?
|
158
158
|
puts "Multiple database configs exist for #{Rails.env} environment."
|
@@ -189,11 +189,10 @@ namespace :pg do
|
|
189
189
|
desc 'Clones the production (--remote heroku by default) database to staging (--remote staging by default)'
|
190
190
|
task :clone, [:source_remote, :target_remote] => :environment do |t, args|
|
191
191
|
args.with_defaults(:source_remote => 'heroku', :target_remote => 'staging')
|
192
|
-
db = ActiveRecord::Base.configurations[Rails.env]
|
193
192
|
|
194
193
|
puts "=== Cloning remote '#{args.source_remote}' to '#{args.target_remote}'"
|
195
194
|
|
196
|
-
Bundler.
|
195
|
+
Bundler.with_unbundled_env do
|
197
196
|
unless system("heroku pg:backups:capture --remote #{args.source_remote}")
|
198
197
|
abort "Error capturing heroku backup"
|
199
198
|
end
|
@@ -240,7 +239,7 @@ namespace :pg do
|
|
240
239
|
puts "=== Cloning local table '#{args.table}' to remote #{args.remote} database"
|
241
240
|
|
242
241
|
# Dump my local database table
|
243
|
-
db = ActiveRecord::Base.configurations
|
242
|
+
db = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env).first
|
244
243
|
tmpfile = "tmp/#{args.table}.sql"
|
245
244
|
|
246
245
|
unless system("pg_dump --data-only --table=#{args.table} -h localhost -U '#{db['username']}' '#{db['database']}' > #{tmpfile}")
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# bundle exec rake sidekiq:start
|
2
|
+
# bundle exec rake sidekiq:clear
|
3
|
+
|
4
|
+
namespace :sidekiq do
|
5
|
+
desc 'Starts the sidekiq background job server'
|
6
|
+
task :start do
|
7
|
+
system('bundle exec sidekiq -C config/sidekiq.yml')
|
8
|
+
end
|
9
|
+
|
10
|
+
desc 'Clears all in progress sidekiq jobs'
|
11
|
+
task clear: :environment do
|
12
|
+
unless Rails.env.development?
|
13
|
+
puts "Cannot run in non-development mode"; exit
|
14
|
+
end
|
15
|
+
|
16
|
+
require 'sidekiq/api'
|
17
|
+
Sidekiq::Queue.all.each { |q| q.clear }
|
18
|
+
|
19
|
+
puts "All sidekiq queues cleared"
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: effective_developer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Code and Effect
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-04-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -48,16 +48,12 @@ files:
|
|
48
48
|
- MIT-LICENSE
|
49
49
|
- README.md
|
50
50
|
- Rakefile
|
51
|
-
- app/jobs/effective/asset_replacer_job.rb
|
52
|
-
- app/jobs/effective/snippet_replacer_job.rb
|
53
51
|
- app/models/effective/annotator.rb
|
54
|
-
- app/models/effective/asset_replacer.rb
|
55
52
|
- app/models/effective/code_writer.rb
|
56
53
|
- app/models/effective/csv_importer.rb
|
57
54
|
- app/models/effective/form_upgrader.rb
|
58
55
|
- app/models/effective/live_generator.rb
|
59
56
|
- app/models/effective/profiler.rb
|
60
|
-
- app/models/effective/snippet_replacer.rb
|
61
57
|
- config/effective_developer.rb
|
62
58
|
- lib/effective_developer.rb
|
63
59
|
- lib/effective_developer/engine.rb
|
@@ -103,11 +99,11 @@ files:
|
|
103
99
|
- lib/scaffolds/views/_resource.html.haml
|
104
100
|
- lib/tasks/annotate.rake
|
105
101
|
- lib/tasks/effective_csv_importer.rake
|
102
|
+
- lib/tasks/hatchbox.rake
|
106
103
|
- lib/tasks/pg_pull.rake
|
107
104
|
- lib/tasks/rename_class.rake
|
108
|
-
- lib/tasks/replace_effective_assets.rake
|
109
|
-
- lib/tasks/replace_effective_snippets.rake
|
110
105
|
- lib/tasks/reset_pk_sequence.rake
|
106
|
+
- lib/tasks/sidekiq_clear.rake
|
111
107
|
- lib/tasks/upgrade_forms.rake
|
112
108
|
- lib/tasks/validate.rake
|
113
109
|
homepage: https://github.com/code-and-effect/effective_developer
|
@@ -1,17 +0,0 @@
|
|
1
|
-
module Effective
|
2
|
-
class AssetReplacerJob < ::ApplicationJob
|
3
|
-
|
4
|
-
queue_as :default
|
5
|
-
|
6
|
-
if defined?(Sidekiq)
|
7
|
-
# The retry setting works. But none of these waits seem to. Still getting exponential backoff.
|
8
|
-
sidekiq_options retry: 2, retry_in: 10, wait: 10
|
9
|
-
sidekiq_retry_in { |count, exception| 10 }
|
10
|
-
end
|
11
|
-
|
12
|
-
def perform(attachment, box)
|
13
|
-
Effective::AssetReplacer.new.replace_attachment!(attachment, box)
|
14
|
-
end
|
15
|
-
|
16
|
-
end
|
17
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
module Effective
|
2
|
-
class SnippetReplacerJob < ::ApplicationJob
|
3
|
-
|
4
|
-
queue_as :default
|
5
|
-
|
6
|
-
if defined?(Sidekiq)
|
7
|
-
# The retry setting works. But none of these waits seem to. Still getting exponential backoff.
|
8
|
-
sidekiq_options retry: 2, retry_in: 10, wait: 10
|
9
|
-
sidekiq_retry_in { |count, exception| 10 }
|
10
|
-
end
|
11
|
-
|
12
|
-
def perform(region)
|
13
|
-
Effective::SnippetReplacer.new.replace_region!(region)
|
14
|
-
end
|
15
|
-
|
16
|
-
end
|
17
|
-
end
|
@@ -1,156 +0,0 @@
|
|
1
|
-
# Looks at the Effective::Asset and Effective::Attachments and converts to ActiveStorage
|
2
|
-
#
|
3
|
-
# 1. Put in the has_attached_files to each model to be upgraded
|
4
|
-
# 2. Remove the acts_as_asset_box
|
5
|
-
|
6
|
-
require 'timeout'
|
7
|
-
|
8
|
-
module Effective
|
9
|
-
class AssetReplacer
|
10
|
-
include ActiveStorage::Blob::Analyzable
|
11
|
-
|
12
|
-
BATCH_SIZE = 500
|
13
|
-
TIMEOUT = 120
|
14
|
-
|
15
|
-
def replace!(skip_existing: false)
|
16
|
-
verify!
|
17
|
-
|
18
|
-
attachments = attachments_to_process().to_a
|
19
|
-
|
20
|
-
while(true)
|
21
|
-
wait_for_active_job!
|
22
|
-
|
23
|
-
puts "\nEnqueuing #{attachments.length} attachments with ids #{attachments.first.id} to #{attachments.last.id}"
|
24
|
-
|
25
|
-
attachments.each do |attachment|
|
26
|
-
asset = attachment.asset
|
27
|
-
attachable = attachment.attachable
|
28
|
-
next if asset.blank? || attachable.blank?
|
29
|
-
|
30
|
-
box = attachment.box.singularize
|
31
|
-
boxes = attachment.box
|
32
|
-
|
33
|
-
one = attachable.respond_to?(box) && attachable.send(box).kind_of?(ActiveStorage::Attached::One)
|
34
|
-
many = attachable.respond_to?(boxes) && attachable.send(boxes).kind_of?(ActiveStorage::Attached::Many)
|
35
|
-
box = (one ? box : boxes)
|
36
|
-
|
37
|
-
if skip_existing
|
38
|
-
existing = Array(attachable.send(box))
|
39
|
-
|
40
|
-
if existing.any? { |obj| obj.respond_to?(:filename) && obj.filename.to_s == asset.file_name }
|
41
|
-
puts("Skipping existing #{attachable.class.name} #{attachable.id} #{box} #{asset.file_name}.")
|
42
|
-
next
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
Effective::AssetReplacerJob.perform_later(attachment, box)
|
47
|
-
end
|
48
|
-
|
49
|
-
attachments = attachments_to_process().where.not(id: attachments.map(&:id))
|
50
|
-
break if attachments.to_a.blank?
|
51
|
-
|
52
|
-
GC.start
|
53
|
-
end
|
54
|
-
|
55
|
-
puts "\nAll Done. Have a great day."
|
56
|
-
true
|
57
|
-
end
|
58
|
-
|
59
|
-
# This is called on the background by the AssetReplacerJob
|
60
|
-
def replace_attachment!(attachment, box)
|
61
|
-
raise('expected an Effective::Attachment') unless attachment.kind_of?(Effective::Attachment)
|
62
|
-
puts("Processing attachment ##{attachment.id}")
|
63
|
-
|
64
|
-
asset = attachment.asset
|
65
|
-
attachable = attachment.attachable
|
66
|
-
|
67
|
-
attachable.replacing_asset = true if attachable.respond_to?(:replacing_asset=)
|
68
|
-
|
69
|
-
Timeout.timeout(TIMEOUT) do
|
70
|
-
attachable.send(box).attach(
|
71
|
-
io: URI.open(asset.url),
|
72
|
-
filename: asset.file_name,
|
73
|
-
content_type: asset.content_type.presence,
|
74
|
-
identify: (asset.content_type.blank?)
|
75
|
-
)
|
76
|
-
|
77
|
-
attachment.update_column(:replaced, true)
|
78
|
-
end
|
79
|
-
|
80
|
-
true
|
81
|
-
end
|
82
|
-
|
83
|
-
def verify!
|
84
|
-
raise('expected effective assets') unless defined?(Effective::Asset)
|
85
|
-
raise('expected active storage') unless defined?(ActiveStorage)
|
86
|
-
|
87
|
-
unless Effective::Attachment.new.respond_to?(:replaced?)
|
88
|
-
raise('please add a replaced boolean to Effective::Attachment. add_column :attachments, :replaced, :boolean')
|
89
|
-
end
|
90
|
-
|
91
|
-
(Effective::Attachment.all.pluck(:attachable_type, :box).uniq).each do |name, boxes|
|
92
|
-
next if name.blank? || boxes.blank?
|
93
|
-
|
94
|
-
box = boxes.singularize
|
95
|
-
|
96
|
-
klass = name.safe_constantize
|
97
|
-
raise("invalid class #{klass}") unless klass.present?
|
98
|
-
|
99
|
-
instance = klass.new
|
100
|
-
|
101
|
-
if instance.respond_to?(:effective_assets)
|
102
|
-
raise("please remove acts_as_asset_box() from #{klass.name}")
|
103
|
-
end
|
104
|
-
|
105
|
-
unless instance.respond_to?(box) || instance.respond_to?(boxes)
|
106
|
-
raise("expected #{klass.name} to has_one_attached :#{box} or has_many_attached :#{boxes}")
|
107
|
-
end
|
108
|
-
|
109
|
-
one = instance.respond_to?(box) && instance.send(box).kind_of?(ActiveStorage::Attached::One)
|
110
|
-
many = instance.respond_to?(boxes) && instance.send(boxes).kind_of?(ActiveStorage::Attached::Many)
|
111
|
-
|
112
|
-
unless one.present? || many.present?
|
113
|
-
raise("expected #{klass.name} to has_one_attached :#{box} or has_many_attached :#{boxes}")
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
puts 'All attachment classes verified.'
|
118
|
-
|
119
|
-
true
|
120
|
-
end
|
121
|
-
|
122
|
-
def reset!
|
123
|
-
Effective::Attachment.update_all(replaced: false)
|
124
|
-
end
|
125
|
-
|
126
|
-
private
|
127
|
-
|
128
|
-
def wait_for_active_job!
|
129
|
-
while(true)
|
130
|
-
if(jobs = enqueued_jobs_count) > (BATCH_SIZE / 10)
|
131
|
-
print '.'; sleep(3)
|
132
|
-
else
|
133
|
-
break
|
134
|
-
end
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
# The last BATCH_SIZE attachments
|
139
|
-
def attachments_to_process
|
140
|
-
Effective::Attachment.all
|
141
|
-
.includes(:asset)
|
142
|
-
.where(replaced: [nil, false])
|
143
|
-
.reorder(id: :desc)
|
144
|
-
.limit(BATCH_SIZE)
|
145
|
-
end
|
146
|
-
|
147
|
-
def enqueued_jobs_count
|
148
|
-
if Rails.application.config.active_job.queue_adapter == :sidekiq
|
149
|
-
Sidekiq::Stats.new.enqueued.to_i
|
150
|
-
else
|
151
|
-
ActiveJob::Base.queue_adapter.enqueued_jobs.count
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
end
|
156
|
-
end
|
@@ -1,67 +0,0 @@
|
|
1
|
-
# Replaces the [snippet_x] in all effective regions with static content
|
2
|
-
|
3
|
-
module Effective
|
4
|
-
class SnippetReplacer
|
5
|
-
include ActiveStorage::Blob::Analyzable
|
6
|
-
include ActionView::Helpers::UrlHelper
|
7
|
-
include ActionView::Helpers::AssetTagHelper
|
8
|
-
|
9
|
-
def replace!
|
10
|
-
raise('expected effective regions') unless defined?(Effective::Region)
|
11
|
-
raise('expected effective assets') unless defined?(Effective::Asset)
|
12
|
-
raise('expected active storage') unless defined?(ActiveStorage)
|
13
|
-
|
14
|
-
Effective::Region.with_snippets.find_each do |region|
|
15
|
-
Effective::SnippetReplacerJob.perform_later(region)
|
16
|
-
end
|
17
|
-
|
18
|
-
puts 'All Done. Background jobs are running. Have a great day.'
|
19
|
-
true
|
20
|
-
end
|
21
|
-
|
22
|
-
def replace_region!(region)
|
23
|
-
region.snippet_objects.each do |snippet|
|
24
|
-
print('.')
|
25
|
-
|
26
|
-
begin
|
27
|
-
case snippet.class.name
|
28
|
-
when 'Effective::Snippets::EffectiveAsset'
|
29
|
-
replace_effective_asset(region, snippet)
|
30
|
-
else
|
31
|
-
raise("unsupported snippet: #{snippet.class.name}")
|
32
|
-
end
|
33
|
-
rescue => e
|
34
|
-
puts "\nError: #{e}\n"
|
35
|
-
remove_snippet(region, snippet)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
region.save!
|
40
|
-
end
|
41
|
-
|
42
|
-
def replace_effective_asset(region, snippet)
|
43
|
-
asset = snippet.asset
|
44
|
-
raise("Effective:Asset id=#{snippet.asset_id || 'none'} does not exist") unless asset.present?
|
45
|
-
|
46
|
-
blob = ActiveStorage::Blob.create_and_upload!(io: URI.open(asset.url), filename: asset.file_name)
|
47
|
-
url = Rails.application.routes.url_helpers.rails_blob_url(blob, only_path: true)
|
48
|
-
|
49
|
-
content = if asset.image?
|
50
|
-
image_tag(url, class: snippet.html_class, alt: snippet.link_title)
|
51
|
-
else
|
52
|
-
link_to(snippet.link_title, url, class: snippet.html_class, title: snippet.link_title)
|
53
|
-
end
|
54
|
-
|
55
|
-
region.content.sub!("[#{snippet.id}]", content.to_s)
|
56
|
-
region.snippets.delete(snippet.id)
|
57
|
-
|
58
|
-
true
|
59
|
-
end
|
60
|
-
|
61
|
-
def remove_snippet(region, snippet)
|
62
|
-
region.content.sub!("[#{snippet.id}]", '')
|
63
|
-
region.snippets.delete(snippet.id)
|
64
|
-
end
|
65
|
-
|
66
|
-
end
|
67
|
-
end
|