bullet_train 1.0.27 ā 1.0.30
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 +4 -4
- data/app/models/concerns/current_attributes/base.rb +36 -0
- data/app/views/bullet_train/partial_resolver.html.erb +2 -0
- data/app/views/devise/sessions/new.html.erb +0 -2
- data/config/locales/en/base.yml +132 -0
- data/config/locales/en/doorkeeper.en.yml +152 -0
- data/config/locales/en/oauth.en.yml +15 -0
- data/config/locales/en/roles.en.yml +6 -0
- data/config/locales/en/user_mailer.en.yml +36 -0
- data/lib/bullet_train/resolver.rb +148 -0
- data/lib/bullet_train/version.rb +1 -1
- data/lib/bullet_train.rb +1 -0
- data/lib/tasks/bullet_train_tasks.rake +31 -0
- metadata +10 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4daae6a44c0ee84d06666767d1ca5b73655b3ed98aa0b9efcffb019c5691edf7
|
4
|
+
data.tar.gz: 0ca25849d1a29c888d6687ca4fbcb11a31db8ba8cc23ed96a6aaf61e484fe4b1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9cc32562c77ed0a146aab0a8fdc3b1e2e3e45911d94c5bfc31cd0a259f17ca9de44481e025b0f7de6fceb2a5286db47e86179d17e859d1bedd06b9104955d538
|
7
|
+
data.tar.gz: f155cfc57b9f831c68c1e984272fe815784ab2ae1bee3713bb0ff68ab3e480c235adb30d603c2056b097c24789567c9e250c7aaab8eebd18da01a90006eaac95
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module CurrentAttributes::Base
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
included do
|
5
|
+
attribute :user, :team, :membership, :ability
|
6
|
+
|
7
|
+
resets do
|
8
|
+
Time.zone = nil
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def user=(user)
|
13
|
+
super
|
14
|
+
|
15
|
+
if user
|
16
|
+
Time.zone = user.time_zone
|
17
|
+
self.ability = Ability.new(user)
|
18
|
+
else
|
19
|
+
Time.zone = nil
|
20
|
+
self.ability = nil
|
21
|
+
end
|
22
|
+
|
23
|
+
update_membership
|
24
|
+
end
|
25
|
+
|
26
|
+
def team=(team)
|
27
|
+
super
|
28
|
+
update_membership
|
29
|
+
end
|
30
|
+
|
31
|
+
def update_membership
|
32
|
+
self.membership = if user && team
|
33
|
+
user.memberships.where(team: team)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
# Files in the config/locales directory are used for internationalization
|
2
|
+
# and are automatically loaded by Rails. If you want to use locales other
|
3
|
+
# than English, add the necessary files in this directory.
|
4
|
+
#
|
5
|
+
# To use the locales, use `I18n.t`:
|
6
|
+
#
|
7
|
+
# I18n.t "hello"
|
8
|
+
#
|
9
|
+
# In views, this is aliased to just `t`:
|
10
|
+
#
|
11
|
+
# <%= t("hello") %>
|
12
|
+
#
|
13
|
+
# To use a different locale, set it with `I18n.locale`:
|
14
|
+
#
|
15
|
+
# I18n.locale = :es
|
16
|
+
#
|
17
|
+
# This would use the information in config/locales/es.yml.
|
18
|
+
#
|
19
|
+
# The following keys must be escaped otherwise they will not be retrieved by
|
20
|
+
# the default I18n backend:
|
21
|
+
#
|
22
|
+
# true, false, on, off, yes, no
|
23
|
+
#
|
24
|
+
# Instead, surround them with single quotes.
|
25
|
+
#
|
26
|
+
# en:
|
27
|
+
# "true": "foo"
|
28
|
+
#
|
29
|
+
# To learn more, please read the Rails Internationalization guide
|
30
|
+
# available at https://guides.rubyonrails.org/i18n.html.
|
31
|
+
|
32
|
+
en:
|
33
|
+
bullet_train:
|
34
|
+
name: Bullet Train
|
35
|
+
tagline: The Ruby on Rails SaaS Template
|
36
|
+
description: Bullet Train is a Ruby on Rails SaaS-in-a-Box that saves developers weeks of effort.
|
37
|
+
keywords: bullet train ruby on rails saas template starter kit
|
38
|
+
support_email: ask@bullettrain.co
|
39
|
+
global:
|
40
|
+
or: Or
|
41
|
+
more: More
|
42
|
+
is_admin: Admin?
|
43
|
+
person: Person
|
44
|
+
admin: Admin
|
45
|
+
confirm_message: Are you sure?
|
46
|
+
typing_search: Start typing search...
|
47
|
+
sidebar: Sidebar
|
48
|
+
creator: Bullet Train, Inc.
|
49
|
+
buttons:
|
50
|
+
other: Other
|
51
|
+
debug: Debug
|
52
|
+
details: Details
|
53
|
+
revoke: Revoke
|
54
|
+
cancel: Cancel
|
55
|
+
next: Next
|
56
|
+
back: Back
|
57
|
+
new: New
|
58
|
+
edit: Edit
|
59
|
+
settings: Settings
|
60
|
+
configure: Configure
|
61
|
+
remove: Remove
|
62
|
+
delete: Delete
|
63
|
+
update: Update
|
64
|
+
sign_up: Sign Up
|
65
|
+
sign_in: Sign In
|
66
|
+
notifications:
|
67
|
+
not_found: not found
|
68
|
+
all_fields_required: All of these fields are required.
|
69
|
+
dates:
|
70
|
+
today: Today
|
71
|
+
day:
|
72
|
+
one: 1 Day
|
73
|
+
other: '%{count} Days'
|
74
|
+
last_month: Last Month
|
75
|
+
last_week: Last Week
|
76
|
+
last_day:
|
77
|
+
one: Last Day
|
78
|
+
other: Last %{count} Days
|
79
|
+
formats:
|
80
|
+
date: '%m/%d/%Y'
|
81
|
+
date_and_time: '%m/%d/%Y %l:%M %p'
|
82
|
+
|
83
|
+
menus:
|
84
|
+
main:
|
85
|
+
labels:
|
86
|
+
account: Account
|
87
|
+
new: New
|
88
|
+
profile_details: Profile Details
|
89
|
+
logout: Logout
|
90
|
+
skip: Skip For Now
|
91
|
+
dashboard: Dashboard
|
92
|
+
team_members: Team Members
|
93
|
+
webhooks: Webhooks
|
94
|
+
invitations: Invitations
|
95
|
+
billing: Billing
|
96
|
+
upgrade: Upgrade
|
97
|
+
switch_teams: Switch Teams
|
98
|
+
add_new_team: Add New Team
|
99
|
+
edit_account_details: Account Details
|
100
|
+
resources: Resources
|
101
|
+
collaborate: Collaborate
|
102
|
+
integrations: Integrations
|
103
|
+
developers: Developers
|
104
|
+
your_account: Your Account
|
105
|
+
|
106
|
+
breadcrumbs:
|
107
|
+
your_dashboard: Your Dashboard
|
108
|
+
actions:
|
109
|
+
edit: 'Edit'
|
110
|
+
new: 'New'
|
111
|
+
|
112
|
+
fields:
|
113
|
+
date_field:
|
114
|
+
apply: Apply
|
115
|
+
cancel: Clear
|
116
|
+
|
117
|
+
layouts:
|
118
|
+
|
119
|
+
application:
|
120
|
+
raise: we should never be using the application layout.
|
121
|
+
|
122
|
+
mailer:
|
123
|
+
trouble: If youāre having trouble with the button above, copy and paste the URL below into your web browser.
|
124
|
+
all_rights_reserved: "%{year} %{product_name}. All rights reserved."
|
125
|
+
|
126
|
+
public:
|
127
|
+
launch_help: We're helping people launch high quality SaaS products!
|
128
|
+
developed_by: Developed By
|
129
|
+
made_with_love: Made With Love In
|
130
|
+
location: Los Angeles, California
|
131
|
+
follow_us: Follow Us
|
132
|
+
all_rights_reserved: "%{year} Bullet Train, Inc., All Rights Reserved"
|
@@ -0,0 +1,152 @@
|
|
1
|
+
en:
|
2
|
+
activerecord:
|
3
|
+
attributes:
|
4
|
+
platform/application:
|
5
|
+
name: 'Name'
|
6
|
+
redirect_uri: 'Redirect URI'
|
7
|
+
errors:
|
8
|
+
models:
|
9
|
+
platform/application:
|
10
|
+
attributes:
|
11
|
+
redirect_uri:
|
12
|
+
fragment_present: 'cannot contain a fragment.'
|
13
|
+
invalid_uri: 'must be a valid URI.'
|
14
|
+
unspecified_scheme: 'must specify a scheme.'
|
15
|
+
relative_uri: 'must be an absolute URI.'
|
16
|
+
secured_uri: 'must be an HTTPS/SSL URI.'
|
17
|
+
forbidden_uri: 'is forbidden by the server.'
|
18
|
+
scopes:
|
19
|
+
not_match_configured: "can only contain the strings \"read\", \"write\", or \"delete\". You can also leave this field blank"
|
20
|
+
|
21
|
+
platform:
|
22
|
+
applications:
|
23
|
+
confirmations:
|
24
|
+
destroy: 'Are you sure?'
|
25
|
+
buttons:
|
26
|
+
edit: 'Edit'
|
27
|
+
destroy: 'Destroy'
|
28
|
+
submit: 'Submit'
|
29
|
+
cancel: 'Cancel'
|
30
|
+
authorize: 'Authorize'
|
31
|
+
form:
|
32
|
+
error: 'Whoops! Check your form for possible errors'
|
33
|
+
help:
|
34
|
+
confidential: 'Application will be used where the client secret can be kept confidential. Native mobile apps and Single Page Apps are considered non-confidential.'
|
35
|
+
redirect_uri: 'Use one line per URI'
|
36
|
+
blank_redirect_uri: "Leave it blank if you configured your provider to use Client Credentials, Resource Owner Password Credentials or any other grant type that doesn't require redirect URI."
|
37
|
+
scopes: 'Separate scopes with spaces. Leave blank to use the default scope.'
|
38
|
+
edit:
|
39
|
+
title: 'Edit application'
|
40
|
+
index:
|
41
|
+
title: 'Your applications'
|
42
|
+
new: 'New Application'
|
43
|
+
name: 'Name'
|
44
|
+
callback_url: 'Callback URL'
|
45
|
+
confidential: 'Confidential?'
|
46
|
+
actions: 'Actions'
|
47
|
+
confidentiality:
|
48
|
+
'yes': 'Yes'
|
49
|
+
'no': 'No'
|
50
|
+
new:
|
51
|
+
title: 'New Application'
|
52
|
+
show:
|
53
|
+
title: 'Application: %{name}'
|
54
|
+
application_id: 'UID'
|
55
|
+
secret: 'Secret'
|
56
|
+
secret_hashed: 'Secret hashed'
|
57
|
+
scopes: 'Scopes'
|
58
|
+
confidential: 'Confidential'
|
59
|
+
callback_urls: 'Callback urls'
|
60
|
+
actions: 'Actions'
|
61
|
+
not_defined: 'Not defined'
|
62
|
+
|
63
|
+
doorkeeper:
|
64
|
+
authorizations:
|
65
|
+
buttons:
|
66
|
+
authorize: 'Authorize'
|
67
|
+
deny: 'Deny'
|
68
|
+
error:
|
69
|
+
title: 'An error has occurred'
|
70
|
+
new:
|
71
|
+
title: 'Authorization required'
|
72
|
+
prompt: 'Authorize %{client_name} to use your account?'
|
73
|
+
able_to: 'This application will be able to'
|
74
|
+
show:
|
75
|
+
title: 'Authorization code'
|
76
|
+
|
77
|
+
authorized_applications:
|
78
|
+
confirmations:
|
79
|
+
revoke: 'Are you sure?'
|
80
|
+
buttons:
|
81
|
+
revoke: 'Revoke'
|
82
|
+
index:
|
83
|
+
title: 'Your authorized applications'
|
84
|
+
application: 'Application'
|
85
|
+
created_at: 'Created At'
|
86
|
+
date_format: '%Y-%m-%d %H:%M:%S'
|
87
|
+
|
88
|
+
pre_authorization:
|
89
|
+
status: 'Pre-authorization'
|
90
|
+
|
91
|
+
errors:
|
92
|
+
messages:
|
93
|
+
# Common error messages
|
94
|
+
invalid_request:
|
95
|
+
unknown: 'The request is missing a required parameter, includes an unsupported parameter value, or is otherwise malformed.'
|
96
|
+
missing_param: 'Missing required parameter: %{value}.'
|
97
|
+
not_support_pkce: 'Invalid code_verifier parameter. Server does not support pkce.'
|
98
|
+
request_not_authorized: 'Request need to be authorized. Required parameter for authorizing request is missing or invalid.'
|
99
|
+
invalid_redirect_uri: "The requested redirect uri is malformed or doesn't match client redirect URI."
|
100
|
+
unauthorized_client: 'The client is not authorized to perform this request using this method.'
|
101
|
+
access_denied: 'The resource owner or authorization server denied the request.'
|
102
|
+
invalid_scope: 'The requested scope is invalid, unknown, or malformed.'
|
103
|
+
invalid_code_challenge_method: 'The code challenge method must be plain or S256.'
|
104
|
+
server_error: 'The authorization server encountered an unexpected condition which prevented it from fulfilling the request.'
|
105
|
+
temporarily_unavailable: 'The authorization server is currently unable to handle the request due to a temporary overloading or maintenance of the server.'
|
106
|
+
|
107
|
+
# Configuration error messages
|
108
|
+
credential_flow_not_configured: 'Resource Owner Password Credentials flow failed due to Doorkeeper.configure.resource_owner_from_credentials being unconfigured.'
|
109
|
+
resource_owner_authenticator_not_configured: 'Resource Owner find failed due to Doorkeeper.configure.resource_owner_authenticator being unconfigured.'
|
110
|
+
admin_authenticator_not_configured: 'Access to admin panel is forbidden due to Doorkeeper.configure.admin_authenticator being unconfigured.'
|
111
|
+
|
112
|
+
# Access grant errors
|
113
|
+
unsupported_response_type: 'The authorization server does not support this response type.'
|
114
|
+
|
115
|
+
# Access token errors
|
116
|
+
invalid_client: 'Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method.'
|
117
|
+
invalid_grant: 'The provided authorization grant is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.'
|
118
|
+
unsupported_grant_type: 'The authorization grant type is not supported by the authorization server.'
|
119
|
+
|
120
|
+
invalid_token:
|
121
|
+
revoked: "The access token was revoked"
|
122
|
+
expired: "The access token expired"
|
123
|
+
unknown: "The access token is invalid"
|
124
|
+
revoke:
|
125
|
+
unauthorized: "You are not authorized to revoke this token"
|
126
|
+
|
127
|
+
flash:
|
128
|
+
applications:
|
129
|
+
create:
|
130
|
+
notice: 'Application created.'
|
131
|
+
destroy:
|
132
|
+
notice: 'Application deleted.'
|
133
|
+
update:
|
134
|
+
notice: 'Application updated.'
|
135
|
+
authorized_applications:
|
136
|
+
destroy:
|
137
|
+
notice: 'Application revoked.'
|
138
|
+
|
139
|
+
layouts:
|
140
|
+
admin:
|
141
|
+
title: 'Doorkeeper'
|
142
|
+
nav:
|
143
|
+
oauth2_provider: 'OAuth2 Provider'
|
144
|
+
applications: 'Applications'
|
145
|
+
home: 'Home'
|
146
|
+
application:
|
147
|
+
title: 'OAuth authorization required'
|
148
|
+
|
149
|
+
scopes:
|
150
|
+
delete: "Your OAuth application is missing the 'delete' scope to access this API method."
|
151
|
+
read: "Your OAuth application is missing the 'read' scope to access this API method."
|
152
|
+
write: "Your OAuth application is missing the 'write' scope to access this API method."
|
@@ -0,0 +1,15 @@
|
|
1
|
+
en:
|
2
|
+
stripe_connect: Stripe
|
3
|
+
# š
super scaffolding will insert new oauth providers above this line.
|
4
|
+
omniauth:
|
5
|
+
team:
|
6
|
+
connected: "We've successfully added that %{provider} account to your team!"
|
7
|
+
denied: "Permission to connect to %{provider} was not granted. Not a problem! You can try again if you want to."
|
8
|
+
already_present: "That %{provider} account is already present for this team!"
|
9
|
+
not_allowed: "You're not allowed to add a %{provider} account to a team you don't have access to."
|
10
|
+
user:
|
11
|
+
connected: "We've successfully connected that %{provider} account to your user account."
|
12
|
+
reconnected: "That %{provider} account is already connected to your user account."
|
13
|
+
already_registered: "That %{provider} account is already connected to another user. Before you can connect that %{provider} account with your user account, you'll need to sign out and sign back in using that account and remove it from that user account profile."
|
14
|
+
email_already_registered: "Sorry, there is already a user registered with the email address %{email}, but this %{provider} account isn't configured for login with that account. Please sign in using your password and then add this account."
|
15
|
+
account_not_found: "Sorry, no existing account was found for that %{provider} account. In order to create a new account, please click the link in the invitation you received via email."
|
@@ -0,0 +1,36 @@
|
|
1
|
+
en:
|
2
|
+
user_mailer:
|
3
|
+
signature: &SIGNATURE
|
4
|
+
html:
|
5
|
+
<p>If you have any questions, please don't hesitate to <a href="mailto:%{support_email}">send us an email</a>.</p>
|
6
|
+
<p>Thanks,<br>Bullet Train, Inc.</p>
|
7
|
+
invited:
|
8
|
+
subject: Invitation to join %{team_name} on Bullet Train!
|
9
|
+
preview: '%{inviter_name} has sent you this invitation.'
|
10
|
+
heading: You're invited!
|
11
|
+
body:
|
12
|
+
html:
|
13
|
+
<p>
|
14
|
+
%{inviter_name} has invited you to join %{team_name} on Bullet Train.
|
15
|
+
You can join %{team_name} by clicking the button below.
|
16
|
+
</p>
|
17
|
+
cta:
|
18
|
+
label: Join %{team_name}
|
19
|
+
signature:
|
20
|
+
<<: *SIGNATURE
|
21
|
+
welcome:
|
22
|
+
subject: Welcome to the Bullet Train demo!
|
23
|
+
preview: This is the default Bullet Train welcome email. Check out the layout!
|
24
|
+
heading: Welcome to Bullet Train!
|
25
|
+
body:
|
26
|
+
html:
|
27
|
+
<p>This is the default welcome email for Bullet Train!</p>
|
28
|
+
<p>If you have any questions about Bullet Train, just reply to this email!</p>
|
29
|
+
<p>It was important to us that Bullet Train applications have a good looking, branded email template by default.</p>
|
30
|
+
<p>Thankfully our friends at <a href="https://postmarkapp.com">Postmark</a> made the foundation of this email template <a href="https://github.com/wildbit/postmark-templates">freely available</a>. From there, we've customized it slightly to better match the default Bullet Train look-and-feel.</p>
|
31
|
+
cta:
|
32
|
+
heading: What's next?
|
33
|
+
body: You can use the following link to always return to your Bullet Train account dashboard.
|
34
|
+
label: View Your Account Dashboard
|
35
|
+
signature:
|
36
|
+
<<: *SIGNATURE
|
@@ -0,0 +1,148 @@
|
|
1
|
+
require 'io/wait'
|
2
|
+
|
3
|
+
module BulletTrain
|
4
|
+
class Resolver
|
5
|
+
def initialize(needle)
|
6
|
+
@needle = needle
|
7
|
+
end
|
8
|
+
|
9
|
+
def run(eject: false, open: false, force: false, interactive: false)
|
10
|
+
# Try to figure out what kind of thing they're trying to look up.
|
11
|
+
source_file = calculate_source_file_details
|
12
|
+
|
13
|
+
if source_file[:absolute_path]
|
14
|
+
if source_file[:package_name].present?
|
15
|
+
puts ""
|
16
|
+
puts "Absolute path:".green
|
17
|
+
puts " #{source_file[:absolute_path]}".green
|
18
|
+
puts ""
|
19
|
+
puts "Package name:".green
|
20
|
+
puts " #{source_file[:package_name]}".green
|
21
|
+
puts ""
|
22
|
+
else
|
23
|
+
puts ""
|
24
|
+
puts "Project path:".green
|
25
|
+
puts " #{source_file[:project_path]}".green
|
26
|
+
puts ""
|
27
|
+
puts "Note: If this file was previously ejected from a package, we can no longer see which package it came from. However, it should say at the top of the file where it was ejected from.".yellow
|
28
|
+
puts ""
|
29
|
+
end
|
30
|
+
|
31
|
+
if interactive && !eject
|
32
|
+
puts "\nWould you like to eject the file into the local project? (y/n)\n"
|
33
|
+
input = $stdin.gets
|
34
|
+
$stdin.getc while $stdin.ready?
|
35
|
+
if input.first.downcase == 'y'
|
36
|
+
eject = true
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
if eject
|
41
|
+
if source_file[:package_name]
|
42
|
+
if File.exist?(source_file[:project_path]) && !force
|
43
|
+
return puts "Can't eject! `#{source_file[:project_path]}` already exists!\n".red
|
44
|
+
else
|
45
|
+
`mkdir -p #{source_file[:project_path].split("/")[0...-1].join("/")}`
|
46
|
+
puts "Ejecting `#{source_file[:absolute_path]}` to `#{source_file[:project_path]}`".green
|
47
|
+
File.open("#{source_file[:project_path]}", "w+") do |file|
|
48
|
+
case source_file[:project_path].split(".").last
|
49
|
+
when "rb", "yml"
|
50
|
+
file.puts "# Ejected from `#{source_file[:package_name]}`.\n\n"
|
51
|
+
when "erb"
|
52
|
+
file.puts "<% # Ejected from `#{source_file[:package_name]}`. %>\n\n"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
`cat #{source_file[:absolute_path]} >> #{source_file[:project_path]}`.strip
|
56
|
+
end
|
57
|
+
|
58
|
+
# Just in case they try to open the file, open it from the new location.
|
59
|
+
source_file[:absolute_path] = source_file[:project_path]
|
60
|
+
else
|
61
|
+
puts "This file is already in the local project directory. Skipping ejection.".yellow
|
62
|
+
puts ""
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
if interactive && !open
|
67
|
+
puts "\nWould you like to open `#{source_file[:absolute_path]}`? (y/n)\n"
|
68
|
+
input = $stdin.gets
|
69
|
+
$stdin.getc while $stdin.ready?
|
70
|
+
if input.first.downcase == 'y'
|
71
|
+
open = true
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
if open
|
76
|
+
path = source_file[:package_name] ? source_file[:absolute_path] : "#{source_file[:project_path]}"
|
77
|
+
puts "Opening `#{path}`.\n".green
|
78
|
+
exec "open #{path}"
|
79
|
+
end
|
80
|
+
else
|
81
|
+
puts "Couldn't resolve `#{@needle}`.".red
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def calculate_source_file_details
|
86
|
+
result = {
|
87
|
+
absolute_path: nil,
|
88
|
+
project_path: nil,
|
89
|
+
package_name: nil,
|
90
|
+
}
|
91
|
+
|
92
|
+
result[:absolute_path] = class_path || partial_path || file_path
|
93
|
+
|
94
|
+
if result[:absolute_path]
|
95
|
+
base_path = "bullet_train" + result[:absolute_path].split("/bullet_train").last
|
96
|
+
|
97
|
+
# Try to calculate which package the file is from, and what it's path is within that project.
|
98
|
+
["app", "config", "lib"].each do |directory|
|
99
|
+
regex = /\/#{directory}\//
|
100
|
+
if base_path.match?(regex)
|
101
|
+
project_path = "./#{directory}/#{base_path.rpartition(regex).last}"
|
102
|
+
package_name = base_path.rpartition(regex).first.split("/").last
|
103
|
+
# If the "package name" is actually just the local project directory.
|
104
|
+
if package_name == `pwd`.chomp.split("/").last
|
105
|
+
package_name = nil
|
106
|
+
end
|
107
|
+
|
108
|
+
result[:project_path] = project_path
|
109
|
+
result[:package_name] = package_name
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
result
|
115
|
+
end
|
116
|
+
|
117
|
+
def url?
|
118
|
+
@needle.match?(/https?:\/\//)
|
119
|
+
end
|
120
|
+
|
121
|
+
def class_path
|
122
|
+
begin
|
123
|
+
@needle.constantize
|
124
|
+
return Object.const_source_location(@needle).first
|
125
|
+
rescue NameError => _
|
126
|
+
return false
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def partial_path
|
131
|
+
begin
|
132
|
+
xray_path = ApplicationController.render(template: "bullet_train/partial_resolver", layout: nil, assigns: {needle: @needle}).lines[1].chomp
|
133
|
+
if xray_path.match(/<!--XRAY START \d+ (.*)-->/)
|
134
|
+
return $1
|
135
|
+
else
|
136
|
+
raise "It looks like Xray-rails isn't properly enabled?"
|
137
|
+
end
|
138
|
+
rescue ActionView::Template::Error => _
|
139
|
+
return nil
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def file_path
|
144
|
+
# We don't have to do anything here... the absolute path is what we're passed, and we just pass it back.
|
145
|
+
@needle
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
data/lib/bullet_train/version.rb
CHANGED
data/lib/bullet_train.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'io/wait'
|
2
|
+
|
1
3
|
namespace :bullet_train do
|
2
4
|
desc "Symlink registered gems in `./tmp/gems` so their views, etc. can be inspected by Tailwind CSS."
|
3
5
|
task :link_gems => :environment do
|
@@ -23,4 +25,33 @@ namespace :bullet_train do
|
|
23
25
|
end
|
24
26
|
end
|
25
27
|
end
|
28
|
+
|
29
|
+
desc "Figure out where something is coming from."
|
30
|
+
task :resolve, [:all_options] => :environment do |t, arguments|
|
31
|
+
ARGV.pop while ARGV.any?
|
32
|
+
|
33
|
+
arguments[:all_options]&.split&.each do |argument|
|
34
|
+
ARGV.push(argument)
|
35
|
+
end
|
36
|
+
|
37
|
+
if ARGV.include?("--interactive")
|
38
|
+
puts "\nOK, paste what you've got for us and hit <Return>!\n".blue
|
39
|
+
|
40
|
+
input = $stdin.gets.strip
|
41
|
+
$stdin.getc while $stdin.ready?
|
42
|
+
|
43
|
+
# Extract absolute paths from XRAY comments.
|
44
|
+
if input.match(/<!--XRAY START \d+ (.*)-->/)
|
45
|
+
input = $1
|
46
|
+
end
|
47
|
+
|
48
|
+
ARGV.unshift input.strip
|
49
|
+
end
|
50
|
+
|
51
|
+
if ARGV.first.present?
|
52
|
+
BulletTrain::Resolver.new(ARGV.first).run(eject: ARGV.include?("--eject"), open: ARGV.include?("--open"), force: ARGV.include?("--force"), interactive: ARGV.include?("--interactive"))
|
53
|
+
else
|
54
|
+
$stderr.puts "\nš
Usage: `bin/resolve [path, partial, or URL] (--eject) (--open)`\n".blue
|
55
|
+
end
|
56
|
+
end
|
26
57
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bullet_train
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.30
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Culver
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-03-
|
11
|
+
date: 2022-03-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -399,6 +399,7 @@ files:
|
|
399
399
|
- app/mailers/concerns/mailers/base.rb
|
400
400
|
- app/mailers/devise_mailer.rb
|
401
401
|
- app/mailers/user_mailer.rb
|
402
|
+
- app/models/concerns/current_attributes/base.rb
|
402
403
|
- app/models/concerns/invitations/base.rb
|
403
404
|
- app/models/concerns/memberships/base.rb
|
404
405
|
- app/models/concerns/records/base.rb
|
@@ -449,6 +450,7 @@ files:
|
|
449
450
|
- app/views/account/users/_form.html.erb
|
450
451
|
- app/views/account/users/edit.html.erb
|
451
452
|
- app/views/account/users/show.html.erb
|
453
|
+
- app/views/bullet_train/partial_resolver.html.erb
|
452
454
|
- app/views/devise/confirmations/new.html.erb
|
453
455
|
- app/views/devise/mailer/confirmation_instructions.html.erb
|
454
456
|
- app/views/devise/mailer/password_change.html.erb
|
@@ -471,12 +473,17 @@ files:
|
|
471
473
|
- app/views/public/home/docs.html.erb
|
472
474
|
- app/views/user_mailer/invited.html.erb
|
473
475
|
- app/views/user_mailer/welcome.html.erb
|
476
|
+
- config/locales/en/base.yml
|
474
477
|
- config/locales/en/devise.en.yml
|
478
|
+
- config/locales/en/doorkeeper.en.yml
|
475
479
|
- config/locales/en/invitations.en.yml
|
476
480
|
- config/locales/en/memberships.en.yml
|
481
|
+
- config/locales/en/oauth.en.yml
|
477
482
|
- config/locales/en/onboarding/user_details.en.yml
|
478
483
|
- config/locales/en/onboarding/user_email.en.yml
|
484
|
+
- config/locales/en/roles.en.yml
|
479
485
|
- config/locales/en/teams.en.yml
|
486
|
+
- config/locales/en/user_mailer.en.yml
|
480
487
|
- config/locales/en/users.en.yml
|
481
488
|
- config/routes.rb
|
482
489
|
- db/migrate/20161115160419_devise_create_users.rb
|
@@ -516,6 +523,7 @@ files:
|
|
516
523
|
- db/migrate/20211027002944_add_doorkeeper_application_to_users.rb
|
517
524
|
- lib/bullet_train.rb
|
518
525
|
- lib/bullet_train/engine.rb
|
526
|
+
- lib/bullet_train/resolver.rb
|
519
527
|
- lib/bullet_train/version.rb
|
520
528
|
- lib/colorizer.rb
|
521
529
|
- lib/string/emoji.rb
|