upm_support 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 +7 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +81 -0
- data/DEVELOPPING.md +69 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +70 -0
- data/MIGRATION.md +140 -0
- data/Rakefile +26 -0
- data/VERDACCIO.md +34 -0
- data/exe/migrate.rb +6 -0
- data/lib/assets/migrations.json +17 -0
- data/lib/upm_support/actions.rb +151 -0
- data/lib/upm_support/unity.rb +88 -0
- data/lib/upm_support/uplift.rb +96 -0
- data/lib/upm_support/version.rb +6 -0
- data/lib/upm_support.rb +31 -0
- data/upm_support.gemspec +38 -0
- metadata +172 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: bdccee4a391fc96e977f141b354b0480f25a95af8a923f410986c3bb761b96d1
|
4
|
+
data.tar.gz: 909e6c8f2ab2ee6f331692e22935aabdd2c3e0cdafac0e78ad13b4801ba55366
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 62e5ac97f852f50b179c1a19f63b034d914aa6ddfc31b74be3aece501979e7c45d9e6ad378e4fddfa1dd1c5de1f627b38277b3ab700fe2e01c519c42d1ad9b4e
|
7
|
+
data.tar.gz: bf855ba5fb3b34c7377744acb71b841ace529290480bf11409e90b680cab5ab5a291ec0f0c5502db52949fef3f77fc618f5c914b804d9e21a7fbf2740043140d
|
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
spec/upm_support/assets/test_*
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
#
|
2
|
+
# File.chmod(0777, f)
|
3
|
+
#
|
4
|
+
# is easier to read than
|
5
|
+
#
|
6
|
+
# File.chmod(0o777, f)
|
7
|
+
#
|
8
|
+
require:
|
9
|
+
- rubocop-rake
|
10
|
+
- rubocop-rspec
|
11
|
+
|
12
|
+
AllCops:
|
13
|
+
NewCops: enable
|
14
|
+
#Include:
|
15
|
+
# - '**/fastlane/Fastfile'
|
16
|
+
#Exclude:
|
17
|
+
# - 'vendor/**/*'
|
18
|
+
# - './fastlane-plugin-u3d/**/*'
|
19
|
+
|
20
|
+
# broken in 0.52.1
|
21
|
+
Layout/EmptyLinesAroundArguments:
|
22
|
+
Enabled: false
|
23
|
+
|
24
|
+
Style/NumericLiteralPrefix:
|
25
|
+
Enabled: false
|
26
|
+
|
27
|
+
Style/StringLiterals:
|
28
|
+
Enabled: false # we're not there yet
|
29
|
+
|
30
|
+
Metrics/AbcSize:
|
31
|
+
Enabled: false
|
32
|
+
|
33
|
+
Metrics/BlockLength:
|
34
|
+
Enabled: false
|
35
|
+
|
36
|
+
Metrics/CyclomaticComplexity:
|
37
|
+
Enabled: false
|
38
|
+
|
39
|
+
Metrics/ParameterLists:
|
40
|
+
Max: 8
|
41
|
+
|
42
|
+
Metrics/PerceivedComplexity:
|
43
|
+
Max: 12
|
44
|
+
|
45
|
+
Metrics/MethodLength:
|
46
|
+
Enabled: false
|
47
|
+
|
48
|
+
# Configuration parameters: AllowURI, URISchemes.
|
49
|
+
Layout/LineLength:
|
50
|
+
Max: 370
|
51
|
+
|
52
|
+
# We're not there yet
|
53
|
+
Style/Documentation:
|
54
|
+
Enabled: false
|
55
|
+
|
56
|
+
# Better too much 'return' than one missing
|
57
|
+
Style/RedundantReturn:
|
58
|
+
Enabled: false
|
59
|
+
|
60
|
+
# Tell Windows to look the other way
|
61
|
+
Layout/EndOfLine:
|
62
|
+
EnforcedStyle: lf
|
63
|
+
|
64
|
+
# Some issues with rspec style
|
65
|
+
Lint/AmbiguousBlockAssociation:
|
66
|
+
Enabled: false
|
67
|
+
|
68
|
+
RSpec/MultipleDescribes:
|
69
|
+
Enabled: false
|
70
|
+
|
71
|
+
RSpec/ExampleLength:
|
72
|
+
Enabled: false
|
73
|
+
|
74
|
+
RSpec/MultipleExpectations:
|
75
|
+
Enabled: false
|
76
|
+
|
77
|
+
Rspec/RSpec/FilePath:
|
78
|
+
Enabled: false
|
79
|
+
|
80
|
+
Lint/EmptyBlock:
|
81
|
+
Enabled: false
|
data/DEVELOPPING.md
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
# Setting up CI
|
2
|
+
|
3
|
+
on agent
|
4
|
+
|
5
|
+
1. install npm
|
6
|
+
|
7
|
+
brew install npm
|
8
|
+
|
9
|
+
2. log in npm
|
10
|
+
|
11
|
+
npm login --registry 'https://upm.dragonbox.com'
|
12
|
+
|
13
|
+
(user: jenkins, Password in 1Password)
|
14
|
+
|
15
|
+
# Developping a UPM package
|
16
|
+
|
17
|
+
See the official layout https://docs.unity3d.com/Manual/cus-layout.html
|
18
|
+
|
19
|
+
## Testing your packages from another Unity Project
|
20
|
+
|
21
|
+
using git, example
|
22
|
+
|
23
|
+
```
|
24
|
+
"com.dragonbox.simple-build": "ssh://git@bitbucket.org/WeWantToKnow/wwtk.simplebuild.git?path=Assets/SimpleBuild#task/upm/migration",
|
25
|
+
```
|
26
|
+
|
27
|
+
More here https://docs.unity3d.com/Manual/upm-git.html
|
28
|
+
|
29
|
+
## or using an UPM
|
30
|
+
|
31
|
+
```
|
32
|
+
"scopedRegistries": [
|
33
|
+
{
|
34
|
+
"name": "DragonBox",
|
35
|
+
"url": "https://upm.dragonbox.com/",
|
36
|
+
"scopes": [
|
37
|
+
"com.dragonbox"
|
38
|
+
]
|
39
|
+
}
|
40
|
+
],
|
41
|
+
"dependencies": {
|
42
|
+
"com.dragonbox.simple-build": "1.2.1",
|
43
|
+
```
|
44
|
+
using a local verdaccio
|
45
|
+
|
46
|
+
## test building using our infra
|
47
|
+
|
48
|
+
```
|
49
|
+
UPM_REGISTRY=http://127.0.0.1:4873 bundle exec fastlane unity_package build_unity_package
|
50
|
+
```
|
51
|
+
|
52
|
+
test publishing using our infra
|
53
|
+
|
54
|
+
```
|
55
|
+
UPM_REGISTRY=http://127.0.0.1:4873 bundle exec fastlane unity_package publish_upm_modules
|
56
|
+
```
|
57
|
+
|
58
|
+
|
59
|
+
# Importing third party packages
|
60
|
+
|
61
|
+
Google provides packages but no UPM support
|
62
|
+
|
63
|
+
https://developers.google.com/unity/instructions#install-tgz
|
64
|
+
|
65
|
+
Just upload them like this
|
66
|
+
|
67
|
+
```
|
68
|
+
npm publish --registry https://upm.dragonbox.com com.google.external-dependency-manager-1.2.170.tgz
|
69
|
+
```
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
upm_support (0.0.2)
|
5
|
+
rexml
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
ast (2.4.2)
|
11
|
+
diff-lcs (1.5.0)
|
12
|
+
parallel (1.22.1)
|
13
|
+
parser (3.1.2.0)
|
14
|
+
ast (~> 2.4.1)
|
15
|
+
rainbow (3.1.1)
|
16
|
+
rake (13.0.6)
|
17
|
+
regexp_parser (2.3.1)
|
18
|
+
rexml (3.2.5)
|
19
|
+
rspec (3.11.0)
|
20
|
+
rspec-core (~> 3.11.0)
|
21
|
+
rspec-expectations (~> 3.11.0)
|
22
|
+
rspec-mocks (~> 3.11.0)
|
23
|
+
rspec-core (3.11.0)
|
24
|
+
rspec-support (~> 3.11.0)
|
25
|
+
rspec-expectations (3.11.0)
|
26
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
27
|
+
rspec-support (~> 3.11.0)
|
28
|
+
rspec-mocks (3.11.1)
|
29
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
30
|
+
rspec-support (~> 3.11.0)
|
31
|
+
rspec-support (3.11.0)
|
32
|
+
rspec_junit_formatter (0.5.1)
|
33
|
+
rspec-core (>= 2, < 4, != 2.12.0)
|
34
|
+
rubocop (1.28.2)
|
35
|
+
parallel (~> 1.10)
|
36
|
+
parser (>= 3.1.0.0)
|
37
|
+
rainbow (>= 2.2.2, < 4.0)
|
38
|
+
regexp_parser (>= 1.8, < 3.0)
|
39
|
+
rexml
|
40
|
+
rubocop-ast (>= 1.17.0, < 2.0)
|
41
|
+
ruby-progressbar (~> 1.7)
|
42
|
+
unicode-display_width (>= 1.4.0, < 3.0)
|
43
|
+
rubocop-ast (1.17.0)
|
44
|
+
parser (>= 3.1.1.0)
|
45
|
+
rubocop-rake (0.6.0)
|
46
|
+
rubocop (~> 1.0)
|
47
|
+
rubocop-rspec (2.10.0)
|
48
|
+
rubocop (~> 1.19)
|
49
|
+
ruby-progressbar (1.11.0)
|
50
|
+
unicode-display_width (2.1.0)
|
51
|
+
|
52
|
+
PLATFORMS
|
53
|
+
arm64-darwin-21
|
54
|
+
x86_64-darwin-21
|
55
|
+
|
56
|
+
DEPENDENCIES
|
57
|
+
bundler (~> 2.0)
|
58
|
+
rake (~> 13.0)
|
59
|
+
rspec (~> 3.11.0)
|
60
|
+
rspec_junit_formatter (~> 0.5.1)
|
61
|
+
rubocop (~> 1.27)
|
62
|
+
rubocop-rake (~> 0.6.0)
|
63
|
+
rubocop-rspec (~> 2.10.0)
|
64
|
+
upm_support!
|
65
|
+
|
66
|
+
RUBY VERSION
|
67
|
+
ruby 2.7.4p191
|
68
|
+
|
69
|
+
BUNDLED WITH
|
70
|
+
2.3.13
|
data/MIGRATION.md
ADDED
@@ -0,0 +1,140 @@
|
|
1
|
+
# Migrating from Uplift
|
2
|
+
|
3
|
+
## Edit the jenkins job
|
4
|
+
|
5
|
+
### Edit the JENKINS_PARAM_LANE_ENV env variable
|
6
|
+
|
7
|
+
```
|
8
|
+
Artifact
|
9
|
+
GithubRepository
|
10
|
+
UnityPackageRegistry
|
11
|
+
```
|
12
|
+
|
13
|
+
### edit the "archive the artifacts" config
|
14
|
+
|
15
|
+
```
|
16
|
+
u3d*.log
|
17
|
+
```
|
18
|
+
|
19
|
+
## Update the project dependencies
|
20
|
+
|
21
|
+
### upgrade ruby in project
|
22
|
+
|
23
|
+
minimum 2.7.4
|
24
|
+
|
25
|
+
```
|
26
|
+
cp ../../DevInfra/fastlane_setup/Gemfile .
|
27
|
+
```
|
28
|
+
|
29
|
+
or (doesn't get all the necessary updates)
|
30
|
+
|
31
|
+
```
|
32
|
+
sed -i '' -e 's/ruby \"2.5.3\"/ruby \"2.7.4\"/' Gemfile && rvm use 2.7.4 && bundle install && git add Gemfile* && git commit -m "Upgrade ruby to 2.7.4"
|
33
|
+
```
|
34
|
+
|
35
|
+
### upgrade unity
|
36
|
+
|
37
|
+
We need minimum 2019.4.9f1
|
38
|
+
|
39
|
+
Start unity and and reserialize (if you have SimpleBuild)
|
40
|
+
|
41
|
+
```
|
42
|
+
u3d -u 2019.4.9f1
|
43
|
+
or
|
44
|
+
u3d -u 2019.4.31f1
|
45
|
+
```
|
46
|
+
|
47
|
+
Update the .gitignore
|
48
|
+
|
49
|
+
Commit
|
50
|
+
|
51
|
+
```
|
52
|
+
git add .gitignore
|
53
|
+
git add Packages/
|
54
|
+
git add ProjectSettings/
|
55
|
+
git commit -am "Upgraded to Unity 2019.LTS"
|
56
|
+
```
|
57
|
+
|
58
|
+
### latest fastlane_setup
|
59
|
+
|
60
|
+
in particular Gemfile requirements (should have been done if you copied the Gemfile from fastlane_setup earlier)
|
61
|
+
|
62
|
+
```
|
63
|
+
gem 'upm_support', git: 'git@bitbucket.org:WeWantToKnow/upm_support.git'
|
64
|
+
```
|
65
|
+
|
66
|
+
## remove already uplifted dependencies
|
67
|
+
|
68
|
+
The upm_support package can also be used from your developper machine to help speeding up migration a bit.
|
69
|
+
|
70
|
+
```
|
71
|
+
git clone git@bitbucket.org:WeWantToKnow/upm_support.git
|
72
|
+
|
73
|
+
export PATH=/Users/lacostej/Code/WWTK/DevInfra/upm_migration/exe/:$PATH
|
74
|
+
```
|
75
|
+
|
76
|
+
### upgrade packages to their latest deps
|
77
|
+
|
78
|
+
```
|
79
|
+
migrate.rb to_upm [--force-upgrade]
|
80
|
+
```
|
81
|
+
|
82
|
+
```
|
83
|
+
migrate.rb clean_upbring
|
84
|
+
```
|
85
|
+
|
86
|
+
open unity and resolve dependencies and commit
|
87
|
+
|
88
|
+
git add Packages/
|
89
|
+
|
90
|
+
### Create the layout and ASMDEFs
|
91
|
+
|
92
|
+
1. move all required dependencies for the package (not the projects) into UPM
|
93
|
+
2. regroup all parts of the package under a single folder. E.g. `Assets/YourPackage/` or `Assets/DragonBox.YourPackage/`
|
94
|
+
3. create the `Editor/` and `Runtime/` subfolders and a default [package.json](FIXME). Use an experimental version number (`-exp.X` suffix) at start.
|
95
|
+
4. move relevant resources (code, assets, etc) under these folders
|
96
|
+
5. add dependencies to the `package.json` as needed
|
97
|
+
See [this package.json example](https://bitbucket.org/WeWantToKnow/wwtk.crashreporter/src/master/Assets/CrashReporter/package.json)
|
98
|
+
6. Create the [ASDMDEFs](https://docs.unity3d.com/Manual/ScriptCompilationAssemblyDefinitionFiles.html#reference-and-assemblies) and add [Assembly Definition references](https://docs.unity3d.com/Manual/class-AssemblyDefinitionReferenceImporter.html) as needed
|
99
|
+
See this [ASMDEF example](https://bitbucket.org/WeWantToKnow/wwtk.crashreporter/src/master/Assets/CrashReporter/Runtime/DragonBox.CrashReporter.Runtime.asmdef)
|
100
|
+
7. double check if tests are still running properly by running them from the Unity test runner.
|
101
|
+
8. commit files in your branch and push feature branch to repo
|
102
|
+
9. test package in a different project using e.g. the [git import package syntax](DEVELOPPING.md)
|
103
|
+
10. iterate by bumping the package version number and pushing to your branch
|
104
|
+
|
105
|
+
When stable, test the infra further
|
106
|
+
|
107
|
+
1. merge branch, and check the jenkins Artifact build
|
108
|
+
2. bump to stable version in `package.json` (remove `-exp.X` suffix) and push
|
109
|
+
3. Run a UPM package build (will publish to our internal repository)
|
110
|
+
4. test importing your package into your projects (you can use the `migrate.rb` tool again to upgrade the dependencies locally inside your project(s))
|
111
|
+
|
112
|
+
|
113
|
+
If your package is usually depended upon by projects, then add an entry in the [Uplift to UPM mapping](https://bitbucket.org/WeWantToKnow/upm_support/src/master/lib/assets/migrations.json) to ease migration.
|
114
|
+
|
115
|
+
|
116
|
+
## Clean up Uplift support
|
117
|
+
|
118
|
+
```
|
119
|
+
git rm Upfile*
|
120
|
+
git rm Assets/Plugins/Editor/Uplift/Uplift.dll*
|
121
|
+
git rm Assets/Plugins/Editor/Uplift.meta
|
122
|
+
git grep 5d250b32d4a234419b8b94fff388f1fc Assets/*.asset | cut -d ':' -f 1 | xargs git rm
|
123
|
+
git rm Assets/*Upset.xml*
|
124
|
+
```
|
125
|
+
|
126
|
+
Clean .env files, remove
|
127
|
+
|
128
|
+
FASTLANE_UPLIFT_TASKS
|
129
|
+
JENKINS_ARTIFACTS
|
130
|
+
|
131
|
+
|
132
|
+
|
133
|
+
## Clean up Jenkins job
|
134
|
+
|
135
|
+
### Edit the JENKINS_PARAM_LANE_ENV env variable
|
136
|
+
|
137
|
+
```
|
138
|
+
Artifact
|
139
|
+
UnityPackageRegistry
|
140
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/gem_tasks'
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
require 'rubocop/rake_task'
|
6
|
+
|
7
|
+
RuboCop::RakeTask.new do |task|
|
8
|
+
task.requires << 'rubocop-rake'
|
9
|
+
end
|
10
|
+
|
11
|
+
desc 'Run all rspec tests'
|
12
|
+
task :test_all do
|
13
|
+
formatter = '--format progress'
|
14
|
+
if ENV['CIRCLECI']
|
15
|
+
Dir.mkdir('/tmp/rspec/')
|
16
|
+
formatter += ' -r rspec_junit_formatter --format RspecJunitFormatter -o /tmp/rspec/rspec.xml'
|
17
|
+
TEST_FILES = `(circleci tests glob "spec/**/*_spec.rb" | circleci tests split --split-by=timings)`.tr!("\n", ' ')
|
18
|
+
rspec_args = "#{formatter} #{TEST_FILES}"
|
19
|
+
else
|
20
|
+
formatter += ' --pattern "./spec/**/*_spec.rb"'
|
21
|
+
rspec_args = formatter
|
22
|
+
end
|
23
|
+
sh "rspec #{rspec_args}"
|
24
|
+
end
|
25
|
+
|
26
|
+
task default: %i[rubocop test_all]
|
data/VERDACCIO.md
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# Basic verdaccio notes
|
2
|
+
|
3
|
+
## Local install verdaccio
|
4
|
+
|
5
|
+
```
|
6
|
+
npm install -g verdaccio
|
7
|
+
```
|
8
|
+
|
9
|
+
## Optionally change listen port
|
10
|
+
|
11
|
+
```
|
12
|
+
listen:
|
13
|
+
- 0.0.0.0:4873
|
14
|
+
```
|
15
|
+
|
16
|
+
to your config
|
17
|
+
|
18
|
+
## Adduser/login
|
19
|
+
|
20
|
+
```
|
21
|
+
npm adduser --registry http://127.0.0.1:4873
|
22
|
+
```
|
23
|
+
|
24
|
+
## Start publishing (from a folder containing a package.json)
|
25
|
+
|
26
|
+
```
|
27
|
+
npm publish --registry http://127.0.0.1:4873
|
28
|
+
```
|
29
|
+
|
30
|
+
## View packages
|
31
|
+
|
32
|
+
```
|
33
|
+
npm view --json com.dragonbox.simple-build --registry http://127.0.0.1:4873
|
34
|
+
```
|
data/exe/migrate.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
{
|
2
|
+
"wwtk.SimpleBuild": "com.dragonbox.simple-build",
|
3
|
+
"wwtk.Authenticator": "com.dragonbox.authenticator",
|
4
|
+
"wwtk.CrashReporter": "com.dragonbox.crash-reporter",
|
5
|
+
"DragonBox.Net": "com.dragonbox.net",
|
6
|
+
"wwtk.OAuth": "com.dragonbox.oauth",
|
7
|
+
"wwtk.OAuthAsync": "com.dragonbox.oauth-async",
|
8
|
+
"wwtk.OAuthRx": "com.dragonbox.oauth-rx",
|
9
|
+
"wwtk.OAuthenticator": "com.dragonbox.oauthenticator",
|
10
|
+
"wwtk.Core": "com.dragonbox.core",
|
11
|
+
"GoogleExternalDependencyManagerForUnity": "com.google.external-dependency-manager",
|
12
|
+
"GooglePlayReview": "com.google.play.review",
|
13
|
+
"wwtk.Glocalization": "com.dragonbox.glocalization",
|
14
|
+
"wwtk.Glocalization.TMProFontPlugin": "com.dragonbox.glocalization.tmpro-font-plugin",
|
15
|
+
"wwtk.Fonts": "com.dragonbox.fonts",
|
16
|
+
"wwtk.MathExpressionFormatter": "com.dragonbox.math-expression-formatter"
|
17
|
+
}
|
@@ -0,0 +1,151 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'uplift'
|
4
|
+
require_relative 'unity'
|
5
|
+
require 'fileutils'
|
6
|
+
|
7
|
+
module UpmSupport
|
8
|
+
class Actions
|
9
|
+
def self.migrate_dependencies_to_upm(dir, migrations, registry_uri, force_upgrade: false)
|
10
|
+
up = UnityProject.new(dir)
|
11
|
+
raise "Unity Project to migrate is too old (#{up.version}), some features might break. Consider upgrading to at least #{up.minimum_supported} first" unless up.is_minimum_supported?
|
12
|
+
|
13
|
+
unless File.exist?("#{dir}/Upfile.lock")
|
14
|
+
puts "No Upfile.lock here. Exiting"
|
15
|
+
exit(-1)
|
16
|
+
end
|
17
|
+
upfile_lock = UpfileLock.new("#{dir}/Upfile.lock")
|
18
|
+
upm_packages = UPMPackages.new("#{dir}/Packages/manifest.json")
|
19
|
+
|
20
|
+
changed = false
|
21
|
+
registry = UpmRegistry.new(registry_uri)
|
22
|
+
upfile_lock.dependencies.each do |uplift_package, version|
|
23
|
+
next unless migrations.keys.include? uplift_package
|
24
|
+
|
25
|
+
upm_package = migrations[uplift_package]
|
26
|
+
|
27
|
+
replacement_version = nil
|
28
|
+
if force_upgrade
|
29
|
+
puts "Trying to upgrade #{uplift_package} to the latest UPM one"
|
30
|
+
|
31
|
+
candidate_versions = registry.versions(upm_package)
|
32
|
+
if candidate_versions.empty?
|
33
|
+
puts 'None found'
|
34
|
+
next
|
35
|
+
end
|
36
|
+
replacement_version = candidate_versions.last
|
37
|
+
else
|
38
|
+
puts "checking if #{uplift_package}@#{version} has an equivalent UPM one"
|
39
|
+
|
40
|
+
versions = registry.versions(upm_package)
|
41
|
+
candidate_versions = versions.filter { |v| v == version || v =~ /#{version}-exp./ }
|
42
|
+
if candidate_versions.empty?
|
43
|
+
puts 'None found'
|
44
|
+
next
|
45
|
+
end
|
46
|
+
replacement_version = if candidate_versions.include? version
|
47
|
+
version
|
48
|
+
else
|
49
|
+
candidate_versions.last # assume in order of releases....
|
50
|
+
end
|
51
|
+
end
|
52
|
+
puts "Replacing #{uplift_package}@#{version} with #{upm_package}@#{replacement_version}"
|
53
|
+
upfile_lock.remove_dependency(uplift_package, version)
|
54
|
+
upm_packages.add_dependency(upm_package, replacement_version)
|
55
|
+
changed = true
|
56
|
+
end
|
57
|
+
return unless changed
|
58
|
+
|
59
|
+
dragonbox_registry_present = upm_packages.scoped_registries.map { |r| r['url'] }.include? registry_uri
|
60
|
+
upm_packages.add_scoped_registry('DragonBox', registry_uri, ['com.dragonbox']) unless dragonbox_registry_present
|
61
|
+
|
62
|
+
upm_packages.save
|
63
|
+
upfile_lock.save
|
64
|
+
command = "git diff #{upfile_lock.path} #{upm_packages.path}"
|
65
|
+
puts `#{command}`
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.remove_deleted_uplift_assets(dir)
|
69
|
+
upbring_path = "#{dir}/UPackages/Upbring.xml"
|
70
|
+
unless File.exist? upbring_path
|
71
|
+
puts "No Uplift setup to deal with"
|
72
|
+
return
|
73
|
+
end
|
74
|
+
upbring = Upbring.new(upbring_path)
|
75
|
+
|
76
|
+
upfile_lock_path = "#{dir}/Upfile.lock"
|
77
|
+
upfile_lock = nil
|
78
|
+
upfile_lock = UpfileLock.new(upfile_lock_path) if File.exist?(upfile_lock_path)
|
79
|
+
|
80
|
+
upbring.installed_packages.each do |ip|
|
81
|
+
if upfile_lock
|
82
|
+
puts "Searching for #{ip.name} #{ip.version}"
|
83
|
+
dependency = upfile_lock.dependencies[ip.name]
|
84
|
+
if dependency == ip.version
|
85
|
+
puts "Dependency #{ip.name}@#{ip.version} still in Upfile.lock"
|
86
|
+
next
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
puts "Dependency #{ip.name}@#{ip.version} not in Upfile.lock anymore, cleaning up"
|
91
|
+
is_with_guids = ip.install_specs.reject { |is| is.guid.nil? }
|
92
|
+
is_with_guids.each do |is|
|
93
|
+
# search for asset
|
94
|
+
is_guid = is.guid
|
95
|
+
command = "grep -r \"^guid: #{is_guid}\" '#{dir}/Assets' --include '*.meta' | cut -d ':' -f 1"
|
96
|
+
# FIXME you can have multiple results here, and you should exclude those that are in git...
|
97
|
+
metapath = `#{command}`.strip.split("\n").first
|
98
|
+
|
99
|
+
# if found
|
100
|
+
if metapath != ""
|
101
|
+
path = File.join(File.dirname(metapath),File.basename(metapath, '.meta'))
|
102
|
+
[path, metapath].each do |file|
|
103
|
+
if !File.exist?(file)
|
104
|
+
puts "ERROR: file #{file} doesn't exist"
|
105
|
+
next
|
106
|
+
end
|
107
|
+
puts "Deleting #{file}"
|
108
|
+
File.delete(file)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
upbring.remove_package(ip.name)
|
113
|
+
upbring.save
|
114
|
+
end
|
115
|
+
|
116
|
+
is_with_paths = ip.install_specs.reject { |is| is.path.nil? }
|
117
|
+
is_with_paths.each do |is|
|
118
|
+
path = "#{dir}/#{is.path}"
|
119
|
+
if Dir.exist? path
|
120
|
+
puts "Deleting #{path} recursively"
|
121
|
+
FileUtils.rm_r path
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
self.clean_empty_dirs
|
126
|
+
end
|
127
|
+
|
128
|
+
|
129
|
+
def self.clean_empty_dirs
|
130
|
+
empty_dirs = Dir.glob("Assets/**/*").filter{|f| Dir.exist?(f)}.select{|d| Dir.empty?(d) }
|
131
|
+
|
132
|
+
while empty_dirs.count > 0
|
133
|
+
empty_dirs.each{|empty_dir| Dir.rmdir(empty_dir)}
|
134
|
+
parent_empty_dirs = empty_dirs.map{|d| File.dirname(d)}.uniq
|
135
|
+
while true do
|
136
|
+
deleted = []
|
137
|
+
parent_empty_dirs.each do |dir|
|
138
|
+
metas = Dir.glob("#{dir}/*.meta")
|
139
|
+
meta_and_non_metas = metas.map{|meta| [meta, File.join(File.dirname(meta), File.basename(meta, ".meta"))] }
|
140
|
+
to_delete = meta_and_non_metas.select{|a| File.exist?(a[0]) and !File.exist?(a[1])}
|
141
|
+
deleted.concat(to_delete)
|
142
|
+
to_delete.each{|a| puts "Deleting #{a[0]}"; File.delete(a[0])}
|
143
|
+
end
|
144
|
+
break if deleted.count == 0
|
145
|
+
sleep 0.1 # give it some time to delete things
|
146
|
+
end
|
147
|
+
empty_dirs = parent_empty_dirs.select{|d| Dir.glob("#{d}/**").count == 0}.uniq
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'English'
|
5
|
+
require 'yaml'
|
6
|
+
|
7
|
+
module UpmSupport
|
8
|
+
class UPMPackages
|
9
|
+
attr_reader :path
|
10
|
+
|
11
|
+
def initialize(path)
|
12
|
+
@path = path
|
13
|
+
@content = JSON.parse(File.read(path))
|
14
|
+
end
|
15
|
+
|
16
|
+
def scoped_registries
|
17
|
+
@content['scopedRegistries'] = [] unless @content['scopedRegistries']
|
18
|
+
@content['scopedRegistries'] || []
|
19
|
+
end
|
20
|
+
|
21
|
+
def add_scoped_registry(name, uri, scopes)
|
22
|
+
@content['scopedRegistries'] = [] unless @content['scopedRegistries']
|
23
|
+
@content['scopedRegistries'] <<
|
24
|
+
{
|
25
|
+
'name' => name,
|
26
|
+
'url' => uri,
|
27
|
+
'scopes' => scopes
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
def dependencies
|
32
|
+
@content['dependencies']
|
33
|
+
end
|
34
|
+
|
35
|
+
def add_dependency(name, version)
|
36
|
+
old_deps = dependencies
|
37
|
+
@content['dependencies'] = { name => version }.merge(old_deps)
|
38
|
+
end
|
39
|
+
|
40
|
+
def save
|
41
|
+
File.write(@path, JSON.pretty_generate(@content))
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class UpmRegistry
|
46
|
+
def initialize(uri)
|
47
|
+
@registry_uri = uri
|
48
|
+
end
|
49
|
+
|
50
|
+
def exist?(package, version)
|
51
|
+
command = "npm view --json #{package}@#{version} --registry '#{@registry_uri}'"
|
52
|
+
output = `#{command} 2> /dev/null`
|
53
|
+
if $CHILD_STATUS.exitstatus.positive?
|
54
|
+
false
|
55
|
+
else
|
56
|
+
output.length.positive?
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def versions(package)
|
61
|
+
command = "npm view --json #{package} --registry '#{@registry_uri}'"
|
62
|
+
output = `#{command} 2> /dev/null`
|
63
|
+
if $CHILD_STATUS.exitstatus.positive?
|
64
|
+
[]
|
65
|
+
else
|
66
|
+
JSON.parse(output)['versions']
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
class UnityProject
|
72
|
+
def initialize(dir)
|
73
|
+
@dir = dir
|
74
|
+
end
|
75
|
+
|
76
|
+
def version
|
77
|
+
Gem::Version.new(YAML.safe_load(File.read("#{@dir}/ProjectSettings/ProjectVersion.txt"))['m_EditorVersion'])
|
78
|
+
end
|
79
|
+
|
80
|
+
def minimum_supported
|
81
|
+
Gem::Version.new("2019.4.9f1")
|
82
|
+
end
|
83
|
+
|
84
|
+
def is_minimum_supported?
|
85
|
+
minimum_supported <= version
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'rexml/document'
|
5
|
+
|
6
|
+
module UpmSupport
|
7
|
+
class UpfileLock
|
8
|
+
attr_reader :path
|
9
|
+
|
10
|
+
def initialize(path)
|
11
|
+
@path = path
|
12
|
+
@content = File.read(path).split("\n")
|
13
|
+
end
|
14
|
+
|
15
|
+
def dependencies
|
16
|
+
idx = @content.index('# SOLVED DEPENDENCIES')
|
17
|
+
@content[(idx + 1)..].grep(/^[A-z]/).to_h do |l|
|
18
|
+
m = l.match(/(.*) \((.*)\)/)
|
19
|
+
[m[1], m[2]]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def remove_dependency(name, version)
|
24
|
+
idx = @content.index('# SOLVED DEPENDENCIES')
|
25
|
+
@content = @content.reject.each_with_index { |l, ix| ix > idx and l =~ /^#{name} \(#{version}\)/ }
|
26
|
+
end
|
27
|
+
|
28
|
+
def save
|
29
|
+
File.write(@path, @content.join("\n"))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class InstallSpec
|
34
|
+
attr_reader :type, :path, :guid
|
35
|
+
|
36
|
+
def initialize(type: nil, path: nil, guid: nil)
|
37
|
+
@type = type
|
38
|
+
@path = path
|
39
|
+
@guid = guid
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class InstalledPackage
|
44
|
+
attr_reader :name, :version, :install_specs
|
45
|
+
|
46
|
+
def initialize(name, version, install_specs)
|
47
|
+
@name = name
|
48
|
+
@version = version
|
49
|
+
@install_specs = install_specs
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class Upbring
|
54
|
+
include REXML
|
55
|
+
|
56
|
+
attr_reader :path
|
57
|
+
|
58
|
+
def initialize(path)
|
59
|
+
@path = path
|
60
|
+
@doc = File.open(path) do |f|
|
61
|
+
REXML::Document.new f
|
62
|
+
rescue => e
|
63
|
+
raise "Unable to open your Upbring file in #{@path}. You might need to clean your project, #{e}"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def installed_packages
|
68
|
+
install_specs = XPath.match(@doc.root, '/Upbring/InstalledPackage').map do |ip|
|
69
|
+
name = ip['Name']
|
70
|
+
version = ip['Version']
|
71
|
+
install_specs = XPath.match(ip, './Install').map do |e|
|
72
|
+
InstallSpec.new(type: e['Type'], path: e['Path'], guid: e['Guid'])
|
73
|
+
end
|
74
|
+
InstalledPackage.new(name, version, install_specs)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def installed_package(name)
|
79
|
+
installed_packages.select { |ip| ip.name == name }.first
|
80
|
+
end
|
81
|
+
|
82
|
+
def remove_package(name)
|
83
|
+
upbring_elt = XPath.match(@doc.root, '/Upbring')
|
84
|
+
elt_to_remove = XPath.match(upbring_elt, "./InstalledPackage[@Name='#{name}']")
|
85
|
+
return nil unless elt_to_remove.count.positive?
|
86
|
+
|
87
|
+
upbring_elt.first.delete(elt_to_remove.first)
|
88
|
+
end
|
89
|
+
|
90
|
+
def save
|
91
|
+
File.open(@path, 'w') do |f|
|
92
|
+
@doc.write(f)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
data/lib/upm_support.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'upm_support/uplift'
|
4
|
+
require_relative 'upm_support/unity'
|
5
|
+
require_relative 'upm_support/actions'
|
6
|
+
|
7
|
+
module UpmSupport
|
8
|
+
class Runner
|
9
|
+
def self.run(args)
|
10
|
+
actions = %w[to_upm clean_upbring]
|
11
|
+
action = args[0]
|
12
|
+
|
13
|
+
migrations_file_path = File.join(File.dirname(__FILE__) + "/assets/migrations.json")
|
14
|
+
|
15
|
+
migrations = JSON.parse(File.read(migrations_file_path))
|
16
|
+
|
17
|
+
registry_uri = ENV.fetch('UPM_REGISTRY', 'https://upm.dragonbox.com')
|
18
|
+
|
19
|
+
puts "Migrating action #{action}"
|
20
|
+
|
21
|
+
case action
|
22
|
+
when 'to_upm'
|
23
|
+
Actions.migrate_dependencies_to_upm('.', migrations, registry_uri, force_upgrade: args.include?("--force-upgrade"))
|
24
|
+
when 'clean_upbring'
|
25
|
+
Actions.remove_deleted_uplift_assets('.')
|
26
|
+
else
|
27
|
+
raise "Unknown action #{action}. Use any of #{actions.join(',')}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/upm_support.gemspec
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require 'upm_support/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = 'upm_support'
|
9
|
+
spec.version = UpmSupport::VERSION
|
10
|
+
spec.authors = ['Jerome Lacoste']
|
11
|
+
spec.email = 'jeromel@kahoot.com'
|
12
|
+
|
13
|
+
spec.required_ruby_version = '>= 2.7.4'
|
14
|
+
|
15
|
+
spec.summary = 'UpmSupport'
|
16
|
+
spec.description = UpmSupport::DESCRIPTION
|
17
|
+
|
18
|
+
spec.homepage = 'https://bitbucket.org/WeWantToKnow/upm_migration'
|
19
|
+
spec.license = 'Proprietary'
|
20
|
+
|
21
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
22
|
+
f.match(%r{^(test|spec|features)/})
|
23
|
+
end
|
24
|
+
spec.bindir = 'exe'
|
25
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
26
|
+
spec.require_paths = ['lib']
|
27
|
+
|
28
|
+
spec.add_dependency 'rexml' # rexml was unbundled from the stdlib in ruby 3
|
29
|
+
# Development only
|
30
|
+
spec.add_development_dependency 'bundler', '~> 2.0'
|
31
|
+
spec.add_development_dependency 'rake', '~> 13.0'
|
32
|
+
spec.add_development_dependency 'rspec', '~> 3.11.0'
|
33
|
+
spec.add_development_dependency 'rspec_junit_formatter', '~> 0.5.1'
|
34
|
+
spec.add_development_dependency 'rubocop', '~> 1.27'
|
35
|
+
spec.add_development_dependency 'rubocop-rake', '~> 0.6.0'
|
36
|
+
spec.add_development_dependency 'rubocop-rspec', '~> 2.10.0'
|
37
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
38
|
+
end
|
metadata
ADDED
@@ -0,0 +1,172 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: upm_support
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jerome Lacoste
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-11-07 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rexml
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '13.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '13.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 3.11.0
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 3.11.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec_junit_formatter
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.5.1
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.5.1
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rubocop
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1.27'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '1.27'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rubocop-rake
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 0.6.0
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 0.6.0
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rubocop-rspec
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 2.10.0
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 2.10.0
|
125
|
+
description: Provides tools for supporting UPM.
|
126
|
+
email: jeromel@kahoot.com
|
127
|
+
executables:
|
128
|
+
- migrate.rb
|
129
|
+
extensions: []
|
130
|
+
extra_rdoc_files: []
|
131
|
+
files:
|
132
|
+
- ".gitignore"
|
133
|
+
- ".rubocop.yml"
|
134
|
+
- DEVELOPPING.md
|
135
|
+
- Gemfile
|
136
|
+
- Gemfile.lock
|
137
|
+
- MIGRATION.md
|
138
|
+
- Rakefile
|
139
|
+
- VERDACCIO.md
|
140
|
+
- exe/migrate.rb
|
141
|
+
- lib/assets/migrations.json
|
142
|
+
- lib/upm_support.rb
|
143
|
+
- lib/upm_support/actions.rb
|
144
|
+
- lib/upm_support/unity.rb
|
145
|
+
- lib/upm_support/uplift.rb
|
146
|
+
- lib/upm_support/version.rb
|
147
|
+
- upm_support.gemspec
|
148
|
+
homepage: https://bitbucket.org/WeWantToKnow/upm_migration
|
149
|
+
licenses:
|
150
|
+
- Proprietary
|
151
|
+
metadata:
|
152
|
+
rubygems_mfa_required: 'true'
|
153
|
+
post_install_message:
|
154
|
+
rdoc_options: []
|
155
|
+
require_paths:
|
156
|
+
- lib
|
157
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
158
|
+
requirements:
|
159
|
+
- - ">="
|
160
|
+
- !ruby/object:Gem::Version
|
161
|
+
version: 2.7.4
|
162
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
requirements: []
|
168
|
+
rubygems_version: 3.1.6
|
169
|
+
signing_key:
|
170
|
+
specification_version: 4
|
171
|
+
summary: UpmSupport
|
172
|
+
test_files: []
|