crosstie 0.0.6 → 0.0.7
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/CHANGELOG.md +24 -0
- data/lib/crosstie/base.rb +19 -1
- data/lib/crosstie/cli.rb +17 -13
- data/lib/crosstie/templates/active_job.rb +7 -7
- data/lib/crosstie/templates/authorization/application_controller.rb +1 -1
- data/lib/crosstie/templates/authorization/index.html.slim +1 -1
- data/lib/crosstie/templates/bullet.rb +9 -0
- data/lib/crosstie/templates/bundle_install.rb +5 -2
- data/lib/crosstie/templates/devise.rb +3 -0
- data/lib/crosstie/templates/guard.rb +0 -1
- data/lib/crosstie/templates/helper.rb +15 -0
- data/lib/crosstie/templates/install_gems.rb +2 -1
- data/lib/crosstie/templates/rails_layout.rb +10 -0
- data/lib/crosstie/templates/resources.rb +20 -8
- data/lib/crosstie/templates/run_seeds.rb +1 -0
- data/lib/crosstie/templates/seeds.rb +0 -4
- data/lib/crosstie/templates/skeleton.rb +4 -0
- data/lib/crosstie/templates/static_pages.rb +32 -1
- data/lib/crosstie/templates/user.rb +46 -1
- data/lib/crosstie/templates/web_console.rb +5 -0
- data/lib/crosstie/version.rb +1 -1
- data/run.sh +16 -0
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ee1aab6bb3ef46c676246f26c92e5fe8e89492c9
|
4
|
+
data.tar.gz: 0a5a7e4aaa0f060b372967672b7aaf7ca148f621
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 743c95838863f2ec1161e493862ea5a18bd3a0353ad23d0ec86b2122ebdb8d488eb7d9362ab8a8bdb8eb64add50785765ea28527dcbe1d643d9a006e14f2b722
|
7
|
+
data.tar.gz: 43d105ecb8afb80bd2120982e63b7d168ee551d34f01929702b4c99ce8d27c81c32f40fa192f8f31cb26a4bfd8bfb08a707d87a2edb647e0ec98e9000bf0d065
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
### Unreleased
|
2
|
+
|
3
|
+
### 0.0.7
|
4
|
+
* run.sh for development and test
|
5
|
+
* local install flag
|
6
|
+
* remove spring from Guardfile
|
7
|
+
* update gem figaro to 1.1.1
|
8
|
+
* add bullet
|
9
|
+
* grant all roles to the first user
|
10
|
+
* add spec/routing/static_pages_spec.rb
|
11
|
+
* add app/helpers/application_helper.rb
|
12
|
+
* comment config/initializers/sidekiq.rb
|
13
|
+
* uncomment secret_key in config/initializers/devise.rb
|
14
|
+
* app/view/layouts/_navigation_links.html.slim
|
15
|
+
* rails new --skip-spring --skip-bundle --skip-test-unit
|
16
|
+
* seed at last
|
17
|
+
* improve controller tests
|
18
|
+
* adjust task order
|
19
|
+
* add normal role for signed up users
|
20
|
+
* fix bug: non normal user cannot sign out
|
21
|
+
* sign in form input order
|
22
|
+
* sign up form auto focus on username
|
23
|
+
* colorful user role activation
|
24
|
+
* web console
|
data/lib/crosstie/base.rb
CHANGED
@@ -15,6 +15,21 @@ end
|
|
15
15
|
|
16
16
|
def perform task
|
17
17
|
eval File.read File.join root, "templates", "#{task}.rb"
|
18
|
+
rescue => e
|
19
|
+
puts "error on performing #{task}"
|
20
|
+
raise e
|
21
|
+
end
|
22
|
+
|
23
|
+
def config
|
24
|
+
return @config if @config
|
25
|
+
config_path = '/tmp/crosstie/config.yml'
|
26
|
+
if File.exist? config_path
|
27
|
+
@config = YAML.load(File.read(config_path))
|
28
|
+
File.delete config_path
|
29
|
+
else
|
30
|
+
@config = {}
|
31
|
+
end
|
32
|
+
@config
|
18
33
|
end
|
19
34
|
|
20
35
|
perform :git_init
|
@@ -34,6 +49,7 @@ perform :simple_form
|
|
34
49
|
perform :rspec
|
35
50
|
perform :guard
|
36
51
|
perform :static_pages
|
52
|
+
perform :web_console
|
37
53
|
perform :devise
|
38
54
|
perform :rails_layout # authform for device
|
39
55
|
perform :user
|
@@ -42,7 +58,9 @@ perform :controller_helpers
|
|
42
58
|
perform :authentication_token
|
43
59
|
perform :rolify
|
44
60
|
perform :authorization
|
45
|
-
perform :
|
61
|
+
perform :helper
|
46
62
|
perform :resources
|
63
|
+
perform :seeds
|
47
64
|
git_commit "project created"
|
48
65
|
perform :run_test
|
66
|
+
perform :run_seeds
|
data/lib/crosstie/cli.rb
CHANGED
@@ -8,25 +8,29 @@ module Crosstie
|
|
8
8
|
|
9
9
|
desc 'new my_app', 'create a new rails application'
|
10
10
|
def new name
|
11
|
-
if File.exist? '
|
11
|
+
if File.exist? 'config.yml'
|
12
12
|
FileUtils.mkdir_p '/tmp/crosstie'
|
13
|
-
FileUtils.cp '
|
13
|
+
FileUtils.cp 'config.yml', '/tmp/crosstie/config.yml'
|
14
14
|
end
|
15
|
-
cmd = "rails new #{name} --template #{template_path}"
|
15
|
+
cmd = "rails new #{name} --template #{template_path} --skip-spring --skip-test-unit --skip-bundle"
|
16
16
|
puts cmd
|
17
17
|
system cmd
|
18
18
|
end
|
19
19
|
|
20
|
-
desc '
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
20
|
+
desc 'config', 'create a config.yml template'
|
21
|
+
option :local, type: :boolean
|
22
|
+
def config
|
23
|
+
puts 'writing config.yml'
|
24
|
+
File.write 'config.yml', <<-EOF
|
25
|
+
options:
|
26
|
+
local: #{!!options[:local]}
|
27
|
+
resources:
|
28
|
+
article:
|
29
|
+
- title:string
|
30
|
+
- content:text
|
31
|
+
comment:
|
32
|
+
- article:references
|
33
|
+
- content:text
|
30
34
|
EOF
|
31
35
|
end
|
32
36
|
|
@@ -6,13 +6,13 @@ EOF
|
|
6
6
|
run "cp config/application.yml config/application.yml.example"
|
7
7
|
|
8
8
|
create_file "config/initializers/sidekiq.rb", <<-EOF
|
9
|
-
Sidekiq.configure_server do |config|
|
10
|
-
config.redis = { :url => "redis://\#{ENV['REDIS_HOST']}:\#{ENV['REDIS_PORT']}/0", :namespace => '#{app_path}' }
|
11
|
-
end
|
12
|
-
|
13
|
-
Sidekiq.configure_client do |config|
|
14
|
-
config.redis = { :url => "redis://\#{ENV['REDIS_HOST']}:\#{ENV['REDIS_PORT']}/0", :namespace => '#{app_path}' }
|
15
|
-
end
|
9
|
+
#Sidekiq.configure_server do |config|
|
10
|
+
# config.redis = { :url => "redis://\#{ENV['REDIS_HOST']}:\#{ENV['REDIS_PORT']}/0", :namespace => '#{app_path}' }
|
11
|
+
#end
|
12
|
+
#
|
13
|
+
#Sidekiq.configure_client do |config|
|
14
|
+
# config.redis = { :url => "redis://\#{ENV['REDIS_HOST']}:\#{ENV['REDIS_PORT']}/0", :namespace => '#{app_path}' }
|
15
|
+
#end
|
16
16
|
EOF
|
17
17
|
|
18
18
|
create_file "tmp/pids/.keep", ""
|
@@ -1,6 +1,9 @@
|
|
1
1
|
# devise
|
2
2
|
generate "devise:install"
|
3
3
|
|
4
|
+
# secret key
|
5
|
+
gsub_file "config/initializers/devise.rb", "# config.secret_key", "config.secret_key"
|
6
|
+
|
4
7
|
# improve password strength
|
5
8
|
gsub_file "config/initializers/devise.rb", "config.password_length = 8..128", "config.password_length = 4..128"
|
6
9
|
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# helper
|
2
|
+
inject_into_file "app/helpers/application_helper.rb", after: "module ApplicationHelper\n" do
|
3
|
+
<<-EOF
|
4
|
+
|
5
|
+
def link_for obj, name = :name, i: false, b: false
|
6
|
+
return nil unless obj
|
7
|
+
raise "not respond to \#{name}" unless obj.respond_to? name
|
8
|
+
|
9
|
+
html = link_to obj.send(name), obj
|
10
|
+
html = content_tag :i, html if i
|
11
|
+
html = content_tag :b, html if b
|
12
|
+
html
|
13
|
+
end
|
14
|
+
EOF
|
15
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
gem 'slim-rails', '3.0.1'
|
2
2
|
gem 'therubyracer', '0.12.2'
|
3
|
-
gem 'figaro', '1.1.
|
3
|
+
gem 'figaro', '1.1.1'
|
4
4
|
gem 'bootstrap-sass', '3.3.4.1'
|
5
5
|
gem 'simple_form', '3.1.0'
|
6
6
|
gem 'quiet_assets', '1.1.0'
|
@@ -22,6 +22,7 @@ gem_group :development do
|
|
22
22
|
gem 'rack-mini-profiler', '0.9.3'
|
23
23
|
gem 'rails_layout', '1.0.25'
|
24
24
|
gem 'annotate', '2.6.8'
|
25
|
+
gem 'bullet', '4.14.7'
|
25
26
|
end
|
26
27
|
|
27
28
|
gem_group :development, :test do
|
@@ -1,2 +1,12 @@
|
|
1
1
|
generate 'layout:install', 'bootstrap3', '--force'
|
2
2
|
generate 'layout:devise', 'bootstrap3'
|
3
|
+
|
4
|
+
remove_file "app/views/layouts/_navigation_links.html.erb"
|
5
|
+
create_file "app/views/layouts/_navigation_links.html.slim", <<-EOF
|
6
|
+
- if user_signed_in?
|
7
|
+
li = link_to 'Users', users_path
|
8
|
+
li = link_to "Sign out", destroy_user_session_path, method: :delete
|
9
|
+
- else
|
10
|
+
li = link_to "Sign in", new_user_session_path
|
11
|
+
li = link_to "Sign up", new_user_registration_path
|
12
|
+
EOF
|
@@ -1,22 +1,34 @@
|
|
1
1
|
# scaffold resources
|
2
|
-
|
3
|
-
if
|
4
|
-
|
2
|
+
|
3
|
+
if config['resources']
|
4
|
+
|
5
|
+
config['resources'].each do |resource, fields|
|
6
|
+
|
5
7
|
generate "scaffold", resource, *fields
|
8
|
+
|
6
9
|
rake "db:migrate"
|
7
|
-
|
10
|
+
|
11
|
+
inject_into_file "spec/controllers/#{resource.tableize}_controller_spec.rb", after: "RSpec.describe #{resource.tableize.camelize}Controller, type: :controller do\n" do
|
8
12
|
<<-EOF
|
9
13
|
|
10
|
-
before
|
14
|
+
before do
|
15
|
+
sign_in_user
|
16
|
+
@#{resource} = FactoryGirl.build(:#{resource})
|
17
|
+
end
|
11
18
|
EOF
|
12
19
|
end
|
13
20
|
|
14
21
|
gsub_file "spec/controllers/#{resource.tableize}_controller_spec.rb",
|
15
22
|
'skip("Add a hash of attributes valid for your model")',
|
16
|
-
"
|
17
|
-
|
23
|
+
"@#{resource}.attributes"
|
24
|
+
|
25
|
+
inject_into_file "app/views/layouts/_navigation_links.html.slim", after: "- if user_signed_in?\n" do
|
26
|
+
<<-EOF
|
27
|
+
li = link_to '#{resource.tableize.titleize}', #{resource.tableize}_path
|
28
|
+
EOF
|
29
|
+
end
|
18
30
|
|
19
|
-
|
31
|
+
end
|
20
32
|
|
21
33
|
run "bundle exec annotate"
|
22
34
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
rake "db:seed"
|
@@ -1,8 +1,4 @@
|
|
1
1
|
append_file "db/seeds.rb", <<-EOF
|
2
2
|
user = User.create! username: "admin", email: "admin@example.com", password: "password"
|
3
|
-
Role::USER_ROLES.each do |role|
|
4
|
-
user.grant role
|
5
|
-
end
|
6
3
|
puts "sign in with:\n\tusername: admin\n\tpassword: password"
|
7
4
|
EOF
|
8
|
-
rake "db:seed"
|
@@ -21,6 +21,8 @@ inject_into_file "config/application.rb", after: "class Application < Rails::App
|
|
21
21
|
|
22
22
|
# active_job
|
23
23
|
|
24
|
+
# web_console
|
25
|
+
|
24
26
|
EOF
|
25
27
|
end
|
26
28
|
|
@@ -30,5 +32,7 @@ inject_into_file "config/routes.rb", after: "Rails.application.routes.draw do\n"
|
|
30
32
|
|
31
33
|
# active_job
|
32
34
|
|
35
|
+
# web_console
|
36
|
+
|
33
37
|
EOF
|
34
38
|
end
|
@@ -1,11 +1,14 @@
|
|
1
1
|
# static pages
|
2
|
-
generate "controller", "static_pages", "home", "status"
|
2
|
+
generate "controller", "static_pages", "home", "status", "console"
|
3
|
+
|
3
4
|
inject_into_file "app/controllers/static_pages_controller.rb", after: "class StaticPagesController < ApplicationController\n" do
|
4
5
|
<<-EOF
|
5
6
|
skip_before_action :authenticate_user!, only: [:home, :status]
|
6
7
|
skip_before_action :authenticate_normal!, only: [:home, :status]
|
8
|
+
before_action :authenticate_system!, only: [:console]
|
7
9
|
EOF
|
8
10
|
end
|
11
|
+
|
9
12
|
inject_into_file "app/controllers/static_pages_controller.rb", after: "def status\n" do
|
10
13
|
<<-EOF
|
11
14
|
render json: {
|
@@ -16,11 +19,39 @@ inject_into_file "app/controllers/static_pages_controller.rb", after: "def statu
|
|
16
19
|
}
|
17
20
|
EOF
|
18
21
|
end
|
22
|
+
|
19
23
|
gsub_file "config/routes.rb", "get 'static_pages/home'", "root to: 'static_pages#home'"
|
20
24
|
gsub_file "config/routes.rb", "get 'static_pages/status'", "get '/status' => 'static_pages#status'"
|
25
|
+
gsub_file "config/routes.rb", "get 'static_pages/console'", "get '/console' => 'static_pages#console'"
|
26
|
+
|
21
27
|
inject_into_file "spec/controllers/static_pages_controller_spec.rb", after: "RSpec.describe StaticPagesController, type: :controller do\n" do
|
22
28
|
<<-EOF
|
23
29
|
|
24
30
|
before { sign_in_user }
|
25
31
|
EOF
|
26
32
|
end
|
33
|
+
|
34
|
+
create_file "spec/routing/static_pages_spec.rb", <<-EOF
|
35
|
+
require "rails_helper"
|
36
|
+
|
37
|
+
describe StaticPagesController, :type => :routing do
|
38
|
+
describe "routing" do
|
39
|
+
|
40
|
+
it "routes to #home" do
|
41
|
+
expect(:get => "/").to route_to("static_pages#home")
|
42
|
+
end
|
43
|
+
|
44
|
+
it "routes to #status" do
|
45
|
+
expect(:get => "/status").to route_to("static_pages#status")
|
46
|
+
end
|
47
|
+
|
48
|
+
it "routes to #console" do
|
49
|
+
expect(:get => "/console").to route_to("static_pages#console")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
EOF
|
54
|
+
|
55
|
+
append_file "app/views/static_pages/console.html.slim", <<-EOF
|
56
|
+
= console
|
57
|
+
EOF
|
@@ -6,6 +6,10 @@ inject_into_file "app/models/user.rb", before: 'end' do
|
|
6
6
|
|
7
7
|
# ldap
|
8
8
|
|
9
|
+
# grant roles
|
10
|
+
|
11
|
+
# grant normal
|
12
|
+
|
9
13
|
# username
|
10
14
|
|
11
15
|
# authentication_token
|
@@ -15,6 +19,40 @@ inject_into_file "app/models/user.rb", before: 'end' do
|
|
15
19
|
EOF
|
16
20
|
end
|
17
21
|
|
22
|
+
# grant roles for the first user
|
23
|
+
inject_into_file "app/models/user.rb", after: "# grant roles\n" do
|
24
|
+
<<-EOF
|
25
|
+
after_create :grant_roles, if: Proc.new {
|
26
|
+
!Rails.env.test? && User.count == 1
|
27
|
+
}
|
28
|
+
|
29
|
+
def grant_roles
|
30
|
+
Role::USER_ROLES.each do |role|
|
31
|
+
self.grant role
|
32
|
+
end
|
33
|
+
end
|
34
|
+
EOF
|
35
|
+
end
|
36
|
+
|
37
|
+
# grant normal role for signed up users
|
38
|
+
inject_into_file "app/models/user.rb", after: "# grant normal\n" do
|
39
|
+
<<-EOF
|
40
|
+
after_create :grant_normal, if: Proc.new {
|
41
|
+
ENV['GRANT_NORMAL']
|
42
|
+
}
|
43
|
+
|
44
|
+
def grant_normal
|
45
|
+
self.grant :normal
|
46
|
+
end
|
47
|
+
EOF
|
48
|
+
end
|
49
|
+
|
50
|
+
append_file "config/application.yml", <<-EOF
|
51
|
+
#GRANT_NORMAL: true
|
52
|
+
EOF
|
53
|
+
run "cp config/application.yml config/application.yml.example"
|
54
|
+
|
55
|
+
|
18
56
|
# add username to users
|
19
57
|
inject_into_file "app/models/user.rb", after: "# username\n" do
|
20
58
|
<<-EOF
|
@@ -32,14 +70,21 @@ gsub_file "app/views/devise/sessions/new.html.erb", "email_field", "text_field"
|
|
32
70
|
"app/views/devise/registrations/new.html.erb",
|
33
71
|
"app/views/devise/registrations/edit.html.erb",
|
34
72
|
].each do |file|
|
73
|
+
gsub_file file, ", :autofocus => true", ""
|
35
74
|
inject_into_file file, after: "<%= devise_error_messages! %>\n" do
|
36
75
|
<<-EOF
|
37
76
|
<div class="form-group">
|
38
77
|
<%= f.label :username %>
|
39
|
-
<%= f.text_field :username, class: 'form-control' %>
|
78
|
+
<%= f.text_field :username, autofocus: true, class: 'form-control' %>
|
40
79
|
</div>
|
41
80
|
EOF
|
42
81
|
end
|
43
82
|
end
|
44
83
|
|
45
84
|
gsub_file "config/initializers/devise.rb", "# config.authentication_keys = [ :email ]", "config.authentication_keys = [ :username ]"
|
85
|
+
|
86
|
+
# add tabindex to sign in
|
87
|
+
inject_into_file "app/views/devise/sessions/new.html.erb", ", tabindex: 1", after: "f.text_field :username"
|
88
|
+
inject_into_file "app/views/devise/sessions/new.html.erb", ", tabindex: 2", after: "f.password_field :password"
|
89
|
+
inject_into_file "app/views/devise/sessions/new.html.erb", ", tabindex: 3", after: "f.check_box :remember_me"
|
90
|
+
inject_into_file "app/views/devise/sessions/new.html.erb", ", tabindex: 4", after: "f.submit 'Sign in'"
|
data/lib/crosstie/version.rb
CHANGED
data/run.sh
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
version=`ruby -Ilib -e 'require "crosstie/version"; puts Crosstie::VERSION'`
|
4
|
+
spec=crosstie.gemspec
|
5
|
+
gem=crosstie-$version.gem
|
6
|
+
|
7
|
+
rm -r $gem
|
8
|
+
gem build $spec
|
9
|
+
gem install $gem --local
|
10
|
+
mkdir -p tmp
|
11
|
+
cd tmp
|
12
|
+
pwd
|
13
|
+
ps aux | grep spring | awk '{print $2}' | xargs kill -9
|
14
|
+
rm -rf sandbox
|
15
|
+
crosstie config --local
|
16
|
+
crosstie new sandbox
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: crosstie
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dong Qingshan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-05-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -61,6 +61,7 @@ extensions: []
|
|
61
61
|
extra_rdoc_files: []
|
62
62
|
files:
|
63
63
|
- ".gitignore"
|
64
|
+
- CHANGELOG.md
|
64
65
|
- Gemfile
|
65
66
|
- LICENSE.txt
|
66
67
|
- README.md
|
@@ -80,6 +81,7 @@ files:
|
|
80
81
|
- lib/crosstie/templates/authorization/users.rb
|
81
82
|
- lib/crosstie/templates/authorization/users_controller.rb
|
82
83
|
- lib/crosstie/templates/authorization/users_controller_spec.rb
|
84
|
+
- lib/crosstie/templates/bullet.rb
|
83
85
|
- lib/crosstie/templates/bundle_install.rb
|
84
86
|
- lib/crosstie/templates/change_source.rb
|
85
87
|
- lib/crosstie/templates/change_timezone.rb
|
@@ -91,12 +93,14 @@ files:
|
|
91
93
|
- lib/crosstie/templates/figaro.rb
|
92
94
|
- lib/crosstie/templates/git_init.rb
|
93
95
|
- lib/crosstie/templates/guard.rb
|
96
|
+
- lib/crosstie/templates/helper.rb
|
94
97
|
- lib/crosstie/templates/install_gems.rb
|
95
98
|
- lib/crosstie/templates/ldap.rb
|
96
99
|
- lib/crosstie/templates/rails_layout.rb
|
97
100
|
- lib/crosstie/templates/resources.rb
|
98
101
|
- lib/crosstie/templates/rolify.rb
|
99
102
|
- lib/crosstie/templates/rspec.rb
|
103
|
+
- lib/crosstie/templates/run_seeds.rb
|
100
104
|
- lib/crosstie/templates/run_test.rb
|
101
105
|
- lib/crosstie/templates/seeds.rb
|
102
106
|
- lib/crosstie/templates/serve_static.rb
|
@@ -105,7 +109,9 @@ files:
|
|
105
109
|
- lib/crosstie/templates/static_pages.rb
|
106
110
|
- lib/crosstie/templates/stop_robots.rb
|
107
111
|
- lib/crosstie/templates/user.rb
|
112
|
+
- lib/crosstie/templates/web_console.rb
|
108
113
|
- lib/crosstie/version.rb
|
114
|
+
- run.sh
|
109
115
|
homepage: https://github.com/dongqs/crosstie
|
110
116
|
licenses:
|
111
117
|
- MIT
|