importmap-package-manager 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 6a110fb59f6923d5c6e6b3d646b6b20936dd41785a04a194f4db90c6bff70745
4
+ data.tar.gz: 557158037bd82ba4c6480074fab6ddb4e38061754723ed1ef6ca89ae0620a804
5
+ SHA512:
6
+ metadata.gz: 85a2d44db07e38b2170b2459c8eefdd63d6d9c76aef699347c5fd03b5e44f39a0848e57a9d0e9d77b0e5600e79939dfbc7af060fb8f0942ed8bb5eaef096a971
7
+ data.tar.gz: '0968ac3a5bce98c409b740b19f9337640d4605e68972f278617217a1f168d015ea5922294edf0aa8431bf005e55f67262eb5fa2cdd24519c2ffbbd82472b3f27'
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Quimbee
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.
data/README.md ADDED
@@ -0,0 +1,80 @@
1
+ # importmap-package-manager
2
+
3
+ `importmap-package-manager` adds package version management to [importmap-rails](https://github.com/rails/importmap-rails) via version ranges, similar to how version ranges can be specified in `Gemfile` (eg `~> 4.0`).
4
+
5
+ This is for managing third-party libraries. For your own first-party code, that will still be managed in the normal ways via `importmap-rails`.
6
+
7
+ ## Installation
8
+
9
+ First, you'll need to have [importmap-rails](https://github.com/rails/importmap-rails) set up and configured properly for your application.
10
+
11
+ Once that's done, add this line to your application's Gemfile:
12
+
13
+ ```ruby
14
+ gem "importmap-package-manager"
15
+ ```
16
+
17
+ And then execute:
18
+
19
+ $ bundle install
20
+
21
+ Finally, run this gem's installer:
22
+
23
+ $ bundle exec rails importmap_package_manager:install
24
+
25
+ ## Usage
26
+
27
+ 1. Add packages to `config/importmap_packages.yml` under the `imports` key. See [#package-options] for more details. You'll also want to delete these from `config/importmap.rb`.
28
+ 2. Run `bundle exec rails importmap_package_manager:update` to update `config/importmap-packages-lock.rb`
29
+ 3. That's it! From here, your packages will automatically be available in the importmap and ready to be used.
30
+
31
+ ### Package options
32
+
33
+ Each import should be specified as a key/value pair. In the most simple case, the key is the package name and the value is the version constraint. For example:
34
+
35
+ ```yml
36
+ imports:
37
+ lodash: "~> 4.0"
38
+ ```
39
+
40
+ In this case, `importmap-package-manager` will install the latest 4.0 version of lodash.
41
+
42
+ Packages can also be broken out into more detail, to provide more options:
43
+
44
+ ```yml
45
+ imports:
46
+ lodash/merge:
47
+ package: "lodash"
48
+ version: "~> 4.0.0"
49
+ subpath: "./merge"
50
+ ```
51
+
52
+ This would produce something like the following in your importmap: `{ "lodash/merge": "https://ga.jspm.io/npm:lodash@4.17.21/merge.js" }`
53
+
54
+ In this case, the key is just a unique identifier. It isn't used at all.
55
+
56
+ The options that can be passed for each import are:
57
+
58
+ || Option || Description ||
59
+ | package | Package name, as listed in npmjs.com |
60
+ | version | Version number constraint, using [ruby syntax](https://guides.rubygems.org/patterns/#pessimistic-version-constraint) |
61
+ | subpath | A subpath within the package to pin. This will be used in both the import name, and the path. |
62
+
63
+ ## Development
64
+
65
+ After checking out the repo, run `bundle install` to install dependencies. Then, run `rake spec` to run the tests.
66
+
67
+ To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
68
+
69
+ ## Contributing
70
+
71
+ Bug reports and pull requests are welcome on GitHub at https://github.com/quimbee/importmap-package-manager. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/quimbee/importmap-package-manager/blob/master/CODE_OF_CONDUCT.md).
72
+
73
+
74
+ ## License
75
+
76
+ importmap-package-manager is released under the [MIT License](https://opensource.org/licenses/MIT).
77
+
78
+ ## Code of Conduct
79
+
80
+ Everyone interacting in the Importmap::Version::Manager project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/quimbee/importmap-package-manager/blob/master/CODE_OF_CONDUCT.md).
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -0,0 +1,99 @@
1
+ require "yaml"
2
+
3
+ module ImportmapPackageManager
4
+ class Manager
5
+ HTTPError = Class.new(StandardError)
6
+
7
+ class << self
8
+ def update!(config: nil, lockfile: nil)
9
+ unless config
10
+ config_file = Rails.root.join("config/importmap_packages.yml")
11
+ config = YAML.load_file(config_file)
12
+ end
13
+
14
+ import_map = build_import_map(config)
15
+ update_lockfile!(import_map, lockfile)
16
+ end
17
+
18
+ private
19
+
20
+ def build_import_map(config)
21
+ imports = config["imports"]
22
+
23
+ if imports == nil
24
+ raise "No imports defined. Add import definitions to `config/importmap_packages.yml`"
25
+ end
26
+
27
+ import_definitions =
28
+ imports.map do |import, import_config|
29
+ if import_config.is_a?(String) || import_config.is_a?(Array)
30
+ import_config = { "version" => import_config }
31
+ end
32
+
33
+ package = import_config["package"] || import
34
+ version_requirement = Gem::Requirement.new(import_config["version"])
35
+
36
+ exact_version = resolve_package_version(package, version_requirement)
37
+
38
+ target = "#{package}@#{exact_version}"
39
+
40
+ import_definition = { target: target }
41
+
42
+ if import_config["subpath"]
43
+ import_definition[:subpath] = import_config["subpath"]
44
+ end
45
+ import_definition
46
+ end
47
+ resolve_import_urls(import_definitions)
48
+ end
49
+
50
+ def resolve_package_version(package, version_requirement)
51
+ # Step 1: Query NPM registry for all versions
52
+ response = Net::HTTP.get(URI("https://registry.npmjs.org/#{package}"))
53
+ versions = JSON.parse(response)["versions"].keys.map { |version_string| Gem::Version.new(version_string) }
54
+
55
+ # Step 2: Find latest version that matches version_requirement
56
+ versions.sort.reverse.find { |version| version_requirement.satisfied_by?(version) && !version.prerelease? }
57
+ rescue StandardError => e
58
+ raise HTTPError, "Unexpected transport error (#{e.class}: #{e.message})"
59
+ end
60
+
61
+ def resolve_import_urls(import_definitions)
62
+ response = Net::HTTP.post(
63
+ URI("https://api.jspm.io/generate"),
64
+ {
65
+ install: import_definitions,
66
+ flattenScope: true,
67
+ env: %w[browser module production],
68
+ defaultProvider: "jspm"
69
+ }.to_json,
70
+ "Content-Type" => "application/json"
71
+ )
72
+
73
+ json_response = JSON.parse(response.body)
74
+
75
+ if response.code != "200"
76
+ raise "Error resolving imports: #{json_response['error']}"
77
+ end
78
+
79
+ # Note: ideally, we would also want to pull "scopes" out of the response, to support
80
+ # incompatible subdependencies. However, importmap-rails does not support subdependencies
81
+ # yet: https://github.com/rails/importmap-rails/issues/148
82
+ json_response.dig("map", "imports").sort.to_h
83
+ end
84
+
85
+ def update_lockfile!(import_map, lockfile)
86
+ lockfile ||= Rails.root.join("config/importmap-packages-lock.rb")
87
+
88
+ File.open(lockfile, "w") do |f|
89
+ f << "# NOTE: this file is managed by importmap-package-manager.\n"
90
+ f << "# DO NOT edit this file directly! Instead, edit `config/importmap_packages.yml` and run `rake importmap_package_manager:update`\n"
91
+
92
+ import_map.each do |import, url|
93
+ f << %(pin "#{import}", to: "#{url}"\n)
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,13 @@
1
+ require "importmap-package-manager"
2
+ require "rails"
3
+
4
+ module ImportmapPackageManager
5
+ class Railtie < Rails::Railtie
6
+ railtie_name :importmap_package_manager
7
+
8
+ rake_tasks do
9
+ path = File.expand_path(__dir__)
10
+ Dir.glob("#{path}/tasks/**/*.rake").each { |f| load f }
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,24 @@
1
+ namespace :importmap_package_manager do
2
+ desc "Install importmap-package-manager"
3
+ task install: :environment do
4
+ File.open(Rails.root.join("config/importmap_packages.yml"), "w") do |f|
5
+ f << %(imports:\n)
6
+ f << %( # For example:\n)
7
+ f << %( # lodash: "~> 4.0"\n)
8
+ end
9
+
10
+ File.open(Rails.root.join("config/initializers/importmap-package-manager.rb"), "w") do |f|
11
+ f << %(Rails.application.configure do\n)
12
+ f << %( config.importmap.paths << Rails.root.join\("config/importmap-packages-lock.rb"\)\n)
13
+ f << %(end\n)
14
+ end
15
+
16
+ File.open(Rails.root.join("config/importmap.rb"), "a") do |f|
17
+ f << %(\n)
18
+ f << %(# Note: package imports are managed by importmap-package-manager.\n)
19
+ f << %(# To add or update packages, make changes in `config/importmap_packages.yml`,\n)
20
+ f << %(# then run `importmap_package_manager:update` to update `config/importmap-packages-lock.rb`.\n)
21
+ f << %(# That file is included into the importmap via `config/initializers/importmap-package-manager.rb`\n)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,6 @@
1
+ namespace :importmap_package_manager do
2
+ desc "Update importmap packages via importmap-package-manager"
3
+ task update: :environment do
4
+ ImportmapPackageManager::Manager.update!
5
+ end
6
+ end
@@ -0,0 +1,3 @@
1
+ module ImportmapPackageManager
2
+ VERSION = "0.1.0".freeze
3
+ end
@@ -0,0 +1,6 @@
1
+ require "importmap-package-manager/version"
2
+ require "importmap-package-manager/manager"
3
+
4
+ module ImportmapPackageManager
5
+ require "importmap-package-manager/railtie" if defined?(Rails)
6
+ end
metadata ADDED
@@ -0,0 +1,54 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: importmap-package-manager
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Derek Kniffin
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2023-08-25 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description:
14
+ email:
15
+ - derek@quimbee.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - LICENSE
21
+ - README.md
22
+ - Rakefile
23
+ - lib/importmap-package-manager.rb
24
+ - lib/importmap-package-manager/manager.rb
25
+ - lib/importmap-package-manager/railtie.rb
26
+ - lib/importmap-package-manager/tasks/install.rake
27
+ - lib/importmap-package-manager/tasks/update.rake
28
+ - lib/importmap-package-manager/version.rb
29
+ homepage: https://github.com/Quimbee/importmap-package-manager
30
+ licenses:
31
+ - MIT
32
+ metadata:
33
+ homepage_uri: https://github.com/Quimbee/importmap-package-manager
34
+ source_code_uri: https://github.com/Quimbee/importmap-package-manager
35
+ post_install_message:
36
+ rdoc_options: []
37
+ require_paths:
38
+ - lib
39
+ required_ruby_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 2.7.0
44
+ required_rubygems_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ requirements: []
50
+ rubygems_version: 3.3.26
51
+ signing_key:
52
+ specification_version: 4
53
+ summary: Manages importmap package versions using ruby-like version constraints
54
+ test_files: []