kar 0.1.0 → 0.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9cb55eed4dafe4bbab2c0538ae1a8db4bfa7c7eec218bbcfd032e6338f6dd73f
4
- data.tar.gz: a8fc42a08018db8aa2ed5a2d7a12f4450d130df764d4cd1462548929e2c8fb37
3
+ metadata.gz: 997bfcbcd92bf9aea3625eaa6f66622c9077e93e754c83328ee48a24d0d42a59
4
+ data.tar.gz: 1a32d287aa169199d98d8af143c3a12be8c84b3be894faf7c5a32479bf1887c8
5
5
  SHA512:
6
- metadata.gz: '0913f70bb384324388c9b431e3da5de8859c5ca800b3a516ee28f8e976b00dbda7c9a73c19d09a05e07ecc2c751168f8d8a611cb69ba87fcc62e7aae4377233b'
7
- data.tar.gz: 34ec977869d4ae40f8ca4109a92682ad92ed2265ec22abef08ca896cde6a6c323adbde54ba69b268cbb377a4d8ed554edd4272d58120d3eaf5e6f737c4b52a75
6
+ metadata.gz: d71c84b1473e99ceb209f8c9510f66823446be3ae68aca1e31e389f6ff5c23c6bdcad4cf3886e28b8144dbf7c04c76ef4dede8ed2721d6d75e9d5ae11e28c0c9
7
+ data.tar.gz: 240afac657222785391bb06b87254137e9fdacc71c323e155a12787d51abe163221c4c0560d1bb6bc89d68f1fbdd8fcb985a01f2ff1be289afdedbb4241a253a
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.1.2] - 2025-10-26
4
+
5
+ - CargoTask, build extension in Rust
6
+
7
+ ## [0.1.1] - 2025-10-24
8
+
9
+ - URITask, handle redirection
10
+
3
11
  ## [0.1.0] - 2024-01-09
4
12
 
5
13
  - Initial release
data/README.md CHANGED
@@ -23,6 +23,7 @@ Usage
23
23
  download "local/path/to/file" => "https://example.net/remote/path/to/file"
24
24
  FILES = FileList["fileA", "fileB", "fileC"]
25
25
  files FILES
26
+ cargo "my_gem"
26
27
 
27
28
  Development
28
29
  -----------
data/kar.gemspec CHANGED
@@ -1,10 +1,6 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "lib/kar/version"
4
-
5
1
  Gem::Specification.new do |spec|
6
2
  spec.name = "kar"
7
- spec.version = Kar::VERSION
3
+ spec.version = "0.1.2"
8
4
  spec.authors = ["Kitaiti Makoto"]
9
5
  spec.email = ["KitaitiMakoto@gmail.com"]
10
6
 
@@ -0,0 +1,113 @@
1
+ require "rake/clean"
2
+ require "rubygems/ext"
3
+ require "json"
4
+ require "shellwords"
5
+ require "stringio"
6
+
7
+ module Kar
8
+ class CargoTask
9
+ include Rake::DSL
10
+
11
+ def initialize(target)
12
+ @target = target
13
+
14
+ define
15
+ end
16
+
17
+ private
18
+
19
+ def verbose?
20
+ Rake.verbose == true
21
+ end
22
+
23
+ def define
24
+ file dl_path => [manifest, lock_file] + src do |t|
25
+ results = Results.new
26
+ begin
27
+ Gem::Ext::CargoBuilder.new.build t.source, ".", results, [], lib_dir, File.expand_path(ext_dir)
28
+ rescue => error
29
+ $stderr.puts results unless verbose?
30
+ fail
31
+ end
32
+ end
33
+ CLEAN.include dl_name, dl_path
34
+
35
+ namespace :cargo do
36
+ task @target => dl_path
37
+
38
+ # TODO: Consider the case `target` is "validate"
39
+ namespace :validate do
40
+ task @target => manifest do |t|
41
+ `cargo metadata --format-version=1 --manifest-path=#{manifest.shellescape} --locked --quiet`
42
+ fail unless $?.success?
43
+ end
44
+ end
45
+
46
+ desc "Validate Cargo.lock files"
47
+ task validate: "cargo:validate:#{@target}"
48
+ end
49
+
50
+ desc "Build all extensions in Rust"
51
+ task cargo: "cargo:#{@target}"
52
+ end
53
+
54
+ def gemspec
55
+ @gemspec ||= Gem::Specification.load("#{@target}.gemspec")
56
+ end
57
+
58
+ def manifest
59
+ @manifest ||= gemspec.extensions.first
60
+ end
61
+
62
+ def lock_file
63
+ @lock_file ||= manifest.ext(".lock")
64
+ end
65
+
66
+ def ext_dir
67
+ @ext_dir ||= File.dirname(manifest)
68
+ end
69
+
70
+ def lib_dir
71
+ # When a gem include an extension, the first element of require_paths is the directory for extensions and the second is for Ruby files.
72
+ @lib_dir ||= gemspec.require_paths[1]
73
+ end
74
+
75
+ def dl_name
76
+ @dl_name ||= "#{gemspec.name}.#{RbConfig::CONFIG["DLEXT"]}"
77
+ end
78
+
79
+ def dl_path
80
+ @dl_path ||= File.join(lib_dir, dl_name)
81
+ end
82
+
83
+ def src
84
+ @src ||= FileList["#{ext_dir}/src/*/*.rs"]
85
+ end
86
+
87
+ class Results
88
+ def initialize
89
+ @io = verbose? ? $stdout : StringIO.new
90
+ end
91
+
92
+ def <<(output)
93
+ # Always break a line even when output isn't terminated by a line break
94
+ @io.puts output
95
+ end
96
+
97
+ def to_s
98
+ if verbose?
99
+ ""
100
+ else
101
+ @io.rewind
102
+ @io.read
103
+ end
104
+ end
105
+
106
+ private
107
+
108
+ def verbose?
109
+ Rake.verbose == true
110
+ end
111
+ end
112
+ end
113
+ end
data/lib/kar/dsl.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require "kar/uritask"
2
+ require "kar/cargotask"
2
3
 
3
4
  module Kar
4
5
  # DSLs you can use in your Rakefiles
@@ -18,6 +19,9 @@ module Kar
18
19
  #
19
20
  # # Downloads file from https://example.com/remote/file and save to local/file
20
21
  # download "local/file" => "https://example.org/remote/file"
22
+ #
23
+ # # Build extension in Rust
24
+ # cargo "my_gem"
21
25
  module DSL
22
26
  def files(file_list)
23
27
  file_list.each do |file_name|
@@ -46,6 +50,27 @@ module Kar
46
50
  URITask.new args
47
51
  end
48
52
 
53
+ # Declare a cargo task which builds extension in Rust by Cargo.
54
+ #
55
+ # @example
56
+ # # Rakefile
57
+ # cargo "my_gem"
58
+ #
59
+ # task build: :cargo
60
+ #
61
+ # # shell
62
+ # % rake cargo
63
+ #
64
+ # Also defines a cargo:validate task which validates version `Cargo.lock`s are up-to-date.
65
+ # It's useful to add them to the dependency of build task and prevent building invalid gem package.
66
+ #
67
+ # Uses {https://docs.ruby-lang.org/en/master/Gem/Ext/CargoBuilder.html Gem::Ext::CargoBuilder} internally unlike {https://oxidize-rb.org/docs/api-reference/rb-sys-gem-config#rbsysextensiontask RbSys::ExtensionTask}
68
+ # in order to build in the same way as `gem install` command, even though the output might be less usefull.
69
+ # When `RbSys::Extension` uses the same way, this function may be deprecated.
70
+ def cargo(target)
71
+ CargoTask.new target
72
+ end
73
+
49
74
  Rake::DSL.prepend self
50
75
  end
51
76
  end
data/lib/kar/uritask.rb CHANGED
@@ -9,6 +9,8 @@ module Kar
9
9
  # Instanctiated in {DSL#download}
10
10
  class URITask < Rake::TaskLib
11
11
  module Util
12
+ REDIRECT_LIMIT = 3
13
+
12
14
  module_function
13
15
 
14
16
  # @todo Consider return value type
@@ -18,27 +20,54 @@ module Kar
18
20
  # @param headers [Hash<String, Object?>] HTTP headers
19
21
  # @return [String] File path content saved, same to +to+
20
22
  # @return [nil] if remote file responded with 304 Not Modified
21
- def fetch_http(uri, to, headers = {})
22
- http = Net::HTTP.new(uri.host, uri.port)
23
- http.use_ssl = uri.scheme == "https"
24
- http.start do |http|
25
- File.open to, "wb" do |file|
26
- http.request_get uri, headers do |response|
27
- return if response.kind_of? Net::HTTPNotModified
28
-
29
- response.read_body do |chunk|
30
- file.write chunk
31
- end
32
- begin
33
- File.utime Time.now, Time.httpdate(response["Last-Modified"]), to
34
- rescue => err
35
- warn err
23
+ def fetch_http(uri, to, headers = {}, redirected = 0)
24
+ if redirected > REDIRECT_LIMIT
25
+ raise "Too many HTTP redirects"
26
+ end
27
+ Net::HTTP.start uri.host, uri.port, use_ssl: uri.scheme == "https" do |http|
28
+ request = Net::HTTP::Get.new(uri, headers)
29
+ http.request request do |response|
30
+ case response
31
+ when Net::HTTPNotModified
32
+ # noop
33
+ when Net::HTTPOK
34
+ File.open to, "wb" do |file|
35
+ response.read_body do |chunk|
36
+ file.write chunk
37
+ end
38
+ now = Time.now
39
+ last_modified = response["last-modified"]
40
+ mtime = last_modified ? Time.httpdate(last_modified) : now
41
+ File.utime now, Time.httpdate(response["Last-Modified"]), to
36
42
  end
43
+ when Net::HTTPRedirection
44
+ fetch_http URI(response["location"]), to, headers, redirected + 1
45
+ else
46
+ raise "#{response.code} #{response.message}\n#{response.body}"
37
47
  end
38
48
  end
39
49
  end
50
+
40
51
  to
41
52
  end
53
+
54
+ private
55
+
56
+ def fetch_http_with_redirection_handling(uri, headers = {})
57
+ Net::HTTP.start uri.host, uri.port, use_ssl: uri.scheme == "https" do |http|
58
+ request = Net::HTTP::Get.new(uri, headers)
59
+ http.request request do |response|
60
+ case response
61
+ when Net::HTTPRedirection
62
+ return fetch_http_with_redirection_handling(URI(response["location"]), headers)
63
+ when Net::HTTPOK
64
+ return response
65
+ else
66
+ raise "#{response.code} #{response.message}\n#{response.body}"
67
+ end
68
+ end
69
+ end
70
+ end
42
71
  end
43
72
 
44
73
  include Util
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kar
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kitaiti Makoto
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-08-22 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: rake
@@ -81,9 +80,9 @@ files:
81
80
  - agpl-3.0.txt
82
81
  - kar.gemspec
83
82
  - lib/kar.rb
83
+ - lib/kar/cargotask.rb
84
84
  - lib/kar/dsl.rb
85
85
  - lib/kar/uritask.rb
86
- - lib/kar/version.rb
87
86
  - sig/kar.rbs
88
87
  homepage: https://gitlab.com/KitaitiMakoto/kar
89
88
  licenses:
@@ -92,7 +91,6 @@ metadata:
92
91
  homepage_uri: https://gitlab.com/KitaitiMakoto/kar
93
92
  source_code_uri: https://gitlab.com/KitaitiMakoto/kar
94
93
  changelog_uri: https://gitlab.com/KitaitiMakoto/kar/CHANGELOG.md
95
- post_install_message:
96
94
  rdoc_options: []
97
95
  require_paths:
98
96
  - lib
@@ -107,8 +105,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
107
105
  - !ruby/object:Gem::Version
108
106
  version: '0'
109
107
  requirements: []
110
- rubygems_version: 3.5.16
111
- signing_key:
108
+ rubygems_version: 3.7.2
112
109
  specification_version: 4
113
110
  summary: Rake utilities
114
111
  test_files: []
data/lib/kar/version.rb DELETED
@@ -1,5 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Kar
4
- VERSION = "0.1.0"
5
- end