textbringer-plugin-generator 0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: b2ebbaedd12e8043bd3cd2c0adb3f9e6681d9874c846e11fcca0b93dc24b5000
4
+ data.tar.gz: 40564380d2ab43084500b231105ba6bd89683c58c0175f1e675b64f66af9676e
5
+ SHA512:
6
+ metadata.gz: 2db0f992690552f9896e2a3b431349e1274b01f3a89cc4938a8e7697f26bc3e12bde84240f0c14c40c5af3d69ce0924a571d581a3f2fb515a528e103817a9b8a
7
+ data.tar.gz: 5805288a8113efe6092c9e3882b46d98ebac0ac5ef39daea68a383a3a64ac9f08c94071d410ad5d7bdfbbf2a1fcb429d77165723ee0f66b8d90eaa810853c0f8
@@ -0,0 +1,28 @@
1
+ name: Release to RubyGems
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*'
7
+
8
+ jobs:
9
+ release:
10
+ runs-on: ubuntu-latest
11
+ permissions:
12
+ contents: read
13
+ id-token: write
14
+
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+
18
+ - name: Set up Ruby
19
+ uses: ruby/setup-ruby@v1
20
+ with:
21
+ ruby-version: '3.2'
22
+ bundler-cache: true
23
+
24
+ - name: Build gem
25
+ run: gem build textbringer-plugin-generator.gemspec
26
+
27
+ - name: Publish to RubyGems
28
+ uses: rubygems/release-gem@v1
data/LICENSE.txt ADDED
@@ -0,0 +1,13 @@
1
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
2
+ Version 2, December 2004
3
+
4
+ Copyright (C) 2026 yancya <yancya@upec.jp>
5
+
6
+ Everyone is permitted to copy and distribute verbatim or modified
7
+ copies of this license document, and changing it is allowed as long
8
+ as the name is changed.
9
+
10
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
11
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
12
+
13
+ 0. You just DO WHAT THE FUCK YOU WANT TO.
data/README.md ADDED
@@ -0,0 +1,56 @@
1
+ # Textbringer Plugin Generator
2
+
3
+ A command-line tool to generate Textbringer plugin scaffolding with proper structure, tests, GitHub Actions, and documentation.
4
+
5
+ ## Features
6
+
7
+ Generates a complete Textbringer plugin project with:
8
+
9
+ - ✅ Proper directory structure with `lib/textbringer_plugin.rb` for automatic loading
10
+ - ✅ Test::Unit test setup with Textbringer mocks
11
+ - ✅ GitHub Actions workflow for automated RubyGems release via OIDC (Trusted Publishing)
12
+ - ✅ Clean README template without TODOs
13
+ - ✅ CLAUDE.md for future AI assistance
14
+ - ✅ `.gitignore` with Gemfile.lock and .claude/ excluded
15
+ - ✅ Rakefile with test task
16
+ - ✅ Choice of license (MIT or WTFPL)
17
+
18
+ All based on best practices learned from developing real Textbringer plugins.
19
+
20
+ ## Installation
21
+
22
+ Install the gem by executing:
23
+
24
+ ```bash
25
+ gem install textbringer-plugin-generator
26
+ ```
27
+
28
+ ## Usage
29
+
30
+ Generate a new Textbringer plugin:
31
+
32
+ ```bash
33
+ textbringer-plugin new my-plugin
34
+ ```
35
+
36
+ This creates a new directory `textbringer-my-plugin` with all the necessary files.
37
+
38
+ ### Options
39
+
40
+ - `--license=[mit|wtfpl]` - Choose license (default: wtfpl)
41
+ - `--author=NAME` - Set author name (default: from git config)
42
+ - `--email=EMAIL` - Set author email (default: from git config)
43
+
44
+ ## Development
45
+
46
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests.
47
+
48
+ To install this gem onto your local machine, run `bundle exec rake install`.
49
+
50
+ ## Contributing
51
+
52
+ Bug reports and pull requests are welcome on GitHub at https://github.com/yancya/textbringer-plugin-generator.
53
+
54
+ ## License
55
+
56
+ The gem is available as open source under the terms of the [WTFPL](http://www.wtfpl.net/).
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rake/testtask"
5
+
6
+ Rake::TestTask.new(:test) do |t|
7
+ t.libs << "test"
8
+ t.libs << "lib"
9
+ t.test_files = FileList["test/**/*_test.rb"]
10
+ end
11
+
12
+ task default: :test
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "textbringer_plugin_generator"
6
+
7
+ Textbringer::Plugin::Generator::CLI.start(ARGV)
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "thor"
4
+
5
+ module Textbringer
6
+ module Plugin
7
+ module Generator
8
+ class CLI < Thor
9
+ def self.exit_on_failure?
10
+ true
11
+ end
12
+
13
+ desc "version", "Show version"
14
+ def version
15
+ puts "textbringer-plugin-generator #{VERSION}"
16
+ end
17
+
18
+ desc "new NAME", "Generate a new Textbringer plugin"
19
+ option :license, type: :string, default: "wtfpl", desc: "License (mit or wtfpl)"
20
+ option :author, type: :string, desc: "Author name"
21
+ option :email, type: :string, desc: "Author email"
22
+ def new(name)
23
+ generator = ::Textbringer::Plugin::Generator::Generator.new(name, options)
24
+ generator.generate
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Textbringer
4
+ module Plugin
5
+ module Generator
6
+ VERSION = "0.1.0"
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,397 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fileutils"
4
+
5
+ module Textbringer
6
+ module Plugin
7
+ module Generator
8
+ class Generator
9
+ attr_reader :name, :gem_name, :module_name, :class_name, :options
10
+
11
+ def initialize(name, options = {})
12
+ @name = name
13
+ @gem_name = "textbringer-#{name}"
14
+ @module_name = camelize(name)
15
+ @class_name = "#{camelize(name)}Mode"
16
+ @options = options
17
+ end
18
+
19
+ def generate
20
+ create_directory_structure
21
+ create_gemspec
22
+ create_gemfile
23
+ create_rakefile
24
+ create_gitignore
25
+ create_lib_files
26
+ create_test_files
27
+ create_readme
28
+ create_license
29
+ puts "Created #{gem_name}/"
30
+ end
31
+
32
+ private
33
+
34
+ def create_directory_structure
35
+ FileUtils.mkdir_p(gem_name)
36
+ FileUtils.mkdir_p("#{gem_name}/lib/textbringer/#{name}")
37
+ FileUtils.mkdir_p("#{gem_name}/test")
38
+ FileUtils.mkdir_p("#{gem_name}/.github/workflows")
39
+ end
40
+
41
+ def create_gemspec
42
+ content = <<~RUBY
43
+ # frozen_string_literal: true
44
+
45
+ require_relative "lib/textbringer/#{name}/version"
46
+
47
+ Gem::Specification.new do |spec|
48
+ spec.name = "#{gem_name}"
49
+ spec.version = Textbringer::#{module_name}::VERSION
50
+ spec.authors = [#{author.inspect}]
51
+ spec.email = [#{email.inspect}]
52
+
53
+ spec.summary = "#{module_name} mode for Textbringer"
54
+ spec.description = "A Textbringer plugin that provides #{name} mode support with syntax highlighting."
55
+ spec.homepage = "https://github.com/#{github_user}/#{gem_name}"
56
+ spec.license = "#{license_type.upcase}"
57
+ spec.required_ruby_version = ">= 3.2.0"
58
+
59
+ spec.metadata["allowed_push_host"] = "https://rubygems.org"
60
+ spec.metadata["homepage_uri"] = spec.homepage
61
+ spec.metadata["source_code_uri"] = "https://github.com/#{github_user}/#{gem_name}"
62
+
63
+ gemspec = File.basename(__FILE__)
64
+ spec.files = IO.popen(%w[git ls-files -z], chdir: __dir__, err: IO::NULL) do |ls|
65
+ ls.readlines("\\x0", chomp: true).reject do |f|
66
+ (f == gemspec) ||
67
+ f.start_with?(*%w[bin/ Gemfile .gitignore .rspec spec/ .github/])
68
+ end
69
+ end
70
+ spec.bindir = "exe"
71
+ spec.executables = spec.files.grep(%r{\\Aexe/}) { |f| File.basename(f) }
72
+ spec.require_paths = ["lib"]
73
+
74
+ spec.add_dependency "textbringer", ">= 1.0"
75
+ end
76
+ RUBY
77
+ File.write("#{gem_name}/#{gem_name}.gemspec", content)
78
+ end
79
+
80
+ def create_gemfile
81
+ content = <<~RUBY
82
+ # frozen_string_literal: true
83
+
84
+ source "https://rubygems.org"
85
+
86
+ gemspec
87
+
88
+ gem "irb"
89
+ gem "rake", "~> 13.0"
90
+ gem "test-unit"
91
+ RUBY
92
+ File.write("#{gem_name}/Gemfile", content)
93
+ end
94
+
95
+ def create_rakefile
96
+ content = <<~RUBY
97
+ # frozen_string_literal: true
98
+
99
+ require "bundler/gem_tasks"
100
+ require "rake/testtask"
101
+
102
+ Rake::TestTask.new(:test) do |t|
103
+ t.libs << "test"
104
+ t.libs << "lib"
105
+ t.test_files = FileList["test/**/*_test.rb"]
106
+ end
107
+
108
+ task default: :test
109
+ RUBY
110
+ File.write("#{gem_name}/Rakefile", content)
111
+ end
112
+
113
+ def create_gitignore
114
+ content = <<~TEXT
115
+ /.bundle/
116
+ /.yardoc
117
+ /_yardoc/
118
+ /coverage/
119
+ /doc/
120
+ /pkg/
121
+ /spec/reports/
122
+ /tmp/
123
+
124
+ # Bundler lockfile for gems
125
+ Gemfile.lock
126
+
127
+ # Claude Code settings
128
+ .claude/
129
+ TEXT
130
+ File.write("#{gem_name}/.gitignore", content)
131
+ end
132
+
133
+ def author
134
+ options[:author] || `git config user.name`.strip
135
+ end
136
+
137
+ def github_user
138
+ # Try to get GitHub username, fallback to sanitized author name
139
+ github = `git config github.user`.strip
140
+ return github unless github.empty?
141
+
142
+ # Remove spaces and non-alphanumeric characters for URL safety
143
+ author.gsub(/\s+/, '').gsub(/[^a-zA-Z0-9-]/, '')
144
+ end
145
+
146
+ def email
147
+ options[:email] || `git config user.email`.strip
148
+ end
149
+
150
+ def license_type
151
+ options[:license] || "wtfpl"
152
+ end
153
+
154
+ def create_lib_files
155
+ create_version_file
156
+ create_main_file
157
+ create_plugin_entry
158
+ end
159
+
160
+ def create_version_file
161
+ content = <<~RUBY
162
+ # frozen_string_literal: true
163
+
164
+ module Textbringer
165
+ module #{module_name}
166
+ VERSION = "0.1.0"
167
+ end
168
+ end
169
+ RUBY
170
+ File.write("#{gem_name}/lib/textbringer/#{name}/version.rb", content)
171
+ end
172
+
173
+ def create_main_file
174
+ content = <<~RUBY
175
+ # frozen_string_literal: true
176
+
177
+ require_relative "#{name}/version"
178
+
179
+ module Textbringer
180
+ # Define faces for syntax elements
181
+ # Face.define :#{name}_keyword, foreground: "cyan", bold: true
182
+
183
+ class #{class_name} < Mode
184
+ self.file_name_pattern = /\\.#{name}\\z/i
185
+
186
+ # Define your syntax highlighting here
187
+ # define_syntax :#{name}_keyword, /your_pattern/
188
+
189
+ def initialize(buffer)
190
+ super(buffer)
191
+ @buffer[:indent_tabs_mode] = false
192
+ @buffer[:tab_width] = 2
193
+ end
194
+ end
195
+ end
196
+ RUBY
197
+ File.write("#{gem_name}/lib/textbringer/#{name}.rb", content)
198
+ end
199
+
200
+ def create_plugin_entry
201
+ content = <<~RUBY
202
+ # frozen_string_literal: true
203
+
204
+ require "textbringer/#{name}"
205
+ RUBY
206
+ File.write("#{gem_name}/lib/textbringer_plugin.rb", content)
207
+ end
208
+
209
+ def create_test_files
210
+ create_test_helper
211
+ create_test_file
212
+ end
213
+
214
+ def create_test_helper
215
+ content = <<~RUBY
216
+ # frozen_string_literal: true
217
+
218
+ $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
219
+
220
+ # Mock Textbringer for testing without the actual dependency
221
+ module Textbringer
222
+ class Face
223
+ def self.define(name, **options)
224
+ # Mock Face.define
225
+ end
226
+ end
227
+
228
+ class Mode
229
+ attr_reader :buffer
230
+
231
+ def initialize(buffer)
232
+ @buffer = buffer
233
+ end
234
+
235
+ def self.define_syntax(face, pattern)
236
+ # Mock define_syntax
237
+ end
238
+
239
+ def self.file_name_pattern
240
+ @file_name_pattern
241
+ end
242
+
243
+ def self.file_name_pattern=(pattern)
244
+ @file_name_pattern = pattern
245
+ end
246
+ end
247
+ end
248
+
249
+ require "textbringer/#{name}"
250
+
251
+ require "test/unit"
252
+ RUBY
253
+ File.write("#{gem_name}/test/test_helper.rb", content)
254
+ end
255
+
256
+ def create_test_file
257
+ test_class = name.split(/[-_]/).map(&:capitalize).join
258
+ content = <<~RUBY
259
+ # frozen_string_literal: true
260
+
261
+ require "test_helper"
262
+
263
+ class Textbringer::#{test_class}Test < Test::Unit::TestCase
264
+ test "VERSION is defined" do
265
+ assert do
266
+ ::Textbringer::#{module_name}.const_defined?(:VERSION)
267
+ end
268
+ end
269
+
270
+ test "#{class_name} class exists" do
271
+ assert do
272
+ defined?(Textbringer::#{class_name})
273
+ end
274
+ end
275
+
276
+ test "#{class_name} file pattern matches .#{name} files" do
277
+ assert do
278
+ Textbringer::#{class_name}.file_name_pattern =~ "test.#{name}"
279
+ end
280
+ end
281
+ end
282
+ RUBY
283
+ File.write("#{gem_name}/test/textbringer_#{name.tr('-', '_')}_test.rb", content)
284
+ end
285
+
286
+ def create_readme
287
+ content = <<~MARKDOWN
288
+ # #{gem_name.split('-').map(&:capitalize).join(' ')}
289
+
290
+ A Textbringer plugin that provides #{name} mode support.
291
+
292
+ ## Installation
293
+
294
+ Install the gem by executing:
295
+
296
+ ```bash
297
+ gem install #{gem_name}
298
+ ```
299
+
300
+ Or add it to your Gemfile:
301
+
302
+ ```bash
303
+ bundle add #{gem_name}
304
+ ```
305
+
306
+ ## Usage
307
+
308
+ The plugin is automatically loaded when you start Textbringer. Simply open any `.#{name}` file and the mode will be applied automatically.
309
+
310
+ No additional configuration is required.
311
+
312
+ ## Development
313
+
314
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests.
315
+
316
+ To install this gem onto your local machine, run `bundle exec rake install`.
317
+
318
+ ## Contributing
319
+
320
+ Bug reports and pull requests are welcome on GitHub at https://github.com/#{github_user}/#{gem_name}.
321
+
322
+ ## License
323
+
324
+ The gem is available as open source under the terms of the [#{license_name}](#{license_url}).
325
+ MARKDOWN
326
+ File.write("#{gem_name}/README.md", content)
327
+ end
328
+
329
+ def create_license
330
+ if license_type == "wtfpl"
331
+ create_wtfpl_license
332
+ else
333
+ create_mit_license
334
+ end
335
+ end
336
+
337
+ def create_wtfpl_license
338
+ content = <<~LICENSE
339
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
340
+ Version 2, December 2004
341
+
342
+ Copyright (C) #{Time.now.year} #{author} <#{email}>
343
+
344
+ Everyone is permitted to copy and distribute verbatim or modified
345
+ copies of this license document, and changing it is allowed as long
346
+ as the name is changed.
347
+
348
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
349
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
350
+
351
+ 0. You just DO WHAT THE FUCK YOU WANT TO.
352
+ LICENSE
353
+ File.write("#{gem_name}/LICENSE.txt", content)
354
+ end
355
+
356
+ def create_mit_license
357
+ content = <<~LICENSE
358
+ The MIT License (MIT)
359
+
360
+ Copyright (c) #{Time.now.year} #{author}
361
+
362
+ Permission is hereby granted, free of charge, to any person obtaining a copy
363
+ of this software and associated documentation files (the "Software"), to deal
364
+ in the Software without restriction, including without limitation the rights
365
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
366
+ copies of the Software, and to permit persons to whom the Software is
367
+ furnished to do so, subject to the following conditions:
368
+
369
+ The above copyright notice and this permission notice shall be included in
370
+ all copies or substantial portions of the Software.
371
+
372
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
373
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
374
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
375
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
376
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
377
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
378
+ THE SOFTWARE.
379
+ LICENSE
380
+ File.write("#{gem_name}/LICENSE.txt", content)
381
+ end
382
+
383
+ def license_name
384
+ license_type == "wtfpl" ? "WTFPL" : "MIT License"
385
+ end
386
+
387
+ def license_url
388
+ license_type == "wtfpl" ? "http://www.wtfpl.net/" : "https://opensource.org/licenses/MIT"
389
+ end
390
+
391
+ def camelize(string)
392
+ string.split(/[-_]/).map(&:capitalize).join
393
+ end
394
+ end
395
+ end
396
+ end
397
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "textbringer/plugin/generator/version"
4
+ require_relative "textbringer/plugin/generator/cli"
5
+ require_relative "textbringer/plugin/generator"
6
+
7
+ module Textbringer
8
+ module Plugin
9
+ module Generator
10
+ class Error < StandardError; end
11
+ end
12
+ end
13
+ end
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: textbringer-plugin-generator
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - yancya
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2026-01-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ description: A command-line tool to generate Textbringer plugin scaffolding with proper
28
+ structure, tests, GitHub Actions, and documentation.
29
+ email:
30
+ - yancya@upec.jp
31
+ executables:
32
+ - textbringer-plugin
33
+ extensions: []
34
+ extra_rdoc_files: []
35
+ files:
36
+ - ".github/workflows/release.yml"
37
+ - LICENSE.txt
38
+ - README.md
39
+ - Rakefile
40
+ - exe/textbringer-plugin
41
+ - lib/textbringer/plugin/generator.rb
42
+ - lib/textbringer/plugin/generator/cli.rb
43
+ - lib/textbringer/plugin/generator/version.rb
44
+ - lib/textbringer_plugin_generator.rb
45
+ homepage: https://github.com/yancya/textbringer-plugin-generator
46
+ licenses:
47
+ - WTFPL
48
+ metadata:
49
+ allowed_push_host: https://rubygems.org
50
+ homepage_uri: https://github.com/yancya/textbringer-plugin-generator
51
+ source_code_uri: https://github.com/yancya/textbringer-plugin-generator
52
+ post_install_message:
53
+ rdoc_options: []
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: 3.2.0
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ requirements: []
67
+ rubygems_version: 3.4.19
68
+ signing_key:
69
+ specification_version: 4
70
+ summary: Generate Textbringer plugin boilerplate with best practices
71
+ test_files: []