upm_support 0.0.2

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: 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
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ ruby '2.7.4'
4
+ source 'https://rubygems.org'
5
+
6
+ gemspec
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,6 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require_relative '../lib/upm_support'
5
+
6
+ UpmSupport::Runner.run(ARGV)
@@ -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
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module UpmSupport
4
+ VERSION = '0.0.2'
5
+ DESCRIPTION = 'Provides tools for supporting UPM.'
6
+ end
@@ -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
@@ -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: []