scriptor 0.0.1

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: a3113e6f5f9a12c71ac148fa619294526176874ea8bd73ccefd6e32cee7b7ab5
4
+ data.tar.gz: 2997de1697ede585d1d536659438cb4a36932ef313e0c1b52c0cc720efb09be3
5
+ SHA512:
6
+ metadata.gz: 648e0d5a14e4843982955278b7f542c84284d96fed4b8194f34c374b80e077566998ba015448f15ad4648845103902ece266248d35b9973144f235015d7b6f56
7
+ data.tar.gz: b47e844e4c220aa288bd371ed030f304716ef6e8ce52bea2789c5836185ffbf59868191fa5b7cfc5a5109d66b8f389b077e56f65f2dea8a0e4c3692d34d03b8b
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright hatsu38
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # Scriptor
2
+ Short description and motivation.
3
+
4
+ ## Usage
5
+ How to use my plugin.
6
+
7
+ ## Installation
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem "scriptor"
12
+ ```
13
+
14
+ And then execute:
15
+ ```bash
16
+ $ bundle
17
+ ```
18
+
19
+ Or install it yourself as:
20
+ ```bash
21
+ $ gem install scriptor
22
+ ```
23
+
24
+ ## Contributing
25
+ Contribution directions go here.
26
+
27
+ ## License
28
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require "bundler/setup"
2
+
3
+ APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
4
+ load "rails/tasks/engine.rake"
5
+
6
+ load "rails/tasks/statistics.rake"
7
+
8
+ require "bundler/gem_tasks"
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
+ * files in this directory. Styles in this file should be added after the last require_* statement.
11
+ * It is generally better to create a new file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,4 @@
1
+ module Scriptor
2
+ class ApplicationController < ActionController::Base
3
+ end
4
+ end
@@ -0,0 +1,19 @@
1
+ module Scriptor
2
+ class ScriptsController < ApplicationController
3
+ def index
4
+ @scripts = Scriptor::Script.all
5
+ end
6
+
7
+ def show
8
+ @script = Scriptor::Script.find(params[:filename])
9
+ end
10
+
11
+ def run
12
+ script = Scriptor::Script.find(params[:filename])
13
+ args = params[:args].to_s.strip.split
14
+ script.run(*args)
15
+
16
+ redirect_to script_path(script.filename, notice: "Script executed successfully.")
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,4 @@
1
+ module Scriptor
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Scriptor
2
+ class ApplicationJob < ActiveJob::Base
3
+ end
4
+ end
@@ -0,0 +1,6 @@
1
+ module Scriptor
2
+ class ApplicationMailer < ActionMailer::Base
3
+ default from: "from@example.com"
4
+ layout "mailer"
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ module Scriptor
2
+ class ApplicationRecord < ActiveRecord::Base
3
+ self.abstract_class = true
4
+ end
5
+ end
@@ -0,0 +1,52 @@
1
+ module Scriptor
2
+ class Script
3
+ attr_reader :filename, :content
4
+
5
+ # コンストラクタでファイル名を受け取る
6
+ def initialize(filename)
7
+ @filename = filename
8
+ @content = load_content
9
+ end
10
+
11
+ # クラスメソッドで全スクリプトを取得
12
+ def self.all
13
+ scripts_path = Rails.root.join("script")
14
+ Dir.glob("#{scripts_path}/**/*.rb").map do |file|
15
+ new(file.sub("#{scripts_path}/", "")) # 各スクリプトをインスタンス化
16
+ end
17
+ end
18
+
19
+ # クラスメソッドで特定のスクリプトを検索してインスタンス化
20
+ def self.find(filename)
21
+ scripts_path = Rails.root.join("script", "#{filename}.rb")
22
+ return nil unless File.exist?(scripts_path)
23
+
24
+ new(filename)
25
+ end
26
+
27
+ # スクリプトの実行メソッド
28
+ def run(*args)
29
+ raise "Script content is empty" if content.blank?
30
+
31
+ script_path = Rails.root.join("script", "#{filename}.rb")
32
+ raise "Script file does not exist: #{script_path}" unless File.exist?(script_path)
33
+
34
+ # Rails 環境が正しくロードされるように Rails.root をカレントディレクトリに設定
35
+ Dir.chdir(Rails.root) do
36
+ escaped_args = args.map(&:shellescape).join(" ")
37
+ system("ruby #{script_path} #{escaped_args}")
38
+ end
39
+ rescue StandardError => e
40
+ Rails.logger.error "Error running script #{filename}: #{e.message}"
41
+ raise e
42
+ end
43
+
44
+ private
45
+
46
+ # ファイル内容をロード
47
+ def load_content
48
+ script_path = Rails.root.join("script", "#{filename}.rb")
49
+ File.exist?(script_path) ? File.read(script_path).strip : nil
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,18 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Scriptor</title>
5
+ <%= csrf_meta_tags %>
6
+ <%= csp_meta_tag %>
7
+
8
+ <%= yield :head %>
9
+
10
+ <%= stylesheet_link_tag "scriptor/application", media: "all" %>
11
+ <script src="https://cdn.tailwindcss.com"></script>
12
+ </head>
13
+ <body>
14
+
15
+ <%= yield %>
16
+
17
+ </body>
18
+ </html>
@@ -0,0 +1,20 @@
1
+ <div class="min-h-screen bg-gray-900 text-gray-200 py-8">
2
+ <div class="max-w-4xl mx-auto px-4">
3
+ <!-- Header -->
4
+ <h1 class="text-4xl font-bold text-blue-400 mb-8 border-b border-gray-700 pb-2">
5
+ 📜 Scripts Explorer
6
+ </h1>
7
+
8
+ <!-- Scripts List -->
9
+ <div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
10
+ <% @scripts.each_with_index do |script, index| %>
11
+ <div class="bg-gray-800 hover:bg-gray-700 p-4 rounded-lg shadow-lg transition duration-200 group">
12
+ <h2 class="text-xl font-semibold mb-2 text-gray-300 group-hover:text-blue-300">
13
+ <%= index + 1 %>. <%= link_to script.filename, script_path(script.filename), class: "hover:underline" %>
14
+ </h2>
15
+ </div>
16
+ <% end %>
17
+ </div>
18
+
19
+ </div>
20
+ </div>
@@ -0,0 +1,74 @@
1
+ <div class="min-h-screen bg-gray-900 text-gray-200 py-8">
2
+ <div class="max-w-4xl mx-auto px-4">
3
+ <!-- Header -->
4
+ <h1 class="text-4xl font-bold text-blue-400 mb-8 border-b border-gray-700 pb-2">
5
+ Script Details
6
+ </h1>
7
+
8
+ <!-- Script File Details -->
9
+ <div class="bg-gray-800 shadow-lg rounded-lg p-6 mb-6">
10
+ <h2 class="text-2xl font-semibold text-blue-300 mb-4">
11
+ <%= @script.filename %>
12
+ </h2>
13
+ <div class="bg-gray-900 text-white p-4 rounded-md overflow-auto">
14
+ <pre>
15
+ <code id="code-block" class="language-ruby">
16
+ <%= @script.content %>
17
+ </code>
18
+ </pre>
19
+ </div>
20
+ <div id="hidden-code" class="hidden"><%= @script.content %></div>
21
+ </div>
22
+
23
+ <!-- Run Script Form -->
24
+ <div class="bg-gray-800 shadow-lg rounded-lg p-6 mb-6">
25
+ <h3 class="text-xl font-semibold text-blue-300 mb-4">Run Script</h3>
26
+ <%= form_with url: run_script_path(@script.filename), method: :post, local: true, id: "script-form" do %>
27
+ <div class="mb-4">
28
+ <label for="args" class="block text-sm font-medium text-gray-300 mb-1">
29
+ Arguments (space-separated)
30
+ </label>
31
+ <%= text_field_tag "args", nil, id: "args-input", placeholder: "arg1 arg2 arg3", class: "w-full px-4 py-2 bg-gray-800 text-gray-300 rounded-md border border-gray-700 focus:ring focus:ring-blue-500" %>
32
+ </div>
33
+
34
+ <!-- Command Preview -->
35
+ <div class="mt-6">
36
+ <h4 class="text-lg font-semibold text-gray-300 mb-2">Command Preview:</h4>
37
+ <div class="bg-gray-900 text-green-400 p-4 rounded-md font-mono shadow-inner">
38
+ ruby <%= @script.filename %> <span id="command-preview-args"></span>
39
+ </div>
40
+ </div>
41
+
42
+ <%= submit_tag "🛠️ Run Script", class: "mt-6 px-4 py-2 bg-blue-500 hover:bg-blue-400 text-white rounded-md font-semibold shadow-md" %>
43
+ <% end %>
44
+ </div>
45
+
46
+ <!-- Back Link -->
47
+ <div class="flex justify-end">
48
+ <%= link_to '⬅️ Back to Index', scripts_path, class: "text-blue-500 hover:text-blue-400 font-medium hover:underline transition duration-200" %>
49
+ </div>
50
+ </div>
51
+ </div>
52
+
53
+ <script type="module">
54
+ // Highlight code using Shiki
55
+ import { codeToHtml } from 'https://esm.sh/shiki@1.0.0'
56
+
57
+ const codeBlock = document.getElementById('code-block')
58
+ const text = document.getElementById('hidden-code').textContent
59
+
60
+ codeBlock.innerHTML = await codeToHtml(text, {
61
+ lang: 'ruby',
62
+ theme: 'rose-pine'
63
+ })
64
+
65
+ // Update command preview dynamically
66
+ const argsInput = document.getElementById("args-input");
67
+ const commandPreviewArgs = document.getElementById("command-preview-args");
68
+ const baseCommand = "ruby <%= @filename %>";
69
+
70
+ argsInput.addEventListener("input", () => {
71
+ const args = argsInput.value.trim();
72
+ commandPreviewArgs.textContent = args;
73
+ });
74
+ </script>
data/config/routes.rb ADDED
@@ -0,0 +1,7 @@
1
+ Scriptor::Engine.routes.draw do
2
+ resources :scripts, only: %i[index show], param: :filename do
3
+ post :run, on: :member
4
+ end
5
+
6
+ root to: "scripts#index"
7
+ end
@@ -0,0 +1,5 @@
1
+ module Scriptor
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace Scriptor
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ module Scriptor
2
+ VERSION = "0.0.1".freeze
3
+ end
data/lib/scriptor.rb ADDED
@@ -0,0 +1,6 @@
1
+ require "scriptor/version"
2
+ require "scriptor/engine"
3
+
4
+ module Scriptor
5
+ # Your code goes here...
6
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :scriptor do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: scriptor
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - hatsu38
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2024-12-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: |
28
+ Scriptor is a Rails Engine that allows you to manage and execute Ruby scripts
29
+ located in the `script` folder directly from a web interface. This gem is
30
+ designed for developers who want an intuitive way to trigger and monitor
31
+ scripts without needing to access the command line.
32
+
33
+ Key Features:
34
+ - Run Ruby scripts with dynamic arguments via a browser-based UI.
35
+ - Preview script execution commands before running them.
36
+ - Capture and display script output in real-time.
37
+ - Simple integration into existing Rails applications.
38
+ email:
39
+ - hajiwata0308@gmail.com
40
+ executables: []
41
+ extensions: []
42
+ extra_rdoc_files: []
43
+ files:
44
+ - MIT-LICENSE
45
+ - README.md
46
+ - Rakefile
47
+ - app/assets/stylesheets/scriptor/application.css
48
+ - app/controllers/scriptor/application_controller.rb
49
+ - app/controllers/scriptor/scripts_controller.rb
50
+ - app/helpers/scriptor/application_helper.rb
51
+ - app/jobs/scriptor/application_job.rb
52
+ - app/mailers/scriptor/application_mailer.rb
53
+ - app/models/scriptor/application_record.rb
54
+ - app/models/scriptor/script.rb
55
+ - app/views/layouts/scriptor/application.html.erb
56
+ - app/views/scriptor/scripts/index.html.erb
57
+ - app/views/scriptor/scripts/show.html.erb
58
+ - config/routes.rb
59
+ - lib/scriptor.rb
60
+ - lib/scriptor/engine.rb
61
+ - lib/scriptor/version.rb
62
+ - lib/tasks/scriptor_tasks.rake
63
+ homepage: https://github.com/hatsu38/scriptor
64
+ licenses:
65
+ - MIT
66
+ metadata:
67
+ allowed_push_host: https://rubygems.org
68
+ homepage_uri: https://github.com/hatsu38/scriptor
69
+ source_code_uri: https://github.com/hatsu38/scriptor
70
+ changelog_uri: https://github.com/hatsu38/scriptor/CHANGELOG.md
71
+ rubygems_mfa_required: 'true'
72
+ post_install_message:
73
+ rdoc_options: []
74
+ require_paths:
75
+ - lib
76
+ required_ruby_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: 3.3.0
81
+ required_rubygems_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ requirements: []
87
+ rubygems_version: 3.5.23
88
+ signing_key:
89
+ specification_version: 4
90
+ summary: A Rails Engine to execute and manage scripts directly from your browser.
91
+ test_files: []