Skip to content

Commit f8ca3c0

Browse files
authored
Merge pull request code-dot-org#24489 from code-dot-org/block-deleter
Block deleter script
2 parents 5cd8eb3 + fa66133 commit f8ca3c0

File tree

1 file changed

+79
-0
lines changed

1 file changed

+79
-0
lines changed

bin/oneoff/block_deletion.rb

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#!/usr/bin/env ruby
2+
3+
# This script is used to find and delete level-specific custom blocks that also
4+
# exist in the block pool.
5+
#
6+
# Usage: ./block_deletion.rb
7+
# Typically you would want to run this script directly on levelbuilder. Be sure
8+
# to commit content first in case something goes wrong.
9+
#
10+
# It will run through all the blocks in the block pool, and compare them against
11+
# all level-specific blocks. The level-specific block will be removed if it's
12+
# exactly the same as the block pool block, or if the level it's in is not used
13+
# in any script, nor is it the 'New Sprite Lab Project' level. Otherwise, the
14+
# script will display a diff and prompt you to keep or delete the level-specific
15+
# block.
16+
17+
require_relative '../../dashboard/config/environment'
18+
19+
def diff(block1, block2)
20+
block1.dup.
21+
delete_if {|k, v| block2[k] == v}.
22+
merge!(block2.dup.delete_if {|k, _| block1.key?(k)})
23+
end
24+
25+
def get_name(block)
26+
block['name'] || block['func']
27+
end
28+
29+
def format_custom_blocks(blocks)
30+
# You want a hack? I'll give you hack
31+
File.write('/tmp/blocks-formatter.js', "console.log(JSON.stringify(#{JSON.pretty_generate blocks}, null, 2))")
32+
`node /tmp/blocks-formatter.js`
33+
end
34+
35+
def remove_block(level, block_name)
36+
blocks = JSON.parse(level.custom_blocks)
37+
blocks.reject! {|block| block_name == get_name(block)}
38+
level.custom_blocks = format_custom_blocks(blocks)
39+
level.save!
40+
end
41+
42+
Block.all.each do |shared_block|
43+
config = JSON.parse(shared_block.config)
44+
shared_name = get_name(config)
45+
config.delete('color')
46+
similar_blocks = [config]
47+
48+
GamelabJr.all.each do |level|
49+
next unless level.custom_blocks
50+
blocks = JSON.parse level.custom_blocks
51+
blocks.each do |block|
52+
block.delete('color')
53+
name = block['name'] || block['func']
54+
next unless name == shared_name
55+
if level.script_levels.empty? && level.name != 'New Sprite Lab Project'
56+
remove_block(level, name)
57+
next
58+
end
59+
puts
60+
puts "Found a gamelab_#{name} block in #{level.name}"
61+
if similar_blocks.include? block
62+
puts "It's the same, deleting..."
63+
remove_block(level, name)
64+
next
65+
end
66+
puts "It's a different block. These fields changed in the level block:"
67+
puts JSON.pretty_generate(diff(block, config).sort.to_h)
68+
puts "Versus these values in the shared block:"
69+
puts JSON.pretty_generate(diff(config, block).sort.to_h)
70+
$stdin.flush
71+
puts "should I delete it anyway? Y/n"
72+
next if gets.downcase.starts_with? 'n'
73+
remove_block(level, name)
74+
similar_blocks << block
75+
end
76+
rescue => e
77+
puts "Failed on #{level.name}, #{e}"
78+
end
79+
end

0 commit comments

Comments
 (0)