discourse_theme 0.7.5 → 0.8.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: fa9710726909f2b5a1381132fb5e68748965bf8af6cf50893c013126e1c6db0d
4
- data.tar.gz: 6446feb3d912101d7193a07776d4aa5dc476fd00ef649e7b4c94e10e1ac21b56
3
+ metadata.gz: 8115db0a38be583770d879d2c54bf167e27d1f05582ec38144c8598d1b3111d8
4
+ data.tar.gz: 1963461e7ea2b640514b2ef049ee968d619fc6163c67e0e039969fbe04db23d1
5
5
  SHA512:
6
- metadata.gz: 72cead3a6060f62bc7e3fd225b82a98ee59e0852559506bcd2d5bd0f83196e4372ca1331c14654d51edc9ff20dad665a7c29777391db85789b4d6367b61a64ea
7
- data.tar.gz: 65b6d6b3d547867b706be85beab21f7d2a47daa521e1b9a5dbd71420a80126a32740f8f3286d5c6ab5c52ee85b92ea9e71a7395def9f2ed8ec4d6bc6aa7f0959
6
+ metadata.gz: c4e0de4798c6667049fbcd3ad97e50f17d3677972d269916f7fa11e0e4a3d310373a6eb58242dad20d3b7fec4f1de4c0b3c255fed30fe0b15e89dce9cac723d8
7
+ data.tar.gz: e70dad03335fb5dcd6c2f3a074d4e0aca04aba798fc31bc52c9a6137b8422f46da12a1497543d104767907473b6e5e411cd592e41e68a218112873bb5c619107
data/CHANGELOG.md ADDED
@@ -0,0 +1,12 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.7.6] - 2023-09-16
9
+
10
+ ### Fixed
11
+
12
+ - Remove trailing slash when storing URL (#25)
@@ -1,7 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
  module DiscourseTheme
3
3
  class Client
4
- THEME_CREATOR_REGEX = /^https:\/\/(theme-creator\.discourse\.org|discourse\.theme-creator\.io)$/i
4
+ THEME_CREATOR_REGEX =
5
+ %r{^https://(theme-creator\.discourse\.org|discourse\.theme-creator\.io)$}i
5
6
 
6
7
  attr_reader :url
7
8
 
@@ -23,17 +24,17 @@ module DiscourseTheme
23
24
 
24
25
  # From https://github.com/discourse/discourse/blob/main/lib/version.rb
25
26
  def self.has_needed_version?(current, needed)
26
- current_split = current.split('.')
27
- needed_split = needed.split('.')
27
+ current_split = current.split(".")
28
+ needed_split = needed.split(".")
28
29
 
29
30
  (0..[current_split.size, needed_split.size].max).each do |idx|
30
- current_str = current_split[idx] || ''
31
+ current_str = current_split[idx] || ""
31
32
 
32
- c0 = (needed_split[idx] || '').sub('beta', '').to_i
33
- c1 = (current_str || '').sub('beta', '').to_i
33
+ c0 = (needed_split[idx] || "").sub("beta", "").to_i
34
+ c1 = (current_str || "").sub("beta", "").to_i
34
35
 
35
36
  # beta is less than stable
36
- return false if current_str.include?('beta') && (c0 == 0) && (c1 > 0)
37
+ return false if current_str.include?("beta") && (c0 == 0) && (c1 > 0)
37
38
 
38
39
  return true if c1 > c0
39
40
  return false if c0 > c1
@@ -43,12 +44,7 @@ module DiscourseTheme
43
44
  end
44
45
 
45
46
  def get_themes_list
46
- endpoint = root +
47
- if @is_theme_creator
48
- "/user_themes.json"
49
- else
50
- "/admin/customize/themes.json"
51
- end
47
+ endpoint = root + (@is_theme_creator ? "/user_themes.json" : "/admin/customize/themes.json")
52
48
 
53
49
  response = request(Net::HTTP::Get.new(endpoint), never_404: true)
54
50
  json = JSON.parse(response.body)
@@ -56,12 +52,9 @@ module DiscourseTheme
56
52
  end
57
53
 
58
54
  def get_raw_theme_export(id)
59
- endpoint = root +
60
- if @is_theme_creator
61
- "/user_themes/#{id}/export"
62
- else
63
- "/admin/customize/themes/#{id}/export"
64
- end
55
+ endpoint =
56
+ root +
57
+ (@is_theme_creator ? "/user_themes/#{id}/export" : "/admin/customize/themes/#{id}/export")
65
58
 
66
59
  response = request(Net::HTTP::Get.new endpoint)
67
60
  raise "Error downloading theme: #{response.code}" unless response.code.to_i == 200
@@ -70,32 +63,24 @@ module DiscourseTheme
70
63
  end
71
64
 
72
65
  def update_theme(id, args)
73
- endpoint = root +
74
- if @is_theme_creator
75
- "/user_themes/#{id}"
76
- else
77
- "/admin/themes/#{id}"
78
- end
66
+ endpoint = root + (@is_theme_creator ? "/user_themes/#{id}" : "/admin/themes/#{id}")
79
67
 
80
- put = Net::HTTP::Put.new(endpoint, 'Content-Type' => 'application/json')
68
+ put = Net::HTTP::Put.new(endpoint, "Content-Type" => "application/json")
81
69
  put.body = args.to_json
82
70
  request(put)
83
71
  end
84
72
 
85
73
  def upload_full_theme(tgz, theme_id:, components:)
86
- endpoint = root +
87
- if @is_theme_creator
88
- "/user_themes/import.json"
89
- else
90
- "/admin/themes/import.json"
91
- end
92
-
93
- post = Net::HTTP::Post::Multipart.new(
94
- endpoint,
95
- "theme_id" => theme_id,
96
- "components" => components,
97
- "bundle" => UploadIO.new(tgz, "application/tar+gzip", "bundle.tar.gz")
98
- )
74
+ endpoint =
75
+ root + (@is_theme_creator ? "/user_themes/import.json" : "/admin/themes/import.json")
76
+
77
+ post =
78
+ Net::HTTP::Post::Multipart.new(
79
+ endpoint,
80
+ "theme_id" => theme_id,
81
+ "components" => components,
82
+ "bundle" => UploadIO.new(tgz, "application/tar+gzip", "bundle.tar.gz"),
83
+ )
99
84
  request(post)
100
85
  end
101
86
 
@@ -132,14 +117,21 @@ module DiscourseTheme
132
117
  http = Net::HTTP.new(uri.host, uri.port)
133
118
  http.use_ssl = URI::HTTPS === uri
134
119
  add_headers(request)
135
- http.request(request).tap do |response|
136
- if response.code == '404' && never_404
137
- raise DiscourseTheme::ThemeError.new "Error: Incorrect site URL, or API key does not have the correct privileges"
138
- elsif !['200', '201'].include?(response.code)
139
- errors = JSON.parse(response.body)["errors"].join(', ') rescue nil
140
- raise DiscourseTheme::ThemeError.new "Error #{response.code} for #{request.path.split("?")[0]}#{(": " + errors) if errors}"
120
+ http
121
+ .request(request)
122
+ .tap do |response|
123
+ if response.code == "404" && never_404
124
+ raise DiscourseTheme::ThemeError.new "Error: Incorrect site URL, or API key does not have the correct privileges"
125
+ elsif !%w[200 201].include?(response.code)
126
+ errors =
127
+ begin
128
+ JSON.parse(response.body)["errors"].join(", ")
129
+ rescue StandardError
130
+ nil
131
+ end
132
+ raise DiscourseTheme::ThemeError.new "Error #{response.code} for #{request.path.split("?")[0]}#{(": " + errors) if errors}"
133
+ end
141
134
  end
142
- end
143
135
  rescue Errno::ECONNREFUSED
144
136
  raise DiscourseTheme::ThemeError.new "Connection refused for #{request.path}"
145
137
  end
@@ -153,19 +145,17 @@ module DiscourseTheme
153
145
  end
154
146
 
155
147
  def guess_url(settings)
156
- url = ENV['DISCOURSE_URL']
157
- if url
158
- UI.progress "Using #{url} from DISCOURSE_URL"
159
- end
148
+ url = normalize_url(ENV["DISCOURSE_URL"])
149
+ UI.progress "Using #{url} from DISCOURSE_URL" if url
160
150
 
161
151
  if !url && settings.url
162
- url = settings.url
152
+ url = normalize_url(settings.url)
163
153
  UI.progress "Using #{url} from #{DiscourseTheme::Cli.settings_file}"
164
154
  end
165
155
 
166
156
  if !url || @reset
167
- url = UI.ask("What is the root URL of your Discourse site?", default: url).strip
168
- url = "http://#{url}" unless url =~ /^https?:\/\//
157
+ url = normalize_url(UI.ask("What is the root URL of your Discourse site?", default: url))
158
+ url = "http://#{url}" unless url =~ %r{^https?://}
169
159
 
170
160
  # maybe this is an HTTPS redirect
171
161
  uri = URI.parse(url)
@@ -184,11 +174,13 @@ module DiscourseTheme
184
174
  url
185
175
  end
186
176
 
177
+ def normalize_url(url)
178
+ url&.strip&.chomp("/")
179
+ end
180
+
187
181
  def guess_api_key(settings)
188
- api_key = ENV['DISCOURSE_API_KEY']
189
- if api_key
190
- UI.progress "Using api key from DISCOURSE_API_KEY"
191
- end
182
+ api_key = ENV["DISCOURSE_API_KEY"]
183
+ UI.progress "Using api key from DISCOURSE_API_KEY" if api_key
192
184
 
193
185
  if !api_key && settings.api_key
194
186
  api_key = settings.api_key
@@ -213,8 +205,7 @@ module DiscourseTheme
213
205
  path = "/" if path.empty?
214
206
  req = Net::HTTP::Get.new("/")
215
207
  response = Net::HTTP.start(url.host, url.port) { |http| http.request(req) }
216
- Net::HTTPRedirection === response && response['location'] =~ /^https/i
208
+ Net::HTTPRedirection === response && response["location"] =~ /^https/i
217
209
  end
218
-
219
210
  end
220
211
  end
@@ -1,19 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'date'
3
4
  require 'json'
4
5
 
5
6
  module DiscourseTheme
6
7
  class Scaffold
7
8
 
8
- BLANK_FILES = %w{
9
- common/common.scss
10
-
11
- settings.yml
12
- }
13
-
14
9
  ABOUT_JSON = {
15
- about_url: nil,
16
- license_url: nil,
10
+ about_url: "TODO: Put your theme's public repo or Meta topic URL here",
11
+ license_url: "TODO: Put your theme's LICENSE URL here",
17
12
  assets: {}
18
13
  }
19
14
 
@@ -21,6 +16,28 @@ module DiscourseTheme
21
16
  Are you a bit lost? Be sure to read https://meta.discourse.org/t/how-to-develop-custom-themes/60848
22
17
  STR
23
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
+
24
41
  GIT_IGNORE = <<~STR
25
42
  .discourse-site
26
43
  node_modules
@@ -30,7 +47,7 @@ module DiscourseTheme
30
47
  API_INITIALIZER = <<~STR
31
48
  import { apiInitializer } from "discourse/lib/api";
32
49
 
33
- export default apiInitializer("0.11.1", api => {
50
+ export default apiInitializer("1.8.0", (api) => {
34
51
  console.log("hello world from api initializer!");
35
52
  });
36
53
  STR
@@ -68,6 +85,11 @@ module DiscourseTheme
68
85
  description: "#DESCRIPTION"
69
86
  YAML
70
87
 
88
+ SETTINGS_YML = <<~YAML
89
+ todo_rename_and_use_setting:
90
+ default: ""
91
+ YAML
92
+
71
93
  def self.generate(dir)
72
94
  UI.progress "Generating a scaffold theme at #{dir}"
73
95
 
@@ -95,7 +117,6 @@ module DiscourseTheme
95
117
 
96
118
  description = UI.ask("How would you describe this theme?").to_s.strip
97
119
 
98
- UI.info "Creating about.json"
99
120
  about_template = ABOUT_JSON.dup
100
121
  about_template[:name] = name
101
122
  if is_component
@@ -103,46 +124,35 @@ module DiscourseTheme
103
124
  else
104
125
  about_template[:color_schemes] = {}
105
126
  end
106
- File.write('about.json', JSON.pretty_generate(about_template))
107
-
108
- UI.info "Creating HELP"
109
- File.write('HELP', HELP)
110
-
111
- UI.info "Creating package.json"
112
- File.write('package.json', PACKAGE_JSON.sub("#AUTHOR", author))
113
-
114
- UI.info "Creating .template-lintrc.js"
115
- File.write('.template-lintrc.js', TEMPLATE_LINT_RC)
116
-
117
- UI.info "Creating .eslintrc"
118
- File.write('.eslintrc', ESLINT_RC)
119
-
120
- UI.info "Creating .gitignore"
121
- File.write('.gitignore', GIT_IGNORE)
122
-
123
- locale = "locales/en.yml"
124
- UI.info "Creating #{locale}"
125
- FileUtils.mkdir_p(File.dirname(locale))
126
- File.write(locale, EN_YML.sub("#DESCRIPTION", description))
127
127
 
128
128
  encoded_name = name.downcase.gsub(/[^a-zA-Z0-9_-]+/, '_')
129
- initializer = "javascripts/discourse/api-initializers/#{encoded_name}.js"
130
- UI.info "Creating #{initializer}"
131
- FileUtils.mkdir_p(File.dirname(initializer))
132
- File.write(initializer, API_INITIALIZER)
133
-
134
- BLANK_FILES.each do |f|
135
- UI.info "Creating #{f}"
136
- FileUtils.mkdir_p File.dirname(f)
137
- FileUtils.touch f
138
- end
129
+
130
+ write('about.json', JSON.pretty_generate(about_template))
131
+ write('HELP', HELP)
132
+ write('LICENSE', LICENSE.sub("#YEAR", "#{Date.today.year}").sub("#AUTHOR", author))
133
+ write('.eslintrc', ESLINT_RC)
134
+ write('.gitignore', GIT_IGNORE)
135
+ write('.template-lintrc.js', TEMPLATE_LINT_RC)
136
+ write('package.json', PACKAGE_JSON.sub("#AUTHOR", author))
137
+ write('settings.yml', SETTINGS_YML)
138
+ write('common/common.scss', '')
139
+ write("javascripts/discourse/api-initializers/#{encoded_name}.js", API_INITIALIZER)
140
+ write('locales/en.yml', EN_YML.sub("#DESCRIPTION", description))
139
141
 
140
142
  UI.info "Initializing git repo"
141
- puts `git init . --initial-branch=main`
143
+ puts `git init && git symbolic-ref HEAD refs/heads/main`
142
144
 
143
145
  UI.info "Installing dependencies"
144
146
  puts `yarn`
145
147
  end
146
148
  end
149
+
150
+ private
151
+
152
+ def self.write(filename, contents)
153
+ UI.info "Creating #{filename}"
154
+ FileUtils.mkdir_p(File.dirname(filename))
155
+ File.write(filename, contents)
156
+ end
147
157
  end
148
158
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module DiscourseTheme
3
- VERSION = "0.7.5"
3
+ VERSION = "0.8.0"
4
4
  end
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: 0.7.5
4
+ version: 0.8.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: 2023-02-03 00:00:00.000000000 Z
11
+ date: 2023-09-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitar
@@ -217,6 +217,7 @@ files:
217
217
  - ".github/workflows/ci.yml"
218
218
  - ".gitignore"
219
219
  - ".rubocop.yml"
220
+ - CHANGELOG.md
220
221
  - CODE_OF_CONDUCT.md
221
222
  - Gemfile
222
223
  - Guardfile