Add Steep type checking starting with Config
Assisted-by: Claude Sonnet 4.6 via Claude Code
change wwmtsxzpowkmoylmkowppuxoxyvoxxkk
commit 95f6bf9c9c1e5cb264a3d4a982a18e447d418eba
author Alpha Chen <alpha@kejadlen.dev>
date
parent vmltrtqt
diff --git a/Gemfile b/Gemfile
index 09c6ad9..b8282c7 100644
--- a/Gemfile
+++ b/Gemfile
@@ -15,5 +15,7 @@ gem "rake"
 group :development, :test do
   gem "minitest"
   gem "rack-test"
+  gem "rbs-inline", require: false
   gem "ruby-lsp"
+  gem "steep"
 end
diff --git a/Gemfile.lock b/Gemfile.lock
index da04ffa..851e0c5 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -9,27 +9,57 @@ GIT
 GEM
   remote: https://rubygems.org/
   specs:
+    ast (2.4.3)
     bigdecimal (4.1.2)
+    concurrent-ruby (1.3.6)
+    csv (3.3.5)
     drb (2.2.3)
+    ffi (1.17.4-aarch64-linux-gnu)
+    ffi (1.17.4-aarch64-linux-musl)
+    ffi (1.17.4-arm-linux-gnu)
+    ffi (1.17.4-arm-linux-musl)
+    ffi (1.17.4-arm64-darwin)
+    ffi (1.17.4-x86-linux-gnu)
+    ffi (1.17.4-x86-linux-musl)
+    ffi (1.17.4-x86_64-darwin)
+    ffi (1.17.4-x86_64-linux-gnu)
+    ffi (1.17.4-x86_64-linux-musl)
+    fileutils (1.8.0)
+    json (2.19.7)
     language_server-protocol (3.17.0.5)
+    listen (3.10.0)
+      logger
+      rb-fsevent (~> 0.10, >= 0.10.3)
+      rb-inotify (~> 0.9, >= 0.9.10)
     logger (1.7.0)
     minitest (6.0.6)
       drb (~> 2.0)
       prism (~> 1.5)
     nio4r (2.7.5)
+    parser (3.3.11.1)
+      ast (~> 2.4.1)
+      racc
     prism (1.9.0)
     puma (8.0.1)
       nio4r (~> 2.0)
+    racc (1.8.1)
     rack (3.2.6)
     rack-test (2.2.0)
       rack (>= 1.3)
     rackup (2.3.1)
       rack (>= 3)
+    rainbow (3.1.1)
     rake (13.4.2)
+    rb-fsevent (0.11.2)
+    rb-inotify (0.11.1)
+      ffi (~> 1.0)
     rbs (4.0.2)
       logger
       prism (>= 1.6.0)
       tsort
+    rbs-inline (0.14.0)
+      prism (>= 0.29)
+      rbs (~> 4.0)
     refract (1.1.0)
       prism
       zeitwerk
@@ -39,6 +69,7 @@ GEM
       language_server-protocol (~> 3.17.0)
       prism (>= 1.2, < 2.0)
       rbs (>= 3, < 5)
+    securerandom (0.4.1)
     sequel (5.104.0)
       bigdecimal
     sqlite3 (2.9.3-aarch64-linux-gnu)
@@ -51,7 +82,30 @@ GEM
     sqlite3 (2.9.3-x86_64-darwin)
     sqlite3 (2.9.3-x86_64-linux-gnu)
     sqlite3 (2.9.3-x86_64-linux-musl)
+    steep (2.0.0)
+      concurrent-ruby (>= 1.1.10)
+      csv (>= 3.0.9)
+      fileutils (>= 1.1.0)
+      json (>= 2.1.0)
+      language_server-protocol (>= 3.17.0.4, < 4.0)
+      listen (~> 3.0)
+      logger (>= 1.3.0)
+      parser (>= 3.2)
+      prism (>= 0.25.0)
+      rainbow (>= 2.2.2, < 4.0)
+      rbs (~> 4.0)
+      securerandom (>= 0.1)
+      strscan (>= 1.0.0)
+      terminal-table (>= 2, < 5)
+      uri (>= 0.12.0)
+    strscan (3.1.8)
+    terminal-table (4.0.0)
+      unicode-display_width (>= 1.1.1, < 4)
     tsort (0.2.0)
+    unicode-display_width (3.2.0)
+      unicode-emoji (~> 4.1)
+    unicode-emoji (4.2.0)
+    uri (1.1.1)
     zeitwerk (2.7.5)
 
 PLATFORMS
@@ -73,10 +127,12 @@ DEPENDENCIES
   rack-test
   rackup
   rake
+  rbs-inline
   roda
   ruby-lsp
   sequel
   sqlite3
+  steep
 
 BUNDLED WITH
   4.0.11
diff --git a/Rakefile b/Rakefile
index 85686fc..af76f3b 100644
--- a/Rakefile
+++ b/Rakefile
@@ -7,20 +7,23 @@ require "sequel/extensions/migration"
 DOMUS_APP = Domus::App.new
 DB = DOMUS_APP.db
 
-BUNDLE_INSTALL_MARKER = Pathname.new(".bundle/installed")
-
-file BUNDLE_INSTALL_MARKER do
-  sh "bundle install"
+desc "Create bundler binstubs (runs when Gemfile.lock changes)"
+file ".direnv/.bundled" => ["Gemfile.lock"] do
   sh "bundle binstubs --all"
-  mkdir_p BUNDLE_INSTALL_MARKER.dirname
-  touch BUNDLE_INSTALL_MARKER
+  touch ".direnv/.bundled"
 end
 
-task setup: BUNDLE_INSTALL_MARKER
+task binstubs: ".direnv/.bundled"
 
 Minitest::TestTask.create(:test)
 
-task default: :test
+desc "Generate RBS from inline annotations and run Steep type checker"
+task :check do
+  sh "rbs-inline --output lib/"
+  sh "steep check"
+end
+
+task default: %i[test check]
 
 desc "Start dev server"
 task :dev do
diff --git a/Steepfile b/Steepfile
new file mode 100644
index 0000000..ab13d20
--- /dev/null
+++ b/Steepfile
@@ -0,0 +1,4 @@
+target :lib do
+  signature "sig"
+  check "lib/config.rb"
+end
diff --git a/lib/config.rb b/lib/config.rb
index a454210..198edaf 100644
--- a/lib/config.rb
+++ b/lib/config.rb
@@ -1,7 +1,13 @@
+# rbs_inline: enabled
 # frozen_string_literal: true
 
 module Domus
-  class Config < Data.define(:database_url)
+  Config = Data.define(
+    :database_url, #: String
+  )
+
+  class Config
+    #: () -> Config
     def self.env = new(database_url: ENV.fetch("DATABASE_URL") { "db/domus.db" })
   end
 end
diff --git a/sig/generated/config.rbs b/sig/generated/config.rbs
new file mode 100644
index 0000000..98e9aa1
--- /dev/null
+++ b/sig/generated/config.rbs
@@ -0,0 +1,19 @@
+# Generated from lib/config.rb with RBS::Inline
+
+module Domus
+  class Config < Data
+    attr_reader database_url(): String
+
+    def self.new: (String database_url) -> instance
+                | (database_url: String) -> instance
+
+    def self.members: () -> [ :database_url ]
+
+    def members: () -> [ :database_url ]
+  end
+
+  class Config
+    # : () -> Config
+    def self.env: () -> Config
+  end
+end