bullet_train 1.0.27 ā 1.0.30
Sign up to get free protection for your applications and to get access to all the features.
- 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
|