discourse_theme 1.0.1 → 1.1.0
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/CHANGELOG.md +14 -1
- data/lib/discourse_theme/cli.rb +45 -3
- data/lib/discourse_theme/cli_commands/rspec.rb +6 -6
- data/lib/discourse_theme/ui.rb +4 -0
- data/lib/discourse_theme/uploader.rb +33 -3
- data/lib/discourse_theme/version.rb +1 -1
- data/lib/discourse_theme/watcher.rb +26 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1e3352f4282ac30c46402e5cdf6f7c9ba504e7c8b5980884e4a42b700eef3e90
|
4
|
+
data.tar.gz: b13f657e0e023c3a6bee4eca8dc3a9090c55333f444bc5b9a55d67781baac017
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9900153835d064382bdde7fbd395345a66cdeb5bd4b5df85f825c2d8ac12556bc4c329d56bd91030a5efae836c567db79ab219d7276d3e5cef784e51aedeba82
|
7
|
+
data.tar.gz: 26aec19d02acf892b7f5434ec7f141c1afa7e3d8e099917e40d15cafa6d8a2ff27a7076769eaa6319b44d0d46a4561d12374fa295929b140e2e0938789334792
|
data/CHANGELOG.md
CHANGED
@@ -5,9 +5,22 @@ All notable changes to this project will be documented in this file.
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
7
|
|
8
|
+
## [1.1.0] - 2024-01-10
|
9
|
+
|
10
|
+
### Added
|
11
|
+
|
12
|
+
- Add upload theme migrations prompt to `watch` command for `discourse_theme` CLI (#38)
|
13
|
+
|
14
|
+
## [1.0.2] - 2023-12-08
|
15
|
+
|
16
|
+
### Fixed
|
17
|
+
|
18
|
+
- `discourse_theme rspec` command using Docker container not copying theme to the right directory that is mounted inside
|
19
|
+
the Docker container.
|
20
|
+
|
8
21
|
## [1.0.1] - 2023-10-19
|
9
22
|
|
10
|
-
|
23
|
+
### Fixed
|
11
24
|
|
12
25
|
- Spec path was not preserved when running rspec against a local Discourse repository.
|
13
26
|
|
data/lib/discourse_theme/cli.rb
CHANGED
@@ -36,7 +36,7 @@ module DiscourseTheme
|
|
36
36
|
exit 1
|
37
37
|
end
|
38
38
|
|
39
|
-
def run(args)
|
39
|
+
def run(args, &block)
|
40
40
|
usage unless args[1]
|
41
41
|
|
42
42
|
reset = !!args.delete("--reset")
|
@@ -66,9 +66,11 @@ module DiscourseTheme
|
|
66
66
|
theme_list = client.get_themes_list
|
67
67
|
|
68
68
|
options = {}
|
69
|
+
|
69
70
|
if theme_id && theme = theme_list.find { |t| t["id"] == theme_id }
|
70
71
|
options["Sync with existing theme: '#{theme["name"]}' (id:#{theme_id})"] = :default
|
71
72
|
end
|
73
|
+
|
72
74
|
options["Create and sync with a new theme"] = :create
|
73
75
|
options["Select a different theme"] = :select
|
74
76
|
|
@@ -89,6 +91,7 @@ module DiscourseTheme
|
|
89
91
|
rescue StandardError
|
90
92
|
nil
|
91
93
|
end
|
94
|
+
|
92
95
|
already_uploaded = !!theme
|
93
96
|
is_component = theme&.[]("component")
|
94
97
|
component_count = about_json&.[]("components")&.length || 0
|
@@ -111,7 +114,9 @@ module DiscourseTheme
|
|
111
114
|
)
|
112
115
|
|
113
116
|
UI.progress "Uploading theme from #{dir}"
|
114
|
-
|
117
|
+
|
118
|
+
settings.theme_id =
|
119
|
+
theme_id = uploader.upload_full_theme(ignore_files: ignored_migrations(theme, dir))
|
115
120
|
|
116
121
|
UI.success "Theme uploaded (id:#{theme_id})"
|
117
122
|
UI.info "Preview: #{client.url}/?preview_theme_id=#{theme_id}"
|
@@ -126,7 +131,7 @@ module DiscourseTheme
|
|
126
131
|
|
127
132
|
watcher = DiscourseTheme::Watcher.new(dir: dir, uploader: uploader)
|
128
133
|
UI.progress "Watching for changes in #{dir}..."
|
129
|
-
watcher.watch
|
134
|
+
watcher.watch(&block)
|
130
135
|
elsif command == "download"
|
131
136
|
client = DiscourseTheme::Client.new(dir, settings, reset: reset)
|
132
137
|
downloader = DiscourseTheme::Downloader.new(dir: dir, client: client)
|
@@ -200,6 +205,43 @@ module DiscourseTheme
|
|
200
205
|
|
201
206
|
private
|
202
207
|
|
208
|
+
def ignored_migrations(theme, dir)
|
209
|
+
return [] unless theme && Dir.exist?(File.join(dir, "migrations"))
|
210
|
+
|
211
|
+
existing_migrations =
|
212
|
+
theme
|
213
|
+
.dig("theme_fields")
|
214
|
+
&.filter_map do |theme_field|
|
215
|
+
theme_field["name"] if theme_field["target"] == "migrations"
|
216
|
+
end || []
|
217
|
+
|
218
|
+
new_migrations =
|
219
|
+
Dir["#{dir}/migrations/**/*.js"]
|
220
|
+
.reject do |f|
|
221
|
+
existing_migrations.any? do |existing_migration|
|
222
|
+
File.basename(f).include?(existing_migration)
|
223
|
+
end
|
224
|
+
end
|
225
|
+
.map { |f| Pathname.new(f).relative_path_from(Pathname.new(dir)).to_s }
|
226
|
+
|
227
|
+
if !new_migrations.empty?
|
228
|
+
options = { "Yes" => :yes, "No" => :no }
|
229
|
+
|
230
|
+
choice = UI.select(<<~TEXT, options.keys)
|
231
|
+
Would you like to upload and run the following pending theme migration(s): #{new_migrations.join(", ")}
|
232
|
+
TEXT
|
233
|
+
|
234
|
+
if options[choice] == :no
|
235
|
+
UI.warn "Pending theme migrations have not been uploaded, run `discourse_theme upload #{dir}` if you wish to upload and run the theme migrations."
|
236
|
+
new_migrations
|
237
|
+
else
|
238
|
+
[]
|
239
|
+
end
|
240
|
+
else
|
241
|
+
[]
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
203
245
|
def command?(cmd)
|
204
246
|
exts = ENV["PATHEXT"] ? ENV["PATHEXT"].split(";") : [""]
|
205
247
|
ENV["PATH"]
|
@@ -37,7 +37,7 @@ module DiscourseTheme
|
|
37
37
|
|
38
38
|
if settings.local_discourse_directory.empty?
|
39
39
|
run_tests_with_docker(
|
40
|
-
|
40
|
+
dir,
|
41
41
|
spec_directory,
|
42
42
|
spec_path,
|
43
43
|
headless: headless,
|
@@ -93,13 +93,15 @@ module DiscourseTheme
|
|
93
93
|
end
|
94
94
|
|
95
95
|
def run_tests_with_docker(
|
96
|
-
|
96
|
+
theme_directory,
|
97
97
|
spec_directory,
|
98
98
|
spec_path,
|
99
99
|
headless: false,
|
100
100
|
verbose: false,
|
101
101
|
rebuild: false
|
102
102
|
)
|
103
|
+
theme_directory_name = File.basename(theme_directory)
|
104
|
+
|
103
105
|
image = "discourse/discourse_test:release"
|
104
106
|
UI.progress("Running RSpec tests using '#{image}' Docker image...")
|
105
107
|
|
@@ -191,9 +193,7 @@ module DiscourseTheme
|
|
191
193
|
rspec_envs = rspec_envs.map { |env| "-e #{env}" }.join(" ")
|
192
194
|
|
193
195
|
begin
|
194
|
-
|
195
|
-
FileUtils.mkdir_p(tmp_theme_directory) if !Dir.exist?(tmp_theme_directory)
|
196
|
-
FileUtils.cp_r(spec_directory, File.join(tmp_theme_directory))
|
196
|
+
FileUtils.cp_r(theme_directory, DISCOURSE_THEME_TEST_TMP_DIR)
|
197
197
|
|
198
198
|
execute(
|
199
199
|
command:
|
@@ -203,7 +203,7 @@ module DiscourseTheme
|
|
203
203
|
stream: true,
|
204
204
|
)
|
205
205
|
ensure
|
206
|
-
FileUtils.rm_rf(File.join(
|
206
|
+
FileUtils.rm_rf(File.join(DISCOURSE_THEME_TEST_TMP_DIR, theme_directory_name))
|
207
207
|
end
|
208
208
|
end
|
209
209
|
|
data/lib/discourse_theme/ui.rb
CHANGED
@@ -1,6 +1,20 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
module DiscourseTheme
|
3
3
|
class Uploader
|
4
|
+
def self.upload_full_theme_callbacks
|
5
|
+
@upload_callbacks ||= []
|
6
|
+
end
|
7
|
+
|
8
|
+
# Used in the test environment to register a callback that is called with the directory of the theme being uploaded.
|
9
|
+
def self.register_upload_full_theme_callback(&block)
|
10
|
+
self.upload_full_theme_callbacks << block
|
11
|
+
end
|
12
|
+
|
13
|
+
# Used in the test environment to clear the registered callbacks.
|
14
|
+
def self.reset_upload_full_theme_callbacks
|
15
|
+
self.upload_full_theme_callbacks.clear
|
16
|
+
end
|
17
|
+
|
4
18
|
def initialize(dir:, client:, theme_id: nil, components: nil)
|
5
19
|
@dir = dir
|
6
20
|
@client = client
|
@@ -53,9 +67,24 @@ module DiscourseTheme
|
|
53
67
|
UI.error "(end of errors)" if diagnose_errors(json) != 0
|
54
68
|
end
|
55
69
|
|
56
|
-
def upload_full_theme
|
70
|
+
def upload_full_theme(ignore_files: [])
|
57
71
|
filename = "#{Pathname.new(Dir.tmpdir).realpath}/bundle_#{SecureRandom.hex}.tar.gz"
|
58
|
-
|
72
|
+
temp_dir = nil
|
73
|
+
|
74
|
+
theme_dir =
|
75
|
+
if !ignore_files.empty?
|
76
|
+
temp_dir = Dir.mktmpdir
|
77
|
+
FileUtils.copy_entry(@dir, temp_dir)
|
78
|
+
dir_pathname = Pathname.new(@dir)
|
79
|
+
ignore_files.each { |file| FileUtils.rm_f(File.join(temp_dir, file)) }
|
80
|
+
temp_dir
|
81
|
+
else
|
82
|
+
@dir
|
83
|
+
end
|
84
|
+
|
85
|
+
self.class.upload_full_theme_callbacks.each { |cb| cb.call(theme_dir) }
|
86
|
+
|
87
|
+
compress_dir(filename, theme_dir)
|
59
88
|
|
60
89
|
File.open(filename) do |tgz|
|
61
90
|
response = @client.upload_full_theme(tgz, theme_id: @theme_id, components: @components)
|
@@ -66,7 +95,8 @@ module DiscourseTheme
|
|
66
95
|
@theme_id
|
67
96
|
end
|
68
97
|
ensure
|
69
|
-
FileUtils.
|
98
|
+
FileUtils.rm_rf(temp_dir) if temp_dir
|
99
|
+
FileUtils.rm_f(filename)
|
70
100
|
end
|
71
101
|
end
|
72
102
|
end
|
@@ -1,14 +1,33 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
module DiscourseTheme
|
3
3
|
class Watcher
|
4
|
+
LISTEN_IGNORE_PATTERNS = [%r{migrations/.+/.+\.js}]
|
5
|
+
|
4
6
|
def self.return_immediately!
|
5
7
|
@return_immediately = true
|
6
8
|
end
|
7
9
|
|
10
|
+
def self.return_immediately=(val)
|
11
|
+
@return_immediately = val
|
12
|
+
end
|
13
|
+
|
8
14
|
def self.return_immediately?
|
9
15
|
!!@return_immediately
|
10
16
|
end
|
11
17
|
|
18
|
+
def self.subscribe_start(&block)
|
19
|
+
@subscribers ||= []
|
20
|
+
@subscribers << block
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.call_start_subscribers
|
24
|
+
@subscribers&.each(&:call)
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.reset_start_subscribers
|
28
|
+
@subscribers = []
|
29
|
+
end
|
30
|
+
|
12
31
|
def initialize(dir:, uploader:)
|
13
32
|
@dir = dir
|
14
33
|
@uploader = uploader
|
@@ -16,7 +35,9 @@ module DiscourseTheme
|
|
16
35
|
|
17
36
|
def watch
|
18
37
|
listener =
|
19
|
-
Listen.to(@dir) do |modified, added, removed|
|
38
|
+
Listen.to(@dir, ignore: LISTEN_IGNORE_PATTERNS) do |modified, added, removed|
|
39
|
+
yield(modified, added, removed) if block_given?
|
40
|
+
|
20
41
|
begin
|
21
42
|
if modified.length == 1 && added.length == 0 && removed.length == 0 &&
|
22
43
|
(resolved = resolve_file(modified[0]))
|
@@ -31,12 +52,14 @@ module DiscourseTheme
|
|
31
52
|
)
|
32
53
|
else
|
33
54
|
count = modified.length + added.length + removed.length
|
55
|
+
|
34
56
|
if count > 1
|
35
57
|
UI.progress "Detected changes in #{count} files, uploading theme"
|
36
58
|
else
|
37
59
|
filename = modified[0] || added[0] || removed[0]
|
38
60
|
UI.progress "Detected changes in #{filename.gsub(@dir, "")}, uploading theme"
|
39
61
|
end
|
62
|
+
|
40
63
|
@uploader.upload_full_theme
|
41
64
|
end
|
42
65
|
UI.success "Done! Watching for changes..."
|
@@ -47,7 +70,8 @@ module DiscourseTheme
|
|
47
70
|
end
|
48
71
|
|
49
72
|
listener.start
|
50
|
-
|
73
|
+
self.class.call_start_subscribers
|
74
|
+
sleep 1 while !self.class.return_immediately?
|
51
75
|
end
|
52
76
|
|
53
77
|
protected
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: discourse_theme
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Saffron
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-01-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitar
|