├── .amber.yml
├── .gitignore
├── .travis.yml
├── Dockerfile
├── LICENSE
├── README.md
├── config
├── application.cr
├── database.cr
├── environments
│ ├── .production.enc
│ ├── development.yml
│ └── test.yml
├── i18n.cr
├── initializers
│ └── client_reload.cr
├── routes.cr
└── webpack
│ ├── common.js
│ ├── development.js
│ ├── entry.js
│ └── production.js
├── docker-compose.yml
├── package-lock.json
├── package.json
├── public
├── crossdomain.xml
├── dist
│ ├── images
│ │ └── logo.svg
│ ├── main.bundle.css
│ └── main.bundle.js
├── favicon.ico
├── favicon.png
├── js
│ └── client_reload.js
└── robots.txt
├── shard.lock
├── shard.yml
├── spec
└── spec_helper.cr
└── src
├── assets
├── fonts
│ └── .gitkeep
├── images
│ ├── .gitkeep
│ └── logo.svg
├── javascripts
│ └── main.js
└── stylesheets
│ └── main.scss
├── controllers
├── application_controller.cr
└── home_controller.cr
├── ruby2crystal.cr
└── views
├── home
└── index.slang
└── layouts
├── _nav.slang
└── application.slang
/.amber.yml:
--------------------------------------------------------------------------------
1 | type: app
2 | database: sqlite
3 | language: slang
4 | model: granite
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /doc/
2 | /lib/
3 | /.crystal/
4 | /.shards/
5 | /.vscode/
6 | /tmp/
7 | .env
8 | .amber_secret_key
9 | production.yml
10 | .DS_Store
11 | /bin/
12 | /node_modules/
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: crystal
2 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM crystallang/crystal:0.23.1
2 |
3 | # Install Dependencies
4 | ARG DEBIAN_FRONTEND=noninteractive
5 | RUN apt-get update -qq && apt-get install -y --no-install-recommends libpq-dev libsqlite3-dev libmysqlclient-dev libreadline-dev git curl vim netcat
6 |
7 | # Install Node
8 | RUN curl -sL https://deb.nodesource.com/setup_6.x | bash -
9 | RUN apt-get install -y nodejs
10 |
11 |
12 | # Install Amber
13 | ENV PATH /app/bin:$PATH
14 | WORKDIR /app
15 | COPY shard.yml shard.lock /app/
16 | RUN shards build amber
17 |
18 | # Add Project
19 | ADD . /app
20 |
21 | # Set config
22 | CMD amber watch
23 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Faustino Aguilar
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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ruby2crystal
2 |
3 | > Please, notice this app is just using a bunch of scripts to find "keywords" in ruby code, I heavily think there are better ways to do this :P
4 |
5 | A proof of concept tool to help porting gems to shards.
6 |
7 | Highly inspired by [Crystal for Rubyist](https://github.com/crystal-lang/crystal/wiki/Crystal-for-Rubyists) wiki.
8 |
9 | Also exists [Crystal for Rubyist](http://www.crystalforrubyists.com/) book :wink:
10 |
11 | 
12 |
13 | ## Installation
14 |
15 | ```shellsession
16 | shards build ruby2crystal
17 | ./bin/ruby2crystal
18 | ```
19 |
20 | ## Contributing
21 |
22 | 1. Fork it ( https://github.com/faustinoaq/ruby2crystal/fork )
23 | 2. Create your feature branch (git checkout -b my-new-feature)
24 | 3. Commit your changes (git commit -am 'Add some feature')
25 | 4. Push to the branch (git push origin my-new-feature)
26 | 5. Create a new Pull Request
27 |
28 | ## Contributors
29 |
30 | - [faustinoaq](https://github.com/faustinoaq) Faustino Aguilar - creator, maintainer
31 |
--------------------------------------------------------------------------------
/config/application.cr:
--------------------------------------------------------------------------------
1 | require "./database.cr"
2 | require "./i18n.cr"
3 | require "./initializers/**"
4 |
5 | require "amber"
6 | # require "../src/models/**"
7 |
8 | require "../src/controllers/application_controller"
9 | require "../src/controllers/**"
10 |
11 | # About Application.cr File
12 | #
13 | # This is Amber application main entry point. This file is responsible for loading
14 | # initializers, classes, and all application related code in order to have
15 | # Amber::Server boot up.
16 | #
17 | # > We recommend to not modify the order of the require since the order will
18 | # affect the behavior of the application.
19 | #
20 | # With `Amber::Server.configure` block you can redefine the Server configuration
21 | # settings and use ENVIRONMENT variables and/or values evaluated at runtime.
22 | #
23 | # > Important! Yaml configurations are first class citizen and are loaded first before
24 | # this file, we recommend to use yaml configurations before changing any settings here.
25 | # Any uncommented setting here will override the YAML with the value set here.
26 |
27 | Amber::Server.configure do |settings|
28 | # Use your environment variables settings here.
29 | #
30 | # Name: A name that identifies this application. This is not internally
31 | # used by the framework.
32 | #
33 | # settings.name = "Example web application."
34 | #
35 | #
36 | # Colorize Logging: specifies whether or not to use ANSI color codes
37 | # when logging information, display the time and/or to display the severity level.
38 | # Defaults to true.
39 | #
40 | # Log Level defines the verbosity of the Amber logger. This option defaults to
41 | # debug for all environments. The available log levels are: debug, info, warn,
42 | # error, fatal, and unknown.
43 | #
44 | # settings.logging.colorize = true
45 | # settings.logging.severity = "debug"
46 | # settings.logging.filter = %w(password confirm_password)
47 | # settings.logging.skip = %w()
48 | # settings.logging.context = %w(request headers cookies session params)
49 | #
50 | #
51 | # Secret Key Base: is used for specifying a key which allows sessions
52 | # for the application to be verified against a known secure key to
53 | # prevent tampering. Applications get Amber.secret_key
54 | # initialized to a random key present in `ENV["AMBER_SECRET_KEY"]` or
55 | # `.amber_secret_key` in this order.
56 | #
57 | # settings.secret_key_base= Z0yS9n1jH8DhVXw_231pzpsZyGbAWjdndzZAd7PhlmE
58 | #
59 | #
60 | # Host: is the application server host address or ip address. Useful for when
61 | # deploying Amber to a PAAS and likely the assigned server IP is either
62 | # known or unknown. Defaults to an environment variable HOST
63 | #
64 | # settings.host = ENV["HOST"] if ENV["HOST"]?
65 | #
66 | #
67 | # Port Reuse: Amber supports clustering mode which allows to spin
68 | # multiple app instances per core. This setting allows to bind the different
69 | # instances to the same port. Default this setting to true if the number or process
70 | # is greater than 1.
71 | #
72 | # > Read more about Linux PORT REUSE https://lwn.net/Articles/542629/
73 | #
74 | # settings.port_reuse = true
75 | #
76 | #
77 | # Process Count: This will enable Amber to be used in cluster mode,
78 | # spinning an instance for each number of process specified here.
79 | # Rule of thumb, always leave at least 1 core available for system processes/resources.
80 | #
81 | # settings.process_count = ENV["PROCESS_COUNT"].to_i if ENV["PROCESS_COUNT"]?
82 | #
83 | #
84 | # PORT: This is the port that you're application will run on. Examples would be (80, 443, 3000, 8080)
85 | #
86 | settings.port = ENV["PORT"].to_i if ENV["PORT"]?
87 | #
88 | #
89 | # Redis URL: Redis is an in memory key value storage. Amber utilizes redis as
90 | # a storing option for session information.
91 | #
92 | # settings.redis_url = ENV["REDIS_URL"] if ENV["REDIS_URL"]?
93 | #
94 | #
95 | # Database URL: This is the database connection string or data file url.
96 | # The connection string contains the information to establish a connection to the
97 | # database or the data file. Defaults to the database provider you chose at
98 | # at app generation.
99 | #
100 | # settings.database_url = ENV["DATABASE_URL"] if ENV["DATABASE_URL"]?
101 | #
102 | #
103 | # SSL Key File: The private key is a text file used initially to generate a
104 | # Certificate Signing Request (CSR), and later to secure and verify connections
105 | # using the certificate created per that request. The private key is used to create
106 | # a digital signature as you might imagine from the name, the private key should be
107 | # ``closely guarded.
108 | #
109 | # settings.ssl_key_file = ENV["SSL_KEY_FILE"] if ENV["SSL_KEY_FILE"]?
110 | #
111 | #
112 | # SSL Cert File: This represents the signed certificate file. SSL Certificates are
113 | # small data files that digitally bind a cryptographic key to an organization's
114 | # details. When installed on a web server, it activates the padlock and the https
115 | # protocol and allows secure connections from a web server to a browser.
116 | #
117 | # settings.ssl_cert_file = ENV["SSL_CERT_FILE"] if ENV["SSL_CERT_FILE"]?
118 | #
119 | #
120 | # Session: A Hash that specifies the session storage mechanism, expiration and key to be used
121 | # for the application. The `key` specifies the name of the cookie to be used defaults to
122 | # "amber.session". The store can be `encrypted_cookie`, `signed_cookie` or `redis`. Expires
123 | # when set to 0 means this is indefinitely and is expressed in seconds.
124 | #
125 | # settings.session = { "key" => "amber.session", "store" => "signed_cookie", "expires" => 0 }
126 | #
127 | #
128 | # Logger: is the logger that Amber and other capable shards in the project will use
129 | # instead of writing directly to STDOUT. Supply a custom logger to write to syslog, etc.
130 | #
131 | # settings.logger = Amber::Environment::Logger.new(File.open("example.log", "w"))
132 | #
133 | #
134 | end
135 |
--------------------------------------------------------------------------------
/config/database.cr:
--------------------------------------------------------------------------------
1 | require "granite/adapter/sqlite"
2 |
3 | Granite::Adapters << Granite::Adapter::Sqlite.new({name: "sqlite", url: Amber.settings.database_url})
4 | Granite.settings.logger = Amber.settings.logger.dup
5 | Granite.settings.logger.not_nil!.progname = "Granite"
6 |
7 |
--------------------------------------------------------------------------------
/config/environments/.production.enc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/faustinoaq/ruby2crystal/d7b910f2269ccef1418451ca3810b254e26fbb9e/config/environments/.production.enc
--------------------------------------------------------------------------------
/config/environments/development.yml:
--------------------------------------------------------------------------------
1 | secret_key_base: TKHCsIAm_rXJnKUpJt6iCJeEaQDA2WA5aadYE15t_L4
2 | port: 3000
3 | name: example
4 |
5 | logging:
6 | severity: debug
7 | colorize: true
8 | filter:
9 | - password
10 | - confirm_password
11 | context:
12 | - request
13 | - session
14 | - headers
15 | - cookies
16 | - params
17 |
18 | host: 0.0.0.0
19 | port_reuse: true
20 | process_count: 1
21 | # ssl_key_file:
22 | # ssl_cert_file:
23 | redis_url: "redis://localhost:6379"
24 | database_url: sqlite3:./db/example_development.db
25 | auto_reload: true
26 |
27 | session:
28 | key: amber.session
29 | store: signed_cookie
30 | expires: 0
31 |
32 | smtp:
33 | enabled: false
34 |
35 | secrets:
36 | description: Store your development secrets credentials and settings here.
37 |
--------------------------------------------------------------------------------
/config/environments/test.yml:
--------------------------------------------------------------------------------
1 | secret_key_base: GAnWH61fiYeX13d9x8ek0U9tXP5Yjmw37FZT7EzWnBQ
2 | port: 3000
3 | name: example
4 |
5 | logging:
6 | severity: debug
7 | colorize: true
8 | filter:
9 | - password
10 | - confirm_password
11 | context:
12 | - request
13 | - session
14 | - headers
15 | - cookies
16 | - params
17 |
18 | host: 0.0.0.0
19 | port_reuse: false
20 | process_count: 1
21 | # ssl_key_file:
22 | # ssl_cert_file:
23 | redis_url: "redis://localhost:6379"
24 | database_url: sqlite3:./db/example_test.db
25 | auto_reload: false
26 |
27 | session:
28 | key: amber.session
29 | store: signed_cookie
30 | expires: 0
31 |
32 | smtp:
33 | enabled: false
34 |
35 | secrets:
36 | description: Store your development secrets credentials and settings here.
37 |
--------------------------------------------------------------------------------
/config/i18n.cr:
--------------------------------------------------------------------------------
1 | require "citrine-i18n"
2 |
3 | Citrine::I18n.configure do |settings|
4 | # Backend storage (as supported by i18n.cr)
5 | # settings.backend = I18n::Backend::Yaml.new
6 |
7 | # Default locale (defaults to "en" and "./src/locales/**/en.yml").
8 | # For a new default locale to be accepted, it must be found by the
9 | # backend storage and reported in "settings.available_locales".
10 | # settings.default_locale = "en"
11 |
12 | # Separator between sublevels of data (defaults to '.')
13 | # e.g. I18n.translate("some/thing") instead of "some.thing"
14 | # settings.default_separator = '.'
15 |
16 | # Returns the current exception handler. Defaults to an instance of
17 | # I18n::ExceptionHandler.
18 | # settings.exception_handler = ExceptionHandler.new
19 |
20 | # The path from where the translations should be loaded
21 | settings.load_path += ["./src/locales"]
22 | end
23 |
24 | I18n.init
25 |
--------------------------------------------------------------------------------
/config/initializers/client_reload.cr:
--------------------------------------------------------------------------------
1 | Amber::Support::ClientReload.new if Amber.settings.auto_reload?
2 |
--------------------------------------------------------------------------------
/config/routes.cr:
--------------------------------------------------------------------------------
1 | Amber::Server.configure do
2 | pipeline :web do
3 | # Plug is the method to use connect a pipe (middleware)
4 | # A plug accepts an instance of HTTP::Handler
5 | if Amber.env != "production"
6 | plug Amber::Pipe::PoweredByAmber.new
7 | end
8 | # plug Amber::Pipe::ClientIp.new(["X-Forwarded-For"])
9 | plug Citrine::I18n::Handler.new
10 | plug Amber::Pipe::Error.new
11 | plug Amber::Pipe::Logger.new
12 | plug Amber::Pipe::Session.new
13 | plug Amber::Pipe::Flash.new
14 | plug Amber::Pipe::CSRF.new
15 | end
16 |
17 | pipeline :api do
18 | plug Amber::Pipe::PoweredByAmber.new
19 | plug Amber::Pipe::Error.new
20 | plug Amber::Pipe::Logger.new
21 | plug Amber::Pipe::Session.new
22 | plug Amber::Pipe::CORS.new
23 | end
24 |
25 | # All static content will run these transformations
26 | pipeline :static do
27 | plug Amber::Pipe::PoweredByAmber.new
28 | plug Amber::Pipe::Error.new
29 | plug Amber::Pipe::Static.new("./public")
30 | end
31 |
32 | routes :web do
33 | get "/", HomeController, :index
34 | post "/", HomeController, :search
35 | end
36 |
37 | routes :api do
38 | end
39 |
40 | routes :static do
41 | # Each route is defined as follow
42 | # verb resource : String, controller : Symbol, action : Symbol
43 | get "/*", Amber::Controller::Static, :index
44 | end
45 | end
46 |
--------------------------------------------------------------------------------
/config/webpack/common.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack');
2 | const path = require('path');
3 | const MiniCssExtractPlugin = require('mini-css-extract-plugin');
4 |
5 | let config = {
6 | entry: {
7 | main: path.resolve(__dirname, 'entry.js')
8 | },
9 | output: {
10 | filename: '[name].bundle.js',
11 | path: path.resolve(__dirname, '../../public/dist'),
12 | publicPath: '/dist'
13 | },
14 | resolve: {
15 | alias: {
16 | amber: path.resolve(__dirname, '../../lib/amber/assets/js/amber.js')
17 | }
18 | },
19 | module: {
20 | rules: [
21 | {
22 | test: /\.(sass|scss|css)$/,
23 | exclude: /node_modules/,
24 | use: [
25 | MiniCssExtractPlugin.loader,
26 | 'css-loader',
27 | 'sass-loader'
28 | ]
29 | },
30 | {
31 | test: /\.(png|svg|jpg|gif)$/,
32 | exclude: /node_modules/,
33 | use: [
34 | 'file-loader?name=/images/[name].[ext]'
35 | ]
36 | },
37 | {
38 | test: /\.(woff|woff2|eot|ttf|otf)$/,
39 | exclude: /node_modules/,
40 | use: [
41 | 'file-loader?name=/[name].[ext]'
42 | ]
43 | },
44 | {
45 | test: /\.js$/,
46 | exclude: /node_modules/,
47 | use: {
48 | loader: 'babel-loader',
49 | options: {
50 | presets: ['@babel/preset-env']
51 | }
52 | }
53 | }
54 | ]
55 | },
56 | plugins: [
57 | new MiniCssExtractPlugin({
58 | filename: '[name].bundle.css'
59 | })
60 | ],
61 | // For more info about webpack logs see: https://webpack.js.org/configuration/stats/
62 | stats: 'errors-only'
63 | };
64 |
65 | module.exports = config;
66 |
--------------------------------------------------------------------------------
/config/webpack/development.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack');
2 | const merge = require('webpack-merge');
3 | const common = require('./common.js');
4 |
5 | module.exports = merge(common, {
6 | mode: 'development',
7 | devtool: 'inline-source-map'
8 | });
9 |
--------------------------------------------------------------------------------
/config/webpack/entry.js:
--------------------------------------------------------------------------------
1 | // This is the Webpack entrypoint and acts as a shim to load both the JavaScript
2 | // and CSS source files into Webpack. It is mainly here to avoid requiring
3 | // stylesheets from the javascripts asset directory and keep those concerns
4 | // separate from each other within the src directory.
5 | //
6 | // This will be removed from Webpack 5 onward.
7 | // See: https://github.com/webpack-contrib/mini-css-extract-plugin/issues/151
8 |
9 | import '../../src/assets/javascripts/main.js';
10 | import '../../src/assets/stylesheets/main.scss';
11 |
--------------------------------------------------------------------------------
/config/webpack/production.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack');
2 | const merge = require('webpack-merge');
3 | const common = require('./common.js');
4 |
5 | module.exports = merge(common, {
6 | mode: 'production',
7 | optimization: {
8 | minimize: true
9 | }
10 | });
11 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '2'
2 |
3 | services:
4 | web:
5 | build: .
6 | image: ruby2crystal
7 | command: bash -c 'npm install && npm run watch'
8 | working_dir: /app/local
9 | volumes:
10 | - '.:/app/local'
11 |
12 | app:
13 | build: .
14 | image: ruby2crystal
15 | command: 'amber watch'
16 | working_dir: /app/local
17 | environment:
18 | DATABASE_URL: sqlite3:./db/ruby2crystal_development.db
19 | SMTP_URL: mail:1025
20 | ports:
21 | - '3000:3000'
22 | links:
23 | - db
24 | - mail
25 | volumes:
26 | - '.:/app/local'
27 |
28 | migrate:
29 | build: .
30 | image: ruby2crystal
31 | command: bash -c 'amber db migrate seed'
32 | working_dir: /app/local
33 | environment:
34 | DATABASE_URL: sqlite3:./db/ruby2crystal_development.db
35 | volumes:
36 | - '.:/app/local'
37 | links:
38 | - db
39 |
40 | mail:
41 | image: drujensen/mailcatcher:latest
42 | ports:
43 | - '1080:1080'
44 |
45 |
46 | volumes:
47 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ruby2crystal",
3 | "version": "0.1.0",
4 | "description": "Ruby2crystal with Amber",
5 | "private": true,
6 | "author": "Amber",
7 | "license": "UNLICENSED",
8 | "scripts": {
9 | "build": "webpack --config config/webpack/development.js",
10 | "watch": "webpack -w --config config/webpack/development.js",
11 | "release": "webpack -p --config config/webpack/production.js",
12 | "test": "echo \"No test specified\" && exit 1"
13 | },
14 | "devDependencies": {
15 | "@babel/core": "^7.2.2",
16 | "@babel/preset-env": "^7.2.3",
17 | "babel-loader": "^8.0.5",
18 | "css-loader": "^2.1.0",
19 | "file-loader": "^3.0.1",
20 | "mini-css-extract-plugin": "^0.5.0",
21 | "node-sass": "^4.9.0",
22 | "sass-loader": "^7.0.1",
23 | "webpack": "^4.28.1",
24 | "webpack-cli": "^3.2.1",
25 | "webpack-merge": "^4.1.2"
26 | },
27 | "dependencies": {
28 | "bootstrap": "^4.2.1",
29 | "jquery": "^3.3.1",
30 | "popper.js": "^1.14.6"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/public/crossdomain.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
15 |
16 |
--------------------------------------------------------------------------------
/public/dist/images/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/faustinoaq/ruby2crystal/d7b910f2269ccef1418451ca3810b254e26fbb9e/public/favicon.ico
--------------------------------------------------------------------------------
/public/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/faustinoaq/ruby2crystal/d7b910f2269ccef1418451ca3810b254e26fbb9e/public/favicon.png
--------------------------------------------------------------------------------
/public/js/client_reload.js:
--------------------------------------------------------------------------------
1 | if ('WebSocket' in window) {
2 | (function () {
3 | /**
4 | * Allows to reload the browser when the server connection is lost
5 | */
6 | function tryReload() {
7 | var request = new XMLHttpRequest();
8 | request.open('GET', window.location.href, true);
9 | request.onreadystatechange = function () {
10 | if (request.readyState == 4) {
11 | if (request.status == 0) {
12 | setTimeout(function () {
13 | tryReload();
14 | }, 1000)
15 | } else {
16 | window.location.reload();
17 | }
18 | }
19 | };
20 | request.send();
21 | }
22 |
23 | /**
24 | * Listen server file reload
25 | */
26 | function refreshCSS() {
27 | var sheets = [].slice.call(document.getElementsByTagName('link'));
28 | var head = document.getElementsByTagName('head')[0];
29 | for (var i = 0; i < sheets.length; ++i) {
30 | var elem = sheets[i];
31 | var rel = elem.rel;
32 | if (elem.href && typeof rel != 'string' || rel.length == 0 || rel.toLowerCase() == 'stylesheet') {
33 | head.removeChild(elem);
34 | var url = elem.href.replace(/(&|\\?)_cacheOverride=\\d+/, '');
35 | elem.href = url + (url.indexOf('?') >= 0 ? '&' : '?') + '_cacheOverride=' + (new Date().valueOf());
36 | head.appendChild(elem);
37 | }
38 | }
39 | }
40 |
41 | var protocol = window.location.protocol === 'http:' ? 'ws://' : 'wss://';
42 | var address = protocol + window.location.host + '/client-reload';
43 | var socket = new WebSocket(address);
44 | socket.onmessage = function (msg) {
45 | if (msg.data == 'reload') {
46 | tryReload();
47 | } else if (msg.data == 'refreshcss') {
48 | refreshCSS();
49 | }
50 | };
51 | socket.onclose = function () {
52 | tryReload();
53 | }
54 | })();
55 | }
56 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # http://www.robotstxt.org
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/shard.lock:
--------------------------------------------------------------------------------
1 | version: 1.0
2 | shards:
3 | amber:
4 | github: amberframework/amber
5 | version: 0.11.3
6 |
7 | amber_router:
8 | github: amberframework/amber-router
9 | version: 0.2.1
10 |
11 | callback:
12 | github: mosop/callback
13 | version: 0.6.3
14 |
15 | citrine-i18n:
16 | github: amberframework/citrine-i18n
17 | version: 0.3.2
18 |
19 | cli:
20 | github: mosop/cli
21 | version: 0.7.0
22 |
23 | compiled_license:
24 | github: elorest/compiled_license
25 | version: 0.1.3
26 |
27 | db:
28 | github: crystal-lang/crystal-db
29 | version: 0.5.1
30 |
31 | email:
32 | github: arcage/crystal-email
33 | version: 0.3.3
34 |
35 | exception_page:
36 | github: crystal-loot/exception_page
37 | version: 0.1.2
38 |
39 | garnet_spec:
40 | github: amberframework/garnet-spec
41 | version: 0.2.1
42 |
43 | granite:
44 | github: amberframework/granite
45 | version: 0.15.2
46 |
47 | i18n:
48 | github: TechMagister/i18n.cr
49 | version: 0.2.0
50 |
51 | inflector:
52 | github: phoffer/inflector.cr
53 | version: 0.1.8
54 |
55 | jasper_helpers:
56 | github: amberframework/jasper-helpers
57 | version: 0.2.4
58 |
59 | kilt:
60 | github: jeromegn/kilt
61 | version: 0.4.0
62 |
63 | liquid:
64 | github: TechMagister/liquid.cr
65 | version: 0.3.0
66 |
67 | micrate:
68 | github: amberframework/micrate
69 | version: 0.3.3
70 |
71 | mysql:
72 | github: crystal-lang/crystal-mysql
73 | version: 0.5.1
74 |
75 | optarg:
76 | github: mosop/optarg
77 | version: 0.5.8
78 |
79 | pg:
80 | github: will/crystal-pg
81 | version: 0.15.0
82 |
83 | pool:
84 | github: ysbaddaden/pool
85 | version: 0.2.3
86 |
87 | quartz_mailer:
88 | github: amberframework/quartz-mailer
89 | version: 0.5.3
90 |
91 | redis:
92 | github: stefanwille/crystal-redis
93 | version: 2.0.0
94 |
95 | selenium:
96 | github: ysbaddaden/selenium-webdriver-crystal
97 | version: 0.4.0
98 |
99 | shell-table:
100 | github: luckyframework/shell-table.cr
101 | commit: 078a04ea58ead5203bb435a3b5fff448ddabaeea
102 |
103 | slang:
104 | github: jeromegn/slang
105 | version: 1.7.1
106 |
107 | sqlite3:
108 | github: crystal-lang/crystal-sqlite3
109 | version: 0.10.0
110 |
111 | string_inflection:
112 | github: mosop/string_inflection
113 | version: 0.2.1
114 |
115 | teeplate:
116 | github: mosop/teeplate
117 | version: 0.7.0
118 |
119 |
--------------------------------------------------------------------------------
/shard.yml:
--------------------------------------------------------------------------------
1 | name: ruby2crystal
2 | version: 0.1.0
3 |
4 | authors:
5 | - Amber
6 |
7 | crystal: 0.23.1
8 |
9 | license: UNLICENSED
10 |
11 | targets:
12 | ruby2crystal:
13 | main: src/ruby2crystal.cr
14 |
15 | amber:
16 | main: lib/amber/src/amber/cli.cr
17 |
18 | dependencies:
19 | amber:
20 | github: amberframework/amber
21 | version: 0.11.3
22 | #branch: master
23 |
24 | granite:
25 | github: amberframework/granite
26 | version: ~> 0.15.0
27 |
28 | quartz_mailer:
29 | github: amberframework/quartz-mailer
30 | version: ~> 0.5.1
31 |
32 | jasper_helpers:
33 | github: amberframework/jasper-helpers
34 | version: ~> 0.2.1
35 |
36 | sqlite3:
37 | github: crystal-lang/crystal-sqlite3
38 | version: ~> 0.10.0
39 |
40 | citrine-i18n:
41 | github: amberframework/citrine-i18n
42 | version: 0.3.2
43 |
44 | development_dependencies:
45 | garnet_spec:
46 | github: amberframework/garnet-spec
47 | version: ~> 0.2.1
48 |
--------------------------------------------------------------------------------
/spec/spec_helper.cr:
--------------------------------------------------------------------------------
1 | require "spec"
2 | require "garnet_spec"
3 | require "../config/*"
4 |
5 | module Spec
6 | DRIVER = :chrome
7 | PATH = "/usr/local/bin/chromedriver"
8 |
9 | # Not all server implementations will support every WebDriver feature.
10 | # Therefore, the client and server should use JSON objects with the properties
11 | # listed below when describing which features a session supports.
12 | capabilities = {
13 | browserName: "chrome",
14 | version: "",
15 | platform: "ANY",
16 | javascriptEnabled: true,
17 | takesScreenshot: true,
18 | handlesAlerts: true,
19 | databaseEnabled: true,
20 | locationContextEnabled: true,
21 | applicationCacheEnabled: true,
22 | browserConnectionEnabled: true,
23 | cssSelectorsEnabled: true,
24 | webStorageEnabled: true,
25 | rotatable: true,
26 | acceptSslCerts: true,
27 | nativeEvents: true,
28 | args: "--headless",
29 | }
30 | end
31 |
--------------------------------------------------------------------------------
/src/assets/fonts/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/faustinoaq/ruby2crystal/d7b910f2269ccef1418451ca3810b254e26fbb9e/src/assets/fonts/.gitkeep
--------------------------------------------------------------------------------
/src/assets/images/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/faustinoaq/ruby2crystal/d7b910f2269ccef1418451ca3810b254e26fbb9e/src/assets/images/.gitkeep
--------------------------------------------------------------------------------
/src/assets/images/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/javascripts/main.js:
--------------------------------------------------------------------------------
1 | import 'bootstrap';
2 | import Amber from 'amber';
3 |
--------------------------------------------------------------------------------
/src/assets/stylesheets/main.scss:
--------------------------------------------------------------------------------
1 | $primary: #f44b4b;
2 |
3 | @import '~bootstrap/scss/bootstrap';
4 |
5 | .main {
6 | padding-top: 20px;
7 | }
8 |
9 | .alert {
10 | margin-top: 1rem;
11 | }
--------------------------------------------------------------------------------
/src/controllers/application_controller.cr:
--------------------------------------------------------------------------------
1 | require "jasper_helpers"
2 |
3 | class ApplicationController < Amber::Controller::Base
4 | include JasperHelpers
5 | LAYOUT = "application.slang"
6 | end
7 |
--------------------------------------------------------------------------------
/src/controllers/home_controller.cr:
--------------------------------------------------------------------------------
1 | class HomeController < ApplicationController
2 | RUBY_VERSION = "2.6.0"
3 |
4 | property found = [] of String
5 | property current_gem : String?
6 |
7 | def index
8 | render("index.slang")
9 | end
10 |
11 | def search
12 | found.clear
13 | if gem = params["gem"]?
14 | current_gem = gem
15 | msg = `gem install #{gem}`
16 | unless Dir.glob(File.expand_path("~/.gem/ruby/#{RUBY_VERSION}/gems/*")).select(&.=~ /\/#{gem}-*/).empty?
17 | found << "send found: #{`grep -rn "\.\s*send" ~/.gem/ruby/*/gems/#{gem}-*/lib`.split('\n').size - 1}\n"
18 | found << "class << found: #{`grep -rn "class <<" ~/.gem/ruby/*/gems/#{gem}-*/lib`.split('\n').size - 1}\n"
19 | # found << "$` found: #{`grep -rn "$\`" ~/.gem/ruby/*/gems/#{gem}-*/lib`.split('\n').size - 1}\n"
20 | found << "Enumerable#detect found: #{`grep -rn "\.\s*detect" ~/.gem/ruby/*/gems/#{gem}-*/lib`.split('\n').size - 1}\n"
21 | found << "Enumerable#collect found: #{`grep -rn "\.\s*collect" ~/.gem/ruby/*/gems/#{gem}-*/lib`.split('\n').size - 1}\n"
22 | found << "Enumerable#respond_to? found: #{`grep -rn "\.\s*respond_to?" ~/.gem/ruby/*/gems/#{gem}-*/lib`.split('\n').size - 1}\n"
23 | found << "length found: #{`grep -rn "\.\s*length" ~/.gem/ruby/*/gems/#{gem}-*/lib`.split('\n').size - 1}\n"
24 | found << "and found: #{`grep -rn "\s+and\s+" ~/.gem/ruby/*/gems/#{gem}-*/lib`.split('\n').size - 1}\n"
25 | found << "or found: #{`grep -rn "\s+or\s+" ~/.gem/ruby/*/gems/#{gem}-*/lib`.split('\n').size - 1}\n"
26 | # found << "posibble autosplat found: #{`grep -rn "\[\s*\[" ~/.gem/ruby/*/gems/#{gem}-*/lib`.split('\n').size - 1}\n"
27 | found << "each found (returns nil in crystal): #{`grep -rn "\.\s*each" ~/.gem/ruby/*/gems/#{gem}-*/lib`.split('\n').size - 1}\n"
28 | found << "simple quote found (use double quotes in crystal): #{`grep -rn "\'[\s\S]+\'" ~/.gem/ruby/*/gems/#{gem}-*/lib`.split('\n').size - 1}\n"
29 | found << "for loop found (use times or each in crystal): #{`grep -rn "\s*for\s+" ~/.gem/ruby/*/gems/#{gem}-*/lib`.split('\n').size - 1}\n"
30 | found << "attr_accessor found (use property keyword in crystal): #{`grep -rn "attr_accessor" ~/.gem/ruby/*/gems/#{gem}-*/lib`.split('\n').size - 1}\n"
31 | found << "attr_getter found (use getter keyword in crystal): #{`grep -rn "attr_getter" ~/.gem/ruby/*/gems/#{gem}-*/lib`.split('\n').size - 1}\n"
32 | found << "attr_setter found (use setter keyword in crystal): #{`grep -rn "attr_setter" ~/.gem/ruby/*/gems/#{gem}-*/lib`.split('\n').size - 1}\n"
33 | else
34 | flash["warning"] = "gem #{gem} not found"
35 | end
36 | found.select! do |item|
37 | !item.ends_with?(": 0\n")
38 | end
39 | render("index.slang")
40 | else
41 | raise Amber::Exceptions::RouteNotFound.new(request)
42 | end
43 | end
44 | end
45 |
--------------------------------------------------------------------------------
/src/ruby2crystal.cr:
--------------------------------------------------------------------------------
1 | require "../config/*"
2 |
3 | Amber::Server.start
4 |
--------------------------------------------------------------------------------
/src/views/home/index.slang:
--------------------------------------------------------------------------------
1 | div.col-sm-6
2 | h2 Welcome to Ruby2Crystal!
3 | p Try a gem name to check crystal portability score.
4 | p Inspired by
5 | a href="https://github.com/crystal-lang/crystal/wiki/Crystal-for-Rubyists" Crystal for Rubyist
6 | | wiki
7 | == form(action: "/", method: "post") do
8 | == csrf_tag
9 | div.form-group
10 | == text_field(name: "gem", value: "", placeholder: current_gem || "ruby gem name", class: "form-control")
11 | br
12 | == submit("Submit", class: "btn btn-primary btn-xs")
13 | == link_to("Reload", "/", class: "btn btn-default btn-xs")
14 | - unless found.empty?
15 | h2 Found compatibilities issues:
16 | ul
17 | - found.each do |f|
18 | li
19 | = f
20 |
--------------------------------------------------------------------------------
/src/views/layouts/_nav.slang:
--------------------------------------------------------------------------------
1 | - active = context.request.path == "/" ? "active" : ""
2 | li.nav-item class=active
3 | a.nav-link href="/" Home
4 |
--------------------------------------------------------------------------------
/src/views/layouts/application.slang:
--------------------------------------------------------------------------------
1 | doctype html
2 | html
3 | head
4 | title uby2crystal using Amber
5 | meta charset="utf-8"
6 | meta http-equiv="X-UA-Compatible" content="IE=edge"
7 | meta name="viewport" content="width=device-width, initial-scale=1"
8 | link rel="stylesheet" href="/dist/main.bundle.css"
9 | link rel="apple-touch-icon" href="/favicon.png"
10 | link rel="icon" href="/favicon.png"
11 | link rel="icon" type="image/x-icon" href="/favicon.ico"
12 |
13 | body
14 | nav.navbar.navbar-expand.navbar-dark.bg-primary
15 | .container
16 | a.navbar-brand href="/"
17 | img src="/dist/images/logo.svg" height="30" alt="Amber logo"
18 | ul.navbar-nav.mr-auto
19 | == render(partial: "layouts/_nav.slang")
20 |
21 | .container
22 | - flash.each do |key, value|
23 | div class="alert alert-#{key}" role="alert"
24 | = flash[key]
25 |
26 | .main== content
27 |
28 | script src="/dist/main.bundle.js"
29 |
30 | - if Amber.settings.auto_reload?
31 | script src="/js/client_reload.js"
32 |
--------------------------------------------------------------------------------