rails-design-profiles 0.1.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 +7 -0
- data/CHANGELOG.md +9 -0
- data/CODE_OF_CONDUCT.md +4 -0
- data/CONTRIBUTING.md +23 -0
- data/LICENSE.txt +22 -0
- data/README.md +136 -0
- data/lib/generators/rails_design_profiles/install/install_generator.rb +29 -0
- data/lib/generators/rails_design_profiles/install/templates/design_profiles.yml +12 -0
- data/lib/rails_design_profiles/catalog_client.rb +50 -0
- data/lib/rails_design_profiles/helper.rb +13 -0
- data/lib/rails_design_profiles/profile_store.rb +110 -0
- data/lib/rails_design_profiles/railtie.rb +14 -0
- data/lib/rails_design_profiles/version.rb +5 -0
- data/lib/rails_design_profiles.rb +31 -0
- data/lib/tasks/rails_design_profiles_tasks.rake +28 -0
- metadata +86 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: f94b1e0af567ce077819a716dc34eb34462542a7bf251cdbb287376fcc7ee3e6
|
|
4
|
+
data.tar.gz: 9c96463447b584330e2e09d95da375b5c96ddc3fad795536a936feb2d584c5c0
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 14674431eac89956035122bc7a4a1941258ca2248b76d2d9bc173df3592defd327c722f7ae517c101cbf5a6f954f9072f2601f9a4fffcc3c9ae97c69741a06d6
|
|
7
|
+
data.tar.gz: ca65b17b242bc0805a8dda7f69716ecbb85d30b17e2515ade2ea9223ccc753d844552e0c64103569ee32d8b50c5ec594f83cd4429ae721cd9c729d24bc497a2c
|
data/CHANGELOG.md
ADDED
data/CODE_OF_CONDUCT.md
ADDED
data/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Thank you for helping make Rails interfaces more intentional and more maintainable.
|
|
4
|
+
|
|
5
|
+
## Before you start
|
|
6
|
+
|
|
7
|
+
- Use [Discussions](https://github.com/paladini/rails-design-profiles/discussions) for questions and proposals; open an issue when you have a reproducible bug or a focused feature.
|
|
8
|
+
- Keep pull requests narrow. Discuss changes that alter public configuration, task names, or output first.
|
|
9
|
+
- Never submit copied third-party CSS, assets, logos, or proprietary `DESIGN.md` content. References are context; executable tokens are authored and reviewed by the application team.
|
|
10
|
+
|
|
11
|
+
## Local workflow
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
bundle install
|
|
15
|
+
bundle exec rake test
|
|
16
|
+
gem build rails-design-profiles.gemspec
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
The CI suite verifies Ruby 3.1 with Rails 7.1 and current supported Ruby versions. Add a regression test for each behavior change and update the README when a public command, configuration key, or output changes.
|
|
20
|
+
|
|
21
|
+
## Pull requests
|
|
22
|
+
|
|
23
|
+
Explain the user problem, the chosen behavior, and how you verified it. Maintainers prioritize correctness, small APIs, accessible output, and changes that preserve the distinction between a design reference and a production theme.
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Fernando Paladini
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
data/README.md
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# rails-design-profiles
|
|
2
|
+
|
|
3
|
+
[](https://github.com/paladini/rails-design-profiles/actions/workflows/ci.yml)
|
|
4
|
+
[](https://rubygems.org/gems/rails-design-profiles)
|
|
5
|
+
[](LICENSE.txt)
|
|
6
|
+
|
|
7
|
+
**A design reference should influence your Rails UI without becoming an unreviewable theme generator.**
|
|
8
|
+
|
|
9
|
+
`rails-design-profiles` keeps the two jobs separate:
|
|
10
|
+
|
|
11
|
+
1. `DESIGN.md` gives your AI agent a clear visual reference.
|
|
12
|
+
2. A small YAML profile exposes the tokens your Rails application actually uses.
|
|
13
|
+
|
|
14
|
+
The result is a deliberate CSS-variable contract you can review, version, switch, and evolve with your team.
|
|
15
|
+
|
|
16
|
+
## Why this exists
|
|
17
|
+
|
|
18
|
+
AI can read a `DESIGN.md`, but Markdown alone does not change an application. Conversely, replacing an entire stylesheet to try a visual direction is risky and hard to review.
|
|
19
|
+
|
|
20
|
+
This gem gives Rails applications a narrow bridge between the two: references stay local and explicit; CSS variables are emitted from an active profile; your components decide which tokens to consume.
|
|
21
|
+
|
|
22
|
+
## Install
|
|
23
|
+
|
|
24
|
+
```ruby
|
|
25
|
+
# Gemfile
|
|
26
|
+
gem "rails-design-profiles"
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
```sh
|
|
30
|
+
bundle install
|
|
31
|
+
bin/rails generate rails_design_profiles:install
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The generator adds a profile file and inserts the helper into `app/views/layouts/application.html.erb`:
|
|
35
|
+
|
|
36
|
+
```erb
|
|
37
|
+
<%= rails_design_profiles_tags %>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Use the resulting variables in your own CSS:
|
|
41
|
+
|
|
42
|
+
```css
|
|
43
|
+
body {
|
|
44
|
+
color: var(--rdp-color-text);
|
|
45
|
+
background: var(--rdp-color-surface);
|
|
46
|
+
font-family: var(--rdp-font-body);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.button {
|
|
50
|
+
background: var(--rdp-color-primary);
|
|
51
|
+
padding: var(--rdp-space-page);
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## The profile contract
|
|
56
|
+
|
|
57
|
+
`config/design_profiles.yml` is the source of truth for production tokens. Token names become `--rdp-*` CSS variables.
|
|
58
|
+
|
|
59
|
+
```yaml
|
|
60
|
+
active: editorial
|
|
61
|
+
profiles:
|
|
62
|
+
editorial:
|
|
63
|
+
reference: config/design_profiles/references/claude.md
|
|
64
|
+
tokens:
|
|
65
|
+
color-primary: "#c15f3c"
|
|
66
|
+
color-surface: "#f8f6f2"
|
|
67
|
+
color-text: "#24211e"
|
|
68
|
+
font-body: "Newsreader, Georgia, serif"
|
|
69
|
+
space-page: "1.5rem"
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
The active profile is global to the app and is resolved for every response. Version 0.1 does not include per-session or query-string overrides.
|
|
73
|
+
|
|
74
|
+
## Bring a public reference into your project
|
|
75
|
+
|
|
76
|
+
The v0.1 catalog uses only the MIT-licensed [VoltAgent/awesome-design-md](https://github.com/VoltAgent/awesome-design-md) collection.
|
|
77
|
+
|
|
78
|
+
```sh
|
|
79
|
+
bin/rails design:list
|
|
80
|
+
bin/rails design:install[claude]
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Installation stores the reference in `config/design_profiles/references/claude.md` and creates an empty `claude` profile. Read that reference with your agent, choose the tokens that fit your product, and add them deliberately to YAML.
|
|
84
|
+
|
|
85
|
+
Switch profiles with:
|
|
86
|
+
|
|
87
|
+
```sh
|
|
88
|
+
bin/rails design:activate[claude]
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
The gem never copies third-party CSS, assets, or branding. It is not affiliated with getdesign.md, VoltAgent, or any referenced brand.
|
|
92
|
+
|
|
93
|
+
## How it works
|
|
94
|
+
|
|
95
|
+
```text
|
|
96
|
+
DESIGN.md reference ──> team / AI design decisions ──> design_profiles.yml
|
|
97
|
+
│
|
|
98
|
+
▼
|
|
99
|
+
<style> --rdp-* variables
|
|
100
|
+
│
|
|
101
|
+
▼
|
|
102
|
+
your Rails components
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
This is intentionally not a Markdown-to-CSS compiler. It preserves human judgment at the point where visual decisions become production code.
|
|
106
|
+
|
|
107
|
+
## Compatibility
|
|
108
|
+
|
|
109
|
+
- Ruby 3.1+
|
|
110
|
+
- Rails 7.1+
|
|
111
|
+
- Asset pipeline, Propshaft, Importmap, Tailwind, and custom CSS all work because the output is standard CSS variables.
|
|
112
|
+
|
|
113
|
+
## Community
|
|
114
|
+
|
|
115
|
+
- Ask questions and share workflows in [Discussions](https://github.com/paladini/rails-design-profiles/discussions).
|
|
116
|
+
- Report reproducible defects or focused feature requests through the issue templates.
|
|
117
|
+
- Read [CONTRIBUTING.md](CONTRIBUTING.md), [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md), [SUPPORT.md](SUPPORT.md), and [SECURITY.md](SECURITY.md) before participating.
|
|
118
|
+
|
|
119
|
+
### Roadmap
|
|
120
|
+
|
|
121
|
+
- [ ] Profile validation and diagnostics
|
|
122
|
+
- [ ] A profile preview surface for development
|
|
123
|
+
- [ ] More import adapters for openly licensed design references
|
|
124
|
+
- [ ] Community-maintained example Rails applications
|
|
125
|
+
|
|
126
|
+
## Development
|
|
127
|
+
|
|
128
|
+
```sh
|
|
129
|
+
bundle install
|
|
130
|
+
bundle exec rake test
|
|
131
|
+
gem build rails-design-profiles.gemspec
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## License
|
|
135
|
+
|
|
136
|
+
MIT. See [LICENSE.txt](LICENSE.txt).
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rails/generators"
|
|
4
|
+
|
|
5
|
+
module RailsDesignProfiles
|
|
6
|
+
module Generators
|
|
7
|
+
class InstallGenerator < Rails::Generators::Base
|
|
8
|
+
source_root File.expand_path("templates", __dir__)
|
|
9
|
+
|
|
10
|
+
def create_configuration
|
|
11
|
+
template "design_profiles.yml", "config/design_profiles.yml" unless File.exist?(path("config/design_profiles.yml"))
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def add_style_helper_to_layout
|
|
15
|
+
layout = "app/views/layouts/application.html.erb"
|
|
16
|
+
return unless File.exist?(path(layout))
|
|
17
|
+
return if File.read(path(layout)).include?("rails_design_profiles_tags")
|
|
18
|
+
|
|
19
|
+
inject_into_file layout, " <%= rails_design_profiles_tags %>\n", before: " </head>\n"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def path(relative_path)
|
|
25
|
+
File.join(destination_root, relative_path)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# CSS values are intentionally explicit and reviewable. Reference files are context for AI agents.
|
|
2
|
+
active: default
|
|
3
|
+
profiles:
|
|
4
|
+
default:
|
|
5
|
+
reference: null
|
|
6
|
+
tokens:
|
|
7
|
+
color-primary: "#2563eb"
|
|
8
|
+
color-surface: "#ffffff"
|
|
9
|
+
color-text: "#111827"
|
|
10
|
+
font-body: "system-ui, sans-serif"
|
|
11
|
+
space-page: "1.5rem"
|
|
12
|
+
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
require "net/http"
|
|
5
|
+
require "uri"
|
|
6
|
+
|
|
7
|
+
module RailsDesignProfiles
|
|
8
|
+
class CatalogClient
|
|
9
|
+
REPOSITORY = "VoltAgent/awesome-design-md"
|
|
10
|
+
TREE_URL = "https://api.github.com/repos/#{REPOSITORY}/git/trees/main?recursive=1"
|
|
11
|
+
RAW_URL = "https://raw.githubusercontent.com/#{REPOSITORY}/main/design-md/%<slug>s/DESIGN.md"
|
|
12
|
+
|
|
13
|
+
def initialize(http_get: nil)
|
|
14
|
+
@http_get = http_get || method(:get)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def slugs
|
|
18
|
+
tree = JSON.parse(@http_get.call(TREE_URL)).fetch("tree")
|
|
19
|
+
tree.filter_map { |entry| entry.fetch("path")[%r{\Adesign-md/([^/]+)/DESIGN\.md\z}, 1] }.sort
|
|
20
|
+
rescue JSON::ParserError, KeyError => error
|
|
21
|
+
raise CatalogError, "Unexpected catalog response: #{error.message}"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def download(slug)
|
|
25
|
+
validate_slug!(slug)
|
|
26
|
+
@http_get.call(format(RAW_URL, slug: slug))
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def get(url)
|
|
32
|
+
uri = URI(url)
|
|
33
|
+
response = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https", open_timeout: 5, read_timeout: 10) do |http|
|
|
34
|
+
http.get(uri.request_uri, "User-Agent" => "rails-design-profiles/#{VERSION}")
|
|
35
|
+
end
|
|
36
|
+
return response.body if response.is_a?(Net::HTTPSuccess)
|
|
37
|
+
|
|
38
|
+
raise CatalogError, "Catalog request failed (HTTP #{response.code})"
|
|
39
|
+
rescue SocketError, Timeout::Error, Errno::ECONNREFUSED => error
|
|
40
|
+
raise CatalogError, "Catalog request failed: #{error.message}"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def validate_slug!(slug)
|
|
44
|
+
return if slug.is_a?(String) && slug.match?(/\A[a-z0-9]+(?:-[a-z0-9]+)*\z/)
|
|
45
|
+
|
|
46
|
+
raise CatalogError, "Invalid catalog slug: #{slug.inspect}"
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RailsDesignProfiles
|
|
4
|
+
module Helper
|
|
5
|
+
def rails_design_profiles_tags
|
|
6
|
+
css = RailsDesignProfiles.store.css_variables
|
|
7
|
+
return "".html_safe if css.empty?
|
|
8
|
+
|
|
9
|
+
content_tag(:style, ":root {#{css}}".html_safe, id: "rails-design-profiles")
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "fileutils"
|
|
4
|
+
require "yaml"
|
|
5
|
+
|
|
6
|
+
module RailsDesignProfiles
|
|
7
|
+
class ProfileStore
|
|
8
|
+
CONFIG_PATH = "config/design_profiles.yml"
|
|
9
|
+
|
|
10
|
+
def initialize(root)
|
|
11
|
+
@root = Pathname(root)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def active_profile
|
|
15
|
+
profile_named(data.fetch("active"))
|
|
16
|
+
rescue KeyError
|
|
17
|
+
raise ConfigurationError, "Missing active profile in #{config_path}"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def css_variables
|
|
21
|
+
tokens = active_profile.fetch("tokens", {})
|
|
22
|
+
unless tokens.is_a?(Hash)
|
|
23
|
+
raise ConfigurationError, "Profile tokens must be a mapping in #{config_path}"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
tokens.filter_map do |name, value|
|
|
27
|
+
next unless valid_token?(name, value)
|
|
28
|
+
|
|
29
|
+
"--rdp-#{name}: #{value};"
|
|
30
|
+
end.join
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def install_reference!(slug, contents)
|
|
34
|
+
validate_slug!(slug)
|
|
35
|
+
reference_path = references_path.join("#{slug}.md")
|
|
36
|
+
raise ConfigurationError, "Reference already exists: #{reference_path}" if reference_path.exist?
|
|
37
|
+
|
|
38
|
+
config = data
|
|
39
|
+
profiles = config.fetch("profiles")
|
|
40
|
+
if profiles.key?(slug)
|
|
41
|
+
raise ConfigurationError, "Profile already exists: #{slug}"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
FileUtils.mkdir_p(reference_path.dirname)
|
|
45
|
+
reference_path.write(contents)
|
|
46
|
+
profiles[slug] = {
|
|
47
|
+
"reference" => reference_path.relative_path_from(@root).to_s,
|
|
48
|
+
"tokens" => {}
|
|
49
|
+
}
|
|
50
|
+
write(config)
|
|
51
|
+
rescue StandardError
|
|
52
|
+
FileUtils.rm_f(reference_path) if defined?(reference_path) && reference_path&.exist?
|
|
53
|
+
raise
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def activate!(name)
|
|
57
|
+
config = data
|
|
58
|
+
profile_named(name, config)
|
|
59
|
+
config["active"] = name
|
|
60
|
+
write(config)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
private
|
|
64
|
+
|
|
65
|
+
def data
|
|
66
|
+
raise ConfigurationError, "Missing configuration: #{config_path}" unless config_path.exist?
|
|
67
|
+
|
|
68
|
+
parsed = YAML.safe_load(config_path.read, permitted_classes: [], aliases: false)
|
|
69
|
+
unless parsed.is_a?(Hash) && parsed["profiles"].is_a?(Hash)
|
|
70
|
+
raise ConfigurationError, "Expected active and profiles mappings in #{config_path}"
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
parsed
|
|
74
|
+
rescue Psych::Exception => error
|
|
75
|
+
raise ConfigurationError, "Invalid YAML in #{config_path}: #{error.message}"
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def write(config)
|
|
79
|
+
config_path.write(YAML.dump(config))
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def profile_named(name, config = data)
|
|
83
|
+
profile = config.fetch("profiles")[name]
|
|
84
|
+
raise ProfileNotFound, "Unknown design profile: #{name}" unless profile.is_a?(Hash)
|
|
85
|
+
|
|
86
|
+
profile
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def config_path
|
|
90
|
+
@root.join(CONFIG_PATH)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def references_path
|
|
94
|
+
@root.join("config/design_profiles/references")
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def validate_slug!(slug)
|
|
98
|
+
return if slug.match?(/\A[a-z0-9]+(?:-[a-z0-9]+)*\z/)
|
|
99
|
+
|
|
100
|
+
raise ConfigurationError, "Invalid catalog slug: #{slug.inspect}"
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def valid_token?(name, value)
|
|
104
|
+
name.is_a?(String) && value.is_a?(String) &&
|
|
105
|
+
name.match?(/\A[a-z0-9]+(?:-[a-z0-9]+)*\z/) &&
|
|
106
|
+
value.match?(/\A[a-zA-Z0-9#%.,()\s\/'\"+*_\-]+\z/)
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RailsDesignProfiles
|
|
4
|
+
class Railtie < Rails::Railtie
|
|
5
|
+
initializer "rails_design_profiles.helper" do
|
|
6
|
+
ActiveSupport.on_load(:action_view) { include RailsDesignProfiles::Helper }
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
rake_tasks do
|
|
10
|
+
load File.expand_path("../tasks/rails_design_profiles_tasks.rake", __dir__)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "pathname"
|
|
4
|
+
require "rails_design_profiles/version"
|
|
5
|
+
require "rails_design_profiles/profile_store"
|
|
6
|
+
require "rails_design_profiles/catalog_client"
|
|
7
|
+
require "rails_design_profiles/helper"
|
|
8
|
+
require "rails_design_profiles/railtie" if defined?(Rails::Railtie)
|
|
9
|
+
|
|
10
|
+
module RailsDesignProfiles
|
|
11
|
+
class Error < StandardError; end
|
|
12
|
+
class ConfigurationError < Error; end
|
|
13
|
+
class ProfileNotFound < Error; end
|
|
14
|
+
class CatalogError < Error; end
|
|
15
|
+
|
|
16
|
+
class << self
|
|
17
|
+
attr_writer :root
|
|
18
|
+
|
|
19
|
+
def root
|
|
20
|
+
return @root if @root
|
|
21
|
+
return Rails.root if defined?(Rails) && Rails.respond_to?(:root)
|
|
22
|
+
|
|
23
|
+
Pathname.pwd
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def store
|
|
27
|
+
ProfileStore.new(root)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
namespace :design do
|
|
4
|
+
desc "List public DESIGN.md references from VoltAgent/awesome-design-md"
|
|
5
|
+
task :list do
|
|
6
|
+
RailsDesignProfiles::CatalogClient.new.slugs.each { |slug| puts slug }
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
desc "Download a public DESIGN.md reference and create a blank token profile"
|
|
10
|
+
task :install, [:slug] => :environment do |_task, arguments|
|
|
11
|
+
slug = arguments.fetch(:slug) { abort "Usage: rails design:install[slug]" }
|
|
12
|
+
contents = RailsDesignProfiles::CatalogClient.new.download(slug)
|
|
13
|
+
RailsDesignProfiles.store.install_reference!(slug, contents)
|
|
14
|
+
puts "Installed #{slug}. Add tokens to config/design_profiles.yml before activating it."
|
|
15
|
+
rescue RailsDesignProfiles::Error => error
|
|
16
|
+
abort error.message
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
desc "Set the active design profile"
|
|
20
|
+
task :activate, [:profile] => :environment do |_task, arguments|
|
|
21
|
+
profile = arguments.fetch(:profile) { abort "Usage: rails design:activate[profile]" }
|
|
22
|
+
RailsDesignProfiles.store.activate!(profile)
|
|
23
|
+
puts "Active design profile: #{profile}"
|
|
24
|
+
rescue RailsDesignProfiles::Error => error
|
|
25
|
+
abort error.message
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
metadata
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: rails-design-profiles
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Fernando Paladini
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: actionview
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '7.1'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '7.1'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: railties
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '7.1'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - ">="
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '7.1'
|
|
40
|
+
description: Keep DESIGN.md references alongside executable, reviewable CSS token
|
|
41
|
+
profiles in Rails.
|
|
42
|
+
email:
|
|
43
|
+
- fnpaladini@gmail.com
|
|
44
|
+
executables: []
|
|
45
|
+
extensions: []
|
|
46
|
+
extra_rdoc_files: []
|
|
47
|
+
files:
|
|
48
|
+
- CHANGELOG.md
|
|
49
|
+
- CODE_OF_CONDUCT.md
|
|
50
|
+
- CONTRIBUTING.md
|
|
51
|
+
- LICENSE.txt
|
|
52
|
+
- README.md
|
|
53
|
+
- lib/generators/rails_design_profiles/install/install_generator.rb
|
|
54
|
+
- lib/generators/rails_design_profiles/install/templates/design_profiles.yml
|
|
55
|
+
- lib/rails_design_profiles.rb
|
|
56
|
+
- lib/rails_design_profiles/catalog_client.rb
|
|
57
|
+
- lib/rails_design_profiles/helper.rb
|
|
58
|
+
- lib/rails_design_profiles/profile_store.rb
|
|
59
|
+
- lib/rails_design_profiles/railtie.rb
|
|
60
|
+
- lib/rails_design_profiles/version.rb
|
|
61
|
+
- lib/tasks/rails_design_profiles_tasks.rake
|
|
62
|
+
homepage: https://github.com/paladini/rails-design-profiles
|
|
63
|
+
licenses:
|
|
64
|
+
- MIT
|
|
65
|
+
metadata:
|
|
66
|
+
source_code_uri: https://github.com/paladini/rails-design-profiles
|
|
67
|
+
changelog_uri: https://github.com/paladini/rails-design-profiles/blob/main/CHANGELOG.md
|
|
68
|
+
rubygems_mfa_required: 'true'
|
|
69
|
+
rdoc_options: []
|
|
70
|
+
require_paths:
|
|
71
|
+
- lib
|
|
72
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
73
|
+
requirements:
|
|
74
|
+
- - ">="
|
|
75
|
+
- !ruby/object:Gem::Version
|
|
76
|
+
version: '3.1'
|
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - ">="
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: '0'
|
|
82
|
+
requirements: []
|
|
83
|
+
rubygems_version: 4.0.16
|
|
84
|
+
specification_version: 4
|
|
85
|
+
summary: Versioned, CSS-variable design profiles for Rails applications.
|
|
86
|
+
test_files: []
|