discourse_theme 1.0.2 → 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 +6 -0
- data/lib/discourse_theme/cli.rb +45 -3
- 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,6 +5,12 @@ 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
|
+
|
|
8
14
|
## [1.0.2] - 2023-12-08
|
|
9
15
|
|
|
10
16
|
### Fixed
|
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"]
|
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
|