rubocop-crystal 0.0.1 → 0.0.2
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/.github/workflows/test.yml +26 -0
- data/CHANGELOG.md +10 -0
- data/README.md +26 -15
- data/config/default.yml +18 -1
- data/lib/rubocop/cop/crystal/interpolation_in_single_quotes.rb +35 -0
- data/lib/rubocop/cop/crystal/require_relative.rb +38 -0
- data/lib/rubocop/cop/crystal_cops.rb +2 -0
- data/rubocop-crystal.gemspec +2 -2
- data/test/harness.rb +41 -0
- data/test/string.rb +20 -0
- metadata +9 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3beb9db336ee0d664fdd093775a9c14dc9512c8ec84be250ec177a6763b4924d
|
4
|
+
data.tar.gz: 015acc39018447fef5d62304bf91dddab3b66faa795149f00b3e447de6db5990
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2077733fe1bc6189b71854a249601f8294366a2d86cd013822bb6ec9fd1371e9229ad6622dc169426ae35c75b1f65e26f5308538a749e2b02fb7239ac99a087e
|
7
|
+
data.tar.gz: ea546caea1eeb127c946df8c97ec77ba7e5572db33c63402bba1ad4ffeeaca05d19d402d6c6a96aa37d4641f2aeda11d95a8f26a2e6b1c18a473961b8468d221
|
@@ -0,0 +1,26 @@
|
|
1
|
+
name: Test
|
2
|
+
on: [push, pull_request]
|
3
|
+
jobs:
|
4
|
+
test:
|
5
|
+
runs-on: ubuntu-latest
|
6
|
+
steps:
|
7
|
+
- name: Download source
|
8
|
+
uses: actions/checkout@v4
|
9
|
+
- name: Install Crystal
|
10
|
+
uses: crystal-lang/install-crystal@v1
|
11
|
+
- name: Install Ruby
|
12
|
+
uses: ruby/setup-ruby@v1
|
13
|
+
with:
|
14
|
+
ruby-version: '3.1.2'
|
15
|
+
- name: Run tests (Ruby)
|
16
|
+
run: ruby test/string.rb
|
17
|
+
- name: Install Rubocop
|
18
|
+
run: gem install rubocop
|
19
|
+
- name: Build and install rubocop-crystal
|
20
|
+
run: |
|
21
|
+
gem build rubocop-crystal
|
22
|
+
gem install rubocop-crystal
|
23
|
+
- name: Convert test files
|
24
|
+
run: rubocop --require rubocop-crystal --fail-level fatal -A test
|
25
|
+
- name: Run tests (Crystal)
|
26
|
+
run: crystal run test/string.cr
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
## 0.0.2 (2024-08-01)
|
2
|
+
|
3
|
+
### New features
|
4
|
+
|
5
|
+
* Enable Style/StringLiterals cop ([@zopolis4][])
|
6
|
+
* Enable Style/MethodDefParentheses cop ([@zopolis4][])
|
7
|
+
* Enable Lint/ImplicitStringConcatenation cop ([@zopolis4][])
|
8
|
+
* Add Crystal/InterpolationInSingleQuotes cop ([@zopolis4][])
|
9
|
+
* Add Crystal/RequireRelative cop ([@zopolis4][])
|
10
|
+
|
1
11
|
## 0.0.1 (2024-03-25)
|
2
12
|
|
3
13
|
### New features
|
data/README.md
CHANGED
@@ -2,21 +2,32 @@
|
|
2
2
|
|
3
3
|
The beginnings of a RuboCop extension for converting Ruby to Crystal.
|
4
4
|
|
5
|
-
##
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
5
|
+
## TODO
|
6
|
+
|
7
|
+
Many things. In particular, how are types going to work?
|
8
|
+
|
9
|
+
Getting static type information about Ruby files isn't the difficult part, the problem is conveying this information to the Crystal compiler while still maintaining valid syntax.
|
10
|
+
|
11
|
+
Inserting Crystal types into Ruby code is a no-go, because that causes `Lint/Syntax` errors in RuboCop.
|
12
|
+
|
13
|
+
Possible paths foward:
|
14
|
+
- Modify the parser to accept Crystal type declarations, or at least not break on them.
|
15
|
+
- Modify Crystal to accept type declarations from `.rbs` and/or `.rbi` files.
|
16
|
+
- Modify Crystal to accept type declarations from sorbet/rbs-inline/other annotations.
|
17
|
+
- Write [Ameba](https://github.com/crystal-ameba/ameba) [extension](https://crystal-ameba.github.io/2019/07/22/how-to-write-extension/) to convert the type annotations, as it works with Crystal syntax.
|
18
|
+
- Find a way to convey type information to Crystal using valid Ruby syntax.
|
19
|
+
|
20
|
+
Interesting repos:
|
21
|
+
- [rbs](https://github.com/ruby/rbs)
|
22
|
+
- [steep](https://github.com/soutaro/steep)
|
23
|
+
- [sorbet](https://github.com/sorbet/sorbet)
|
24
|
+
- [tapioca](https://github.com/Shopify/tapioca)
|
25
|
+
- [parlour](https://github.com/AaronC81/parlour)
|
26
|
+
- [gloss](https://github.com/johansenja/gloss)
|
27
|
+
- [claret](https://github.com/stevegeek/claret)
|
28
|
+
- [irbs](https://github.com/diaphragm/irbs)
|
29
|
+
- [rbs-inline](https://github.com/soutaro/rbs-inline)
|
30
|
+
- [syntax-tree-rbs](https://github.com/ruby-syntax-tree/syntax_tree-rbs)
|
20
31
|
|
21
32
|
## Installation
|
22
33
|
|
data/config/default.yml
CHANGED
@@ -4,4 +4,21 @@ AllCops:
|
|
4
4
|
Crystal/FileExtension:
|
5
5
|
Description: 'This cop renames files ending in `.rb` to `.cr`.'
|
6
6
|
Enabled: true
|
7
|
-
|
7
|
+
|
8
|
+
Crystal/InterpolationInSingleQuotes:
|
9
|
+
Description: "This cop uses %q in place of ' if the enclosed string would be affected by interpolation."
|
10
|
+
Enabled: true
|
11
|
+
|
12
|
+
Crystal/RequireRelative:
|
13
|
+
Description: 'This cop replaces require_relative with require while maintaining behavior.'
|
14
|
+
Enabled: true
|
15
|
+
|
16
|
+
Lint/ImplicitStringConcatenation:
|
17
|
+
Enabled: true
|
18
|
+
|
19
|
+
Style/StringLiterals:
|
20
|
+
Enabled: true
|
21
|
+
EnforcedStyle: double_quotes
|
22
|
+
|
23
|
+
Style/MethodDefParentheses:
|
24
|
+
Enabled: true
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module RuboCop
|
2
|
+
module Cop
|
3
|
+
module Crystal
|
4
|
+
# In ruby, strings deliminated with single quotes do not have interpolation applied.
|
5
|
+
# Crystal does not support this, so use %q literals to replicate this functionality.
|
6
|
+
# Only do this for strings which would be affected by interpolation, and let Style/StringLiterals handle the rest.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# # bad
|
10
|
+
# '#{foo}'
|
11
|
+
# 'cat #{con}'
|
12
|
+
#
|
13
|
+
# # good
|
14
|
+
# %q(#{foo})
|
15
|
+
# %q(cat #{con})
|
16
|
+
#
|
17
|
+
class InterpolationInSingleQuotes < Base
|
18
|
+
extend AutoCorrector
|
19
|
+
MSG = 'Crystal does not support the use of single-quote deliminated strings to avoid interpolation.'
|
20
|
+
|
21
|
+
def on_str(node)
|
22
|
+
# We're only interested in single-quote deliminated strings.
|
23
|
+
return unless node.source.start_with?("'")
|
24
|
+
# Replace the single quotes deliminating the string with double quotes, and check if the resulting ast is still the same.
|
25
|
+
# If it is, the string doesn't have any interpolation to avoid, and we're done here.
|
26
|
+
return if node == parse('"' + node.source[1..-2] + '"').ast
|
27
|
+
|
28
|
+
add_offense(node) do |corrector|
|
29
|
+
corrector.replace(node, '%q(' + node.source[1..-2] + ')')
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module RuboCop
|
2
|
+
module Cop
|
3
|
+
module Crystal
|
4
|
+
# In ruby, require_relative attempts to load the library relative to the directory of the currently executing file.
|
5
|
+
# Crystal does not have require_relative, but it has the same behavior in the form of require './foo'
|
6
|
+
#
|
7
|
+
# @example
|
8
|
+
# # bad
|
9
|
+
# require_relative 'foo'
|
10
|
+
# require_relative './bar'
|
11
|
+
# require_relative '../baz'
|
12
|
+
# require_relative '/qux'
|
13
|
+
#
|
14
|
+
# # good
|
15
|
+
# require './foo'
|
16
|
+
# require './bar'
|
17
|
+
# require '../baz'
|
18
|
+
# require '/qux'
|
19
|
+
#
|
20
|
+
class RequireRelative < Base
|
21
|
+
extend AutoCorrector
|
22
|
+
MSG = 'Crystal does not support require_relative.'
|
23
|
+
RESTRICT_ON_SEND = [:require_relative]
|
24
|
+
|
25
|
+
def on_send(node)
|
26
|
+
add_offense(node) do |corrector|
|
27
|
+
if node.first_argument.value.start_with?('.', '/')
|
28
|
+
require_value = node.first_argument.value
|
29
|
+
else
|
30
|
+
require_value = "./#{node.first_argument.value}"
|
31
|
+
end
|
32
|
+
corrector.replace(node, "require '#{require_value}'")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/rubocop-crystal.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |spec|
|
2
2
|
spec.name = 'rubocop-crystal'
|
3
3
|
spec.summary = 'A RuboCop extension for converting Ruby to Crystal.'
|
4
|
-
spec.version = '0.0.
|
4
|
+
spec.version = '0.0.2'
|
5
5
|
spec.license = 'GPL-3.0-or-later'
|
6
6
|
spec.author = 'Zopolis4'
|
7
7
|
spec.email = 'creatorsmithmdt@gmail.com'
|
@@ -10,5 +10,5 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.files = `git ls-files`.split("\n")
|
11
11
|
spec.require_paths = ['lib']
|
12
12
|
|
13
|
-
spec.
|
13
|
+
spec.add_dependency 'rubocop', '>= 1.65.1'
|
14
14
|
end
|
data/test/harness.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
class Test
|
2
|
+
@@failed_tests = 0
|
3
|
+
@@passed_tests = 0
|
4
|
+
|
5
|
+
def self.failed_tests
|
6
|
+
@@failed_tests
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.passed_tests
|
10
|
+
@@passed_tests
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.assert_equal(expected, actual)
|
14
|
+
if expected == actual
|
15
|
+
@@passed_tests += 1
|
16
|
+
else
|
17
|
+
@@failed_tests += 1
|
18
|
+
puts "Assertion of equality failed:"
|
19
|
+
puts "Expected: #{expected}"
|
20
|
+
puts "Actual: #{actual}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.assert_unequal(expected, actual)
|
25
|
+
if expected != actual
|
26
|
+
@@passed_tests += 1
|
27
|
+
else
|
28
|
+
@@failed_tests += 1
|
29
|
+
puts "Assertion of inequality failed:"
|
30
|
+
puts "Expected: #{expected}"
|
31
|
+
puts "Actual: #{actual}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
at_exit do
|
37
|
+
puts "#{Test.passed_tests} tests passed."
|
38
|
+
puts "#{Test.failed_tests} tests failed."
|
39
|
+
exit(1) if Test.failed_tests.positive?
|
40
|
+
end
|
41
|
+
|
data/test/string.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require_relative 'harness'
|
2
|
+
|
3
|
+
Test.assert_equal 'foo', "foo"
|
4
|
+
Test.assert_equal 'foo'"bar", "foobar"
|
5
|
+
Test.assert_equal "foobar", "foo" + 'bar'
|
6
|
+
|
7
|
+
foo = 'bar'
|
8
|
+
Test.assert_equal '#{foo}', '#{foo}'
|
9
|
+
Test.assert_equal 'bar', "#{foo}"
|
10
|
+
|
11
|
+
Test.assert_unequal 'bar', '#{foo}'
|
12
|
+
Test.assert_unequal "#{foo}", '#{foo}'
|
13
|
+
|
14
|
+
Test.assert_equal '#{foo}'"bar", '#{foo}bar'
|
15
|
+
Test.assert_equal "#{foo}""bar", 'bar' + "bar"
|
16
|
+
|
17
|
+
|
18
|
+
Test.assert_unequal '#{1 + 1}', '2'
|
19
|
+
|
20
|
+
Test.assert_equal '#{foo}'"bar", '#{foo}bar'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubocop-crystal
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Zopolis4
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-08-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubocop
|
@@ -16,20 +16,21 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 1.65.1
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 1.65.1
|
27
27
|
description:
|
28
28
|
email: creatorsmithmdt@gmail.com
|
29
29
|
executables: []
|
30
30
|
extensions: []
|
31
31
|
extra_rdoc_files: []
|
32
32
|
files:
|
33
|
+
- ".github/workflows/test.yml"
|
33
34
|
- ".gitignore"
|
34
35
|
- CHANGELOG.md
|
35
36
|
- LICENSE
|
@@ -37,10 +38,14 @@ files:
|
|
37
38
|
- config/default.yml
|
38
39
|
- lib/rubocop-crystal.rb
|
39
40
|
- lib/rubocop/cop/crystal/file_extension.rb
|
41
|
+
- lib/rubocop/cop/crystal/interpolation_in_single_quotes.rb
|
42
|
+
- lib/rubocop/cop/crystal/require_relative.rb
|
40
43
|
- lib/rubocop/cop/crystal_cops.rb
|
41
44
|
- lib/rubocop/crystal.rb
|
42
45
|
- lib/rubocop/crystal/inject.rb
|
43
46
|
- rubocop-crystal.gemspec
|
47
|
+
- test/harness.rb
|
48
|
+
- test/string.rb
|
44
49
|
homepage: https://github.com/Zopolis4/rubocop-crystal
|
45
50
|
licenses:
|
46
51
|
- GPL-3.0-or-later
|