discourse_theme 1.1.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1e3352f4282ac30c46402e5cdf6f7c9ba504e7c8b5980884e4a42b700eef3e90
4
- data.tar.gz: b13f657e0e023c3a6bee4eca8dc3a9090c55333f444bc5b9a55d67781baac017
3
+ metadata.gz: 202bc4483d1d73df24eb1674c2d2e1f8920c3f73a7ffbf6d0a69d0fd9bc0fce8
4
+ data.tar.gz: 47e22597abb662a1fff0ba8f1678ea7533d8daa84eb63879d9dcb2c8a79e8dbf
5
5
  SHA512:
6
- metadata.gz: 9900153835d064382bdde7fbd395345a66cdeb5bd4b5df85f825c2d8ac12556bc4c329d56bd91030a5efae836c567db79ab219d7276d3e5cef784e51aedeba82
7
- data.tar.gz: 26aec19d02acf892b7f5434ec7f141c1afa7e3d8e099917e40d15cafa6d8a2ff27a7076769eaa6319b44d0d46a4561d12374fa295929b140e2e0938789334792
6
+ metadata.gz: 14f195165983249d04b48c8e80427176ba1d673541fb87054a9e1f24f64e8f59897d88e2b11612be93996aee9c6122d6772ce141485674167cf793a8c41bb818
7
+ data.tar.gz: 2b6c59248aaac23b12744c89eb83ee886326cbff563a8156cba494e372c9b5b3ccf5cd2ede58c193ae0acb17c72ebeeafec10f35767448bb3e91d64029107c37
@@ -7,46 +7,63 @@ on:
7
7
  - main
8
8
 
9
9
  jobs:
10
- build:
10
+ lint:
11
11
  runs-on: ubuntu-latest
12
12
 
13
- strategy:
14
- matrix:
15
- ruby:
16
- - "3.0"
17
- - "3.1"
18
- - "3.2"
19
-
20
13
  steps:
21
- - uses: actions/checkout@v3
14
+ - uses: actions/checkout@v4
22
15
 
23
16
  - name: Setup ruby
24
17
  uses: ruby/setup-ruby@v1
25
18
  with:
26
- ruby-version: ${{ matrix.ruby }}
19
+ ruby-version: "3.3"
27
20
  bundler-cache: true
28
21
 
29
22
  - name: Lint
30
23
  run: bundle exec rubocop
31
24
 
32
25
  - name: syntax_tree
26
+ if: ${{ !cancelled() }}
33
27
  run: |
34
28
  bundle exec stree check Gemfile $(git ls-files '*.rb') $(git ls-files '*.rake') $(git ls-files '*.thor')
35
29
 
30
+ test:
31
+ runs-on: ubuntu-latest
32
+
33
+ strategy:
34
+ matrix:
35
+ ruby:
36
+ - "3.1"
37
+ - "3.2"
38
+ - "3.3"
39
+
40
+ steps:
41
+ - uses: actions/checkout@v4
42
+
43
+ - name: Setup Git
44
+ run: |
45
+ git config --global user.email "ci@ci.invalid"
46
+ git config --global user.name "Discourse CI"
47
+
48
+ - name: Setup ruby
49
+ uses: ruby/setup-ruby@v1
50
+ with:
51
+ ruby-version: ${{ matrix.ruby }}
52
+ bundler-cache: true
36
53
 
37
54
  - name: Tests
38
55
  run: bundle exec rake test
39
56
 
40
57
  publish:
41
58
  if: github.event_name == 'push' && github.ref == 'refs/heads/main'
42
- needs: build
59
+ needs: [lint, test]
43
60
  runs-on: ubuntu-latest
44
61
 
45
62
  steps:
46
- - uses: actions/checkout@v3
63
+ - uses: actions/checkout@v4
47
64
 
48
65
  - name: Release Gem
49
- uses: discourse/publish-rubygems-action@v2
66
+ uses: discourse/publish-rubygems-action@v3
50
67
  env:
51
68
  RUBYGEMS_API_KEY: ${{ secrets.RUBYGEMS_API_KEY }}
52
69
  GIT_EMAIL: team@discourse.org
data/.streerc CHANGED
@@ -1,2 +1,2 @@
1
1
  --print-width=100
2
- --plugins=plugin/trailing_comma,disable_ternary
2
+ --plugins=plugin/trailing_comma,plugin/disable_auto_ternary
data/CHANGELOG.md CHANGED
@@ -5,6 +5,23 @@ 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
+ ## [2.1.0] - 2024-02-28
9
+
10
+ ### Changed
11
+
12
+ - `new` command now uses discourse-theme-skeleton repo (#44)
13
+
14
+ ## [2.0.0] - 2024-01-31
15
+
16
+ ### Added
17
+
18
+ - `watch` command for `discourse_theme` will prompt user if pending theme migrations should be run (#40)
19
+
20
+ ### Removed
21
+
22
+ - Remove upload theme migrations prompt to `watch` command for `discourse_theme` CLI previously added in #38. Theme migrations
23
+ files are always uploaded going forward.
24
+
8
25
  ## [1.1.0] - 2024-01-10
9
26
 
10
27
  ### Added
data/README.md CHANGED
@@ -45,7 +45,7 @@ On the first run for the given directory, you will be asked if you'll like to us
45
45
  If you select 'Y' and proceeds to configure the path to the local Discourse repository, the tests will be ran using the local Discourse development environment provided by the local Discourse repository. Note that you'll have to set up the local test environment before
46
46
  the tests can be ran successfully.
47
47
 
48
- If the 'n' option is selected, the tests will run in a Docker container created using the [`discourse/discours_test:release`](https://hub.docker.com/r/discourse/discourse_test) Docker image. Note that this requires [Docker](https://docs.docker.com/engine/install/) to be installed.
48
+ If the 'n' option is selected, the tests will run in a Docker container created using the [`discourse/discourse_test:release`](https://hub.docker.com/r/discourse/discourse_test) Docker image. Note that this requires [Docker](https://docs.docker.com/engine/install/) to be installed.
49
49
 
50
50
  When the `--headless` option is used, a local installation of the [Google Chrome browser](https://www.google.com/chrome/) is required.
51
51
 
data/bin/discourse_theme CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- require_relative '../lib/discourse_theme'
4
+ require_relative "../lib/discourse_theme"
5
5
 
6
6
  DiscourseTheme::Cli.new.run(ARGV)
@@ -27,7 +27,7 @@ Gem::Specification.new do |spec|
27
27
  spec.add_runtime_dependency "listen", "~> 3.1"
28
28
  spec.add_runtime_dependency "multipart-post", "~> 2.0"
29
29
  spec.add_runtime_dependency "tty-prompt", "~> 0.18"
30
- spec.add_runtime_dependency "rubyzip", "~> 1.2"
30
+ spec.add_runtime_dependency "rubyzip", "~> 2.3"
31
31
  spec.add_runtime_dependency "selenium-webdriver", "> 4.11"
32
32
 
33
33
  spec.add_development_dependency "bundler"
@@ -36,10 +36,8 @@ Gem::Specification.new do |spec|
36
36
  spec.add_development_dependency "guard"
37
37
  spec.add_development_dependency "guard-minitest"
38
38
  spec.add_development_dependency "webmock"
39
- spec.add_development_dependency "rubocop"
40
- spec.add_development_dependency "rubocop-discourse"
39
+ spec.add_development_dependency "rubocop-discourse", "~> 3.6.0"
41
40
  spec.add_development_dependency "m"
42
41
  spec.add_development_dependency "syntax_tree"
43
- spec.add_development_dependency "syntax_tree-disable_ternary"
44
42
  spec.add_development_dependency "mocha"
45
43
  end
@@ -36,7 +36,7 @@ module DiscourseTheme
36
36
  exit 1
37
37
  end
38
38
 
39
- def run(args, &block)
39
+ def run(args)
40
40
  usage unless args[1]
41
41
 
42
42
  reset = !!args.delete("--reset")
@@ -57,7 +57,7 @@ module DiscourseTheme
57
57
  raise DiscourseTheme::ThemeError.new "git is not installed" if !command?("git")
58
58
  raise DiscourseTheme::ThemeError.new "yarn is not installed" if !command?("yarn")
59
59
 
60
- DiscourseTheme::Scaffold.generate(dir)
60
+ DiscourseTheme::Scaffold.generate(dir, name: args[1])
61
61
  watch_theme?(args)
62
62
  elsif command == "watch"
63
63
  raise DiscourseTheme::ThemeError.new "'#{dir} does not exist" unless Dir.exist?(dir)
@@ -116,7 +116,7 @@ module DiscourseTheme
116
116
  UI.progress "Uploading theme from #{dir}"
117
117
 
118
118
  settings.theme_id =
119
- theme_id = uploader.upload_full_theme(ignore_files: ignored_migrations(theme, dir))
119
+ theme_id = uploader.upload_full_theme(skip_migrations: skip_migrations(theme, dir))
120
120
 
121
121
  UI.success "Theme uploaded (id:#{theme_id})"
122
122
  UI.info "Preview: #{client.url}/?preview_theme_id=#{theme_id}"
@@ -131,7 +131,7 @@ module DiscourseTheme
131
131
 
132
132
  watcher = DiscourseTheme::Watcher.new(dir: dir, uploader: uploader)
133
133
  UI.progress "Watching for changes in #{dir}..."
134
- watcher.watch(&block)
134
+ watcher.watch
135
135
  elsif command == "download"
136
136
  client = DiscourseTheme::Client.new(dir, settings, reset: reset)
137
137
  downloader = DiscourseTheme::Downloader.new(dir: dir, client: client)
@@ -205,40 +205,41 @@ module DiscourseTheme
205
205
 
206
206
  private
207
207
 
208
- def ignored_migrations(theme, dir)
209
- return [] unless theme && Dir.exist?(File.join(dir, "migrations"))
208
+ def skip_migrations(theme, dir)
209
+ return true unless theme && Dir.exist?(File.join(dir, "migrations"))
210
210
 
211
- existing_migrations =
211
+ migrated_migrations =
212
212
  theme
213
213
  .dig("theme_fields")
214
214
  &.filter_map do |theme_field|
215
- theme_field["name"] if theme_field["target"] == "migrations"
215
+ if theme_field["target"] == "migrations" && theme_field["migrated"] == true
216
+ theme_field["name"]
217
+ end
216
218
  end || []
217
219
 
218
- new_migrations =
220
+ pending_migrations =
219
221
  Dir["#{dir}/migrations/**/*.js"]
220
222
  .reject do |f|
221
- existing_migrations.any? do |existing_migration|
223
+ migrated_migrations.any? do |existing_migration|
222
224
  File.basename(f).include?(existing_migration)
223
225
  end
224
226
  end
225
227
  .map { |f| Pathname.new(f).relative_path_from(Pathname.new(dir)).to_s }
226
228
 
227
- if !new_migrations.empty?
228
- options = { "Yes" => :yes, "No" => :no }
229
+ return true if pending_migrations.empty?
230
+
231
+ options = { "No" => :no, "Yes" => :yes }
229
232
 
230
- choice = UI.select(<<~TEXT, options.keys)
231
- Would you like to upload and run the following pending theme migration(s): #{new_migrations.join(", ")}
233
+ choice = UI.select(<<~TEXT, options.keys)
234
+ Would you like to run the following pending theme migration(s): #{pending_migrations.join(", ")}
235
+ Select 'No' if you are in the midst of adding or modifying theme migration(s).
232
236
  TEXT
233
237
 
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
238
+ if options[choice] == :no
239
+ UI.warn "Pending theme migrations have not been run, run `discourse_theme upload #{dir}` if you wish to run the theme migrations."
240
+ true
240
241
  else
241
- []
242
+ false
242
243
  end
243
244
  end
244
245
 
@@ -73,7 +73,7 @@ module DiscourseTheme
73
73
  success = exit_status.success?
74
74
 
75
75
  unless success
76
- UI.error "Error occured while running: `#{command}`:\n\n#{output}" unless stream
76
+ UI.error "Error occurred while running: `#{command}`:\n\n#{output}" unless stream
77
77
  exit 1 if exit_on_error
78
78
  end
79
79
  end
@@ -84,7 +84,7 @@ module DiscourseTheme
84
84
  request(put)
85
85
  end
86
86
 
87
- def upload_full_theme(tgz, theme_id:, components:)
87
+ def upload_full_theme(tgz, theme_id:, components:, skip_migrations: false)
88
88
  endpoint =
89
89
  root +
90
90
  (
@@ -95,13 +95,15 @@ module DiscourseTheme
95
95
  end
96
96
  )
97
97
 
98
- post =
99
- Net::HTTP::Post::Multipart.new(
100
- endpoint,
101
- "theme_id" => theme_id,
102
- "components" => components,
103
- "bundle" => UploadIO.new(tgz, "application/tar+gzip", "bundle.tar.gz"),
104
- )
98
+ params = {
99
+ "theme_id" => theme_id,
100
+ "components" => components,
101
+ "bundle" => UploadIO.new(tgz, "application/tar+gzip", "bundle.tar.gz"),
102
+ }
103
+
104
+ params["skip_migrations"] = true if skip_migrations
105
+
106
+ post = Net::HTTP::Post::Multipart.new(endpoint, params)
105
107
  request(post)
106
108
  end
107
109
 
@@ -2,159 +2,111 @@
2
2
 
3
3
  require "date"
4
4
  require "json"
5
+ require "yaml"
6
+ require "resolv"
5
7
 
6
8
  module DiscourseTheme
7
9
  class Scaffold
8
- ABOUT_JSON = {
9
- about_url: "TODO: Put your theme's public repo or Meta topic URL here",
10
- license_url: "TODO: Put your theme's LICENSE URL here",
11
- assets: {
12
- },
13
- }
14
-
15
- HELP = <<~STR
16
- Are you a bit lost? Be sure to read https://meta.discourse.org/t/how-to-develop-custom-themes/60848
17
- STR
18
-
19
- LICENSE = <<~STR
20
- Copyright #YEAR #AUTHOR
21
-
22
- Permission is hereby granted, free of charge, to any person obtaining a copy
23
- of this software and associated documentation files (the "Software"), to deal
24
- in the Software without restriction, including without limitation the rights
25
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
26
- copies of the Software, and to permit persons to whom the Software is
27
- furnished to do so, subject to the following conditions:
28
-
29
- The above copyright notice and this permission notice shall be included in all
30
- copies or substantial portions of the Software.
31
-
32
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
33
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
34
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
35
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
36
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
37
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
38
- SOFTWARE.
39
- STR
40
-
41
- GIT_IGNORE = <<~STR
42
- .discourse-site
43
- node_modules
44
- HELP
45
- STR
46
-
47
- API_INITIALIZER = <<~STR
48
- import { apiInitializer } from "discourse/lib/api";
49
-
50
- export default apiInitializer("1.8.0", (api) => {
51
- console.log("hello world from api initializer!");
52
- });
53
- STR
54
-
55
- PACKAGE_JSON = <<~STR
56
- {
57
- "author": "#AUTHOR",
58
- "license": "MIT",
59
- "devDependencies": {
60
- "eslint-config-discourse": "latest"
61
- }
62
- }
63
- STR
64
-
65
- ESLINT_RC = <<~STR
66
- {
67
- "extends": "eslint-config-discourse",
68
- "globals": {
69
- "settings": "readonly",
70
- "themePrefix": "readonly"
71
- }
72
- }
73
- STR
74
-
75
- TEMPLATE_LINT_RC = <<~STR
76
- module.exports = {
77
- plugins: ["ember-template-lint-plugin-discourse"],
78
- extends: "discourse:recommended",
79
- };
80
- STR
81
-
82
- EN_YML = <<~YAML
83
- en:
84
- theme_metadata:
85
- description: "#DESCRIPTION"
86
- YAML
87
-
88
- SETTINGS_YML = <<~YAML
89
- todo_rename_and_use_setting:
90
- default: ""
91
- YAML
92
-
93
- def self.generate(dir)
10
+ def self.generate(dir, name:)
94
11
  UI.progress "Generating a scaffold theme at #{dir}"
95
12
 
96
- name =
97
- loop do
98
- input = UI.ask("What would you like to call your theme?").to_s.strip
99
- if input.empty?
100
- UI.error("Theme name cannot be empty")
101
- else
102
- break input
103
- end
104
- end
105
-
13
+ name = UI.ask("What would you like to call your theme?", default: name).to_s.strip
106
14
  is_component = UI.yes?("Is this a component?")
107
15
 
108
- FileUtils.mkdir_p dir
109
- Dir.chdir dir do
110
- author =
111
- loop do
112
- input = UI.ask("Who is authoring the theme?", default: ENV["USER"]).to_s.strip
113
- if input.empty?
114
- UI.error("Author cannot be empty")
115
- else
116
- break input
117
- end
118
- end
16
+ get_theme_skeleton(dir)
119
17
 
18
+ Dir.chdir dir do
19
+ author = UI.ask("Who is authoring the theme?", default: "Discourse").to_s.strip
120
20
  description = UI.ask("How would you describe this theme?").to_s.strip
121
21
 
122
- about_template = ABOUT_JSON.dup
123
- about_template[:name] = name
124
- if is_component
125
- about_template[:component] = true
126
- else
127
- about_template[:color_schemes] = {}
22
+ about = JSON.parse(File.read("about.json"))
23
+ about["name"] = name
24
+ about["authors"] = author
25
+ if !is_component
26
+ about.delete("component")
27
+ about["color_schemes"] = {}
128
28
  end
29
+ File.write("about.json", JSON.pretty_generate(about))
30
+
31
+ if author != "Discourse"
32
+ license = File.read("LICENSE")
33
+ license.sub!(/^(Copyright\s\(c\))\s(.+)/, "\\1 #{author}")
34
+ File.write("LICENSE", license)
35
+ end
36
+
37
+ readme = File.read("README.md")
38
+ readme.sub!("**Theme Name**", name)
39
+ File.write("README.md", readme)
129
40
 
130
- encoded_name = name.downcase.gsub(/[^a-zA-Z0-9_-]+/, "_")
41
+ encoded_name = name.downcase.gsub(/[^a-zA-Z0-9_-]+/, "-")
42
+ FileUtils.mv(
43
+ "javascripts/discourse/api-initializers/todo.js",
44
+ "javascripts/discourse/api-initializers/#{encoded_name}.js",
45
+ )
131
46
 
132
- write("about.json", JSON.pretty_generate(about_template))
133
- write("HELP", HELP)
134
- write("LICENSE", LICENSE.sub("#YEAR", "#{Date.today.year}").sub("#AUTHOR", author))
135
- write(".eslintrc", ESLINT_RC)
136
- write(".gitignore", GIT_IGNORE)
137
- write(".template-lintrc.js", TEMPLATE_LINT_RC)
138
- write("package.json", PACKAGE_JSON.sub("#AUTHOR", author))
139
- write("settings.yml", SETTINGS_YML)
140
- write("common/common.scss", "")
141
- write("javascripts/discourse/api-initializers/#{encoded_name}.js", API_INITIALIZER)
142
- write("locales/en.yml", EN_YML.sub("#DESCRIPTION", description))
47
+ i18n = YAML.safe_load(File.read("locales/en.yml"))
48
+ i18n["en"]["theme_metadata"]["description"] = description
49
+ File.write("locales/en.yml", YAML.safe_dump(i18n).sub(/\A---\n/, ""))
143
50
 
144
51
  UI.info "Initializing git repo"
145
- puts `git init && git symbolic-ref HEAD refs/heads/main`
52
+ FileUtils.rm_rf(".git")
53
+ FileUtils.rm_rf("**/.gitkeep")
54
+ system "git", "init", exception: true
55
+ system "git", "symbolic-ref", "HEAD", "refs/heads/main", exception: true
56
+ root_files = Dir.glob("*").select { |f| File.file?(f) }
57
+ system "git", "add", *root_files, exception: true
58
+ system "git", "add", ".*", exception: true
59
+ system "git", "add", "locales", exception: true
60
+ system "git",
61
+ "commit",
62
+ "-m",
63
+ "Initial commit by `discourse_theme` CLI",
64
+ "--quiet",
65
+ exception: true
146
66
 
147
67
  UI.info "Installing dependencies"
148
- puts `yarn`
68
+ system "yarn", exception: true
149
69
  end
70
+
71
+ puts "✅ Done!"
72
+ puts "See https://meta.discourse.org/t/how-to-develop-custom-themes/60848 for more information!"
150
73
  end
151
74
 
152
75
  private
153
76
 
154
- def self.write(filename, contents)
155
- UI.info "Creating #{filename}"
156
- FileUtils.mkdir_p(File.dirname(filename))
157
- File.write(filename, contents)
77
+ def self.get_theme_skeleton(dir)
78
+ if online?
79
+ puts "Downloading discourse-theme-skeleton"
80
+ tmp = Dir.mktmpdir
81
+ system "git",
82
+ "clone",
83
+ "https://github.com/discourse/discourse-theme-skeleton",
84
+ tmp,
85
+ "--depth",
86
+ "1",
87
+ "--quiet",
88
+ exception: true
89
+ FileUtils.rm_rf(skeleton_dir)
90
+ # Store the local copy for offline use
91
+ FileUtils.cp_r(tmp, skeleton_dir)
92
+
93
+ FileUtils.cp_r(skeleton_dir, dir)
94
+ elsif Dir.exist?(skeleton_dir)
95
+ puts "⚠️ No internet connection detected, using the local copy of discourse-theme-skeleton"
96
+ FileUtils.cp_r(skeleton_dir, dir)
97
+ else
98
+ raise "🛑 Couldn't download discourse-theme-skeleton"
99
+ end
100
+ end
101
+
102
+ def self.online?
103
+ !!Resolv::DNS.new.getaddress("github.com")
104
+ rescue Resolv::ResolvError => e
105
+ false
106
+ end
107
+
108
+ def self.skeleton_dir
109
+ File.expand_path("~/.discourse_theme_skeleton")
158
110
  end
159
111
  end
160
112
  end
@@ -1,20 +1,6 @@
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
-
18
4
  def initialize(dir:, client:, theme_id: nil, components: nil)
19
5
  @dir = dir
20
6
  @client = client
@@ -67,27 +53,19 @@ module DiscourseTheme
67
53
  UI.error "(end of errors)" if diagnose_errors(json) != 0
68
54
  end
69
55
 
70
- def upload_full_theme(ignore_files: [])
56
+ def upload_full_theme(skip_migrations: false)
71
57
  filename = "#{Pathname.new(Dir.tmpdir).realpath}/bundle_#{SecureRandom.hex}.tar.gz"
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
58
 
87
- compress_dir(filename, theme_dir)
59
+ compress_dir(filename, @dir)
88
60
 
89
61
  File.open(filename) do |tgz|
90
- response = @client.upload_full_theme(tgz, theme_id: @theme_id, components: @components)
62
+ response =
63
+ @client.upload_full_theme(
64
+ tgz,
65
+ theme_id: @theme_id,
66
+ components: @components,
67
+ skip_migrations: skip_migrations,
68
+ )
91
69
 
92
70
  json = JSON.parse(response.body)
93
71
  @theme_id = json["theme"]["id"]
@@ -95,7 +73,6 @@ module DiscourseTheme
95
73
  @theme_id
96
74
  end
97
75
  ensure
98
- FileUtils.rm_rf(temp_dir) if temp_dir
99
76
  FileUtils.rm_f(filename)
100
77
  end
101
78
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module DiscourseTheme
3
- VERSION = "1.1.0"
3
+ VERSION = "2.1.0"
4
4
  end
@@ -1,33 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
  module DiscourseTheme
3
3
  class Watcher
4
- LISTEN_IGNORE_PATTERNS = [%r{migrations/.+/.+\.js}]
5
-
6
4
  def self.return_immediately!
7
5
  @return_immediately = true
8
6
  end
9
7
 
10
- def self.return_immediately=(val)
11
- @return_immediately = val
12
- end
13
-
14
8
  def self.return_immediately?
15
9
  !!@return_immediately
16
10
  end
17
11
 
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
-
31
12
  def initialize(dir:, uploader:)
32
13
  @dir = dir
33
14
  @uploader = uploader
@@ -35,9 +16,7 @@ module DiscourseTheme
35
16
 
36
17
  def watch
37
18
  listener =
38
- Listen.to(@dir, ignore: LISTEN_IGNORE_PATTERNS) do |modified, added, removed|
39
- yield(modified, added, removed) if block_given?
40
-
19
+ Listen.to(@dir) do |modified, added, removed|
41
20
  begin
42
21
  if modified.length == 1 && added.length == 0 && removed.length == 0 &&
43
22
  (resolved = resolve_file(modified[0]))
@@ -60,7 +39,7 @@ module DiscourseTheme
60
39
  UI.progress "Detected changes in #{filename.gsub(@dir, "")}, uploading theme"
61
40
  end
62
41
 
63
- @uploader.upload_full_theme
42
+ @uploader.upload_full_theme(skip_migrations: true)
64
43
  end
65
44
  UI.success "Done! Watching for changes..."
66
45
  rescue DiscourseTheme::ThemeError => e
@@ -70,8 +49,7 @@ module DiscourseTheme
70
49
  end
71
50
 
72
51
  listener.start
73
- self.class.call_start_subscribers
74
- sleep 1 while !self.class.return_immediately?
52
+ sleep if !self.class.return_immediately?
75
53
  end
76
54
 
77
55
  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.1.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Saffron
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-10 00:00:00.000000000 Z
11
+ date: 2024-02-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitar
@@ -72,14 +72,14 @@ dependencies:
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '1.2'
75
+ version: '2.3'
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '1.2'
82
+ version: '2.3'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: selenium-webdriver
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -178,34 +178,20 @@ dependencies:
178
178
  - - ">="
179
179
  - !ruby/object:Gem::Version
180
180
  version: '0'
181
- - !ruby/object:Gem::Dependency
182
- name: rubocop
183
- requirement: !ruby/object:Gem::Requirement
184
- requirements:
185
- - - ">="
186
- - !ruby/object:Gem::Version
187
- version: '0'
188
- type: :development
189
- prerelease: false
190
- version_requirements: !ruby/object:Gem::Requirement
191
- requirements:
192
- - - ">="
193
- - !ruby/object:Gem::Version
194
- version: '0'
195
181
  - !ruby/object:Gem::Dependency
196
182
  name: rubocop-discourse
197
183
  requirement: !ruby/object:Gem::Requirement
198
184
  requirements:
199
- - - ">="
185
+ - - "~>"
200
186
  - !ruby/object:Gem::Version
201
- version: '0'
187
+ version: 3.6.0
202
188
  type: :development
203
189
  prerelease: false
204
190
  version_requirements: !ruby/object:Gem::Requirement
205
191
  requirements:
206
- - - ">="
192
+ - - "~>"
207
193
  - !ruby/object:Gem::Version
208
- version: '0'
194
+ version: 3.6.0
209
195
  - !ruby/object:Gem::Dependency
210
196
  name: m
211
197
  requirement: !ruby/object:Gem::Requirement
@@ -234,20 +220,6 @@ dependencies:
234
220
  - - ">="
235
221
  - !ruby/object:Gem::Version
236
222
  version: '0'
237
- - !ruby/object:Gem::Dependency
238
- name: syntax_tree-disable_ternary
239
- requirement: !ruby/object:Gem::Requirement
240
- requirements:
241
- - - ">="
242
- - !ruby/object:Gem::Version
243
- version: '0'
244
- type: :development
245
- prerelease: false
246
- version_requirements: !ruby/object:Gem::Requirement
247
- requirements:
248
- - - ">="
249
- - !ruby/object:Gem::Version
250
- version: '0'
251
223
  - !ruby/object:Gem::Dependency
252
224
  name: mocha
253
225
  requirement: !ruby/object:Gem::Requirement
@@ -298,7 +270,7 @@ homepage: https://github.com/discourse/discourse_theme
298
270
  licenses:
299
271
  - MIT
300
272
  metadata: {}
301
- post_install_message:
273
+ post_install_message:
302
274
  rdoc_options: []
303
275
  require_paths:
304
276
  - lib
@@ -313,8 +285,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
313
285
  - !ruby/object:Gem::Version
314
286
  version: '0'
315
287
  requirements: []
316
- rubygems_version: 3.1.6
317
- signing_key:
288
+ rubygems_version: 3.5.3
289
+ signing_key:
318
290
  specification_version: 4
319
291
  summary: CLI helper for creating Discourse themes
320
292
  test_files: []