uas2git 0.9.4 → 0.9.9

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
  SHA1:
3
- metadata.gz: b2b19bc2bc78262e8dc5261a3835e8c0268b944b
4
- data.tar.gz: bb591d0df72a7ff57184d20e1525e45cff0c7136
3
+ metadata.gz: 8302d5fed76cf87bdb9b56054a90258ff1113c69
4
+ data.tar.gz: 4189adf83d09fc9b1052c84d266570a7a9deecd4
5
5
  SHA512:
6
- metadata.gz: 657ad52b78256644bcfd3bf0cbf24f5703a35f3b0478b4ca002b911b477696152285d92d5b92338c62136f6f880463019f73a43f3986eb8fc442c3e476cee34d
7
- data.tar.gz: 9ed83b1077de6d7404ef44a9ac09c2e558fa6a17bae7d0b8b60dff46e2f55227033ea483c7837c4b0056a91c7a945657ebd059e2500dddeffad608b68faabde4
6
+ metadata.gz: 18f2bf2c2a83092d9d5654b67341b87b41d33cd309197e52b9ad1d74db3ad45ef694d01ffcd1ef6345ad44c14c1b322dc41bf3399a9c8695c183930fa81548cf
7
+ data.tar.gz: a5a86e132d479d2db4133bf280ea72005a0670748254a2cc518cb0239d683c5bdfe671ecd7daafd3b1b15fc0ce4d5afcef37b9ffc1df833461392fbe2bfb3a78
data/README.md CHANGED
@@ -11,11 +11,10 @@ A tool for migrating Unity Asset Server projects to git
11
11
  Usage: uas2git PROJECT_NAME [options]
12
12
 
13
13
  Specific options:
14
- -H, --host NAME Unity Asset Server host
15
- -u, --username NAME Crendential for Unity Asset Server
16
- -p, --password PASSWD
14
+ -h HOSTNAME Unity Asset Server host (default: "localhost")
15
+ -U NAME Unity Asset Server user name (default: "admin")
17
16
 
18
- -h, --help Show this message
17
+ --help Show this message
19
18
 
20
19
  ## Contributing
21
20
 
data/bin/uas2git CHANGED
@@ -3,5 +3,5 @@
3
3
  require 'rubygems'
4
4
  require 'uas2git'
5
5
 
6
- migration = Uas2Git::Migration.new(ARGV)
7
- migration.run!
6
+ main = Uas2Git::Main.new(ARGV)
7
+ main.run!
data/lib/uas2git.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'uas2git/version'
2
2
  require 'uas2git/lo_reader'
3
- require 'uas2git/migration'
3
+ require 'uas2git/main'
4
+ require 'uas2git/migrator'
4
5
  require 'uas2git/uas'
@@ -0,0 +1,90 @@
1
+ require 'highline/import'
2
+ require 'optparse'
3
+ require 'rugged'
4
+ require 'progress'
5
+
6
+ module Uas2Git
7
+ class Main
8
+ def initialize(args)
9
+ @options = parse(args)
10
+
11
+ show_help_message('Missing PROJECT_NAME parameter') if args.empty?
12
+ show_help_message('Too many arguments') if args.size > 1
13
+
14
+ @project_name = args.first
15
+
16
+ begin
17
+ show_help_message('The repository must be empty') unless Rugged::Repository.new('.').empty?
18
+ rescue
19
+ end
20
+
21
+ end
22
+
23
+ def run!
24
+ password = ask('Enter password for ' + @options[:username] + '@' + @options[:host] + ': ') { |q| q.echo = false }
25
+
26
+ ActiveRecord::Base.establish_connection(
27
+ :adapter => 'postgresql',
28
+ :host => @options[:host],
29
+ :port => '10733',
30
+ :username => @options[:username],
31
+ :password => password,
32
+ :database => @project_name
33
+ )
34
+
35
+ # Initialize a git repository
36
+ repo = Progress.start('Initializing a git repository', 1) do
37
+ Progress.step do
38
+ Rugged::Repository.init_at('.')
39
+ end
40
+ end
41
+
42
+ Migrator.new(repo).migrate!
43
+
44
+ # Checking out the working copy
45
+ Progress.start('Checking out the work tree', 1) do
46
+ Progress.step do
47
+ repo.reset('HEAD', :hard)
48
+ end
49
+ end
50
+ end
51
+
52
+ def parse(args)
53
+ # Set up reasonable defaults for options.
54
+ options = {}
55
+ options[:host] = 'localhost'
56
+ options[:username] = 'admin'
57
+
58
+ @opts = OptionParser.new do |opts|
59
+ opts.banner = 'Usage: uas2git PROJECT_NAME [options]'
60
+
61
+ opts.separator ''
62
+ opts.separator 'Specific options:'
63
+
64
+ opts.on('-h HOSTNAME', 'Unity Asset Server host (default: "localhost")') do |host|
65
+ options[:host] = host
66
+ end
67
+
68
+ opts.on('-U NAME', 'Unity Asset Server user name (default: "admin")') do |username|
69
+ options[:username] = username
70
+ end
71
+
72
+ opts.separator ''
73
+
74
+ opts.on_tail('--help', 'Show this message') do
75
+ puts opts
76
+ exit
77
+ end
78
+ end
79
+
80
+ @opts.parse! args
81
+ options
82
+ end
83
+
84
+ def show_help_message(msg)
85
+ puts "Error starting script: #{msg}\n\n"
86
+ puts @opts.help
87
+ exit
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,128 @@
1
+ require 'rugged'
2
+ require 'progress'
3
+
4
+ module Uas2Git
5
+ class Migrator
6
+ def initialize(repo)
7
+ @repo = repo
8
+ end
9
+
10
+ def migrate!
11
+ # Importing changesets
12
+ @paths = {}
13
+ @index = Rugged::Index.new
14
+
15
+ Progress.start('Importing ' + Uas2Git::Uas::Model::AssetVersion.count.to_s + ' asset versions in ' + Uas2Git::Uas::Model::Changeset.count.to_s + ' changesets', Uas2Git::Uas::Model::AssetVersion.count * 3) do
16
+ Uas2Git::Uas::Model::Changeset.find_each do |changeset|
17
+ import_changeset(changeset)
18
+ end
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def import_changeset(changeset)
25
+ old_paths = @paths.clone
26
+ asset_versions = changeset.asset_versions.includes(:parent, :asset, :type)
27
+
28
+ asset_versions.find_each do |v|
29
+ Progress.step do
30
+ if v.parent then
31
+ path = @paths[v.parent.serial] + '/' + v.name
32
+ elsif %w(00000000000000001000000000000000 ffffffffffffffffffffffffffffffff).include?(v.asset.guid_hex) then
33
+ path = v.name
34
+ else
35
+ path = 'ProjectSettings/' + v.name
36
+ end
37
+
38
+ @paths[v.asset.serial] = path
39
+ end
40
+ end
41
+
42
+ asset_versions.find_each do |v|
43
+ Progress.step do
44
+ # Has moved or deleted?
45
+ if old_paths.has_key?(v.asset.serial) && old_paths[v.asset.serial] != @paths[v.asset.serial] then
46
+ old_path = old_paths[v.asset.serial]
47
+
48
+ if v.type.description == 'dir' then
49
+ @index.remove(old_path + '.meta')
50
+
51
+ old_paths.select { |asset_serial, path| path.start_with?(old_path + '/') }.each { |asset_serial, path|
52
+ old_paths[asset_serial] = @paths[v.asset.serial] + path[old_path.length .. -1]
53
+ }
54
+
55
+ @paths.select { |asset_serial, path| path.start_with?(old_path + '/') }.each { |asset_serial, path|
56
+ @paths[asset_serial] = @paths[v.asset.serial] + path[old_path.length .. -1]
57
+ }
58
+
59
+ @index.remove_all(old_path + '/*') { |matched, pathspec|
60
+ entry = @index[matched]
61
+ entry[:path] = @paths[v.asset.serial] + entry[:path][old_path.length .. -1]
62
+ @index << entry
63
+
64
+ true
65
+ }
66
+ else
67
+ v.contents.find_each do |c|
68
+ @index.remove(old_path) if c.tag == 'asset'
69
+ @index.remove(old_path + '.meta') if c.tag == 'asset.meta'
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+
76
+ asset_versions.find_each do |v|
77
+ Progress.step do
78
+ if v.type.description == 'dir' then
79
+ if v.parent then
80
+ @index << { path: @paths[v.asset.serial] + '.meta', oid: dir_meta_oid(v.asset), mode: 0100644 }
81
+ end
82
+ else
83
+ v.contents.each do |c|
84
+ oid = LOReader.new(v.class.connection.raw_connection).open(c.stream) { |lo| Rugged::Blob.from_chunks(@repo, lo) }
85
+
86
+ @index << { path: @paths[v.asset.serial], oid: oid, mode: 0100644 } if c.tag == 'asset'
87
+ @index << { path: @paths[v.asset.serial] + '.meta', oid: oid, mode: 0100644 } if c.tag == 'asset.meta'
88
+ end
89
+ end
90
+ end
91
+ end
92
+
93
+ # Exclude trashes
94
+ tree_builder = Rugged::Tree::Builder.new(@repo.lookup(@index.write_tree(@repo)))
95
+ tree_builder.remove('Trash') if tree_builder['Trash']
96
+ tree = tree_builder.write(@repo)
97
+
98
+ author = {
99
+ :name => changeset.creator.username,
100
+ :email => '',
101
+ :time => changeset.commit_time.nil? ? Time.now : changeset.commit_time
102
+ }
103
+
104
+ Rugged::Commit.create(@repo, {
105
+ :tree => tree,
106
+ :author => author,
107
+ :committer => author,
108
+ :message => changeset.description,
109
+ :parents => @repo.empty? ? [] : [ @repo.head.target ].compact,
110
+ :update_ref => 'HEAD'
111
+ })
112
+ end
113
+
114
+ def dir_meta_oid(asset)
115
+ @dir_meta_oids ||= {}
116
+
117
+ meta = <<EOF
118
+ fileFormatVersion: 2
119
+ guid: #{asset.guid_hex}
120
+ folderAsset: yes
121
+ DefaultImporter:
122
+ userData:\s
123
+ EOF
124
+
125
+ @dir_meta_oids[asset.serial] = @repo.write(meta, :blob)
126
+ end
127
+ end
128
+ end
data/lib/uas2git/uas.rb CHANGED
@@ -9,11 +9,14 @@ module Uas2Git
9
9
  self.primary_key = 'serial'
10
10
 
11
11
  has_many :versions, :class_name => 'AssetVersion', :primary_key => 'serial', :foreign_key => 'asset'
12
+
13
+ def guid_hex
14
+ [self.guid].pack('B*').unpack("H*").join
15
+ end
12
16
  end
13
17
 
14
18
  class AssetContents < ActiveRecord::Base
15
19
  self.table_name = 'assetcontents'
16
- self.primary_key = [ 'assetversion', 'tag' ]
17
20
 
18
21
  belongs_to :asset_version, :class_name => 'AssetVersion', :primary_key => 'serial', :foreign_key => 'assetversion'
19
22
  end
@@ -1,3 +1,3 @@
1
1
  module UAS2Git
2
- VERSION = '0.9.4'
2
+ VERSION = '0.9.9'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: uas2git
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.4
4
+ version: 0.9.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Toru Nayuki
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-13 00:00:00.000000000 Z
11
+ date: 2014-02-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -139,7 +139,8 @@ files:
139
139
  - bin/uas2git
140
140
  - lib/uas2git.rb
141
141
  - lib/uas2git/lo_reader.rb
142
- - lib/uas2git/migration.rb
142
+ - lib/uas2git/main.rb
143
+ - lib/uas2git/migrator.rb
143
144
  - lib/uas2git/uas.rb
144
145
  - lib/uas2git/version.rb
145
146
  - uas2git.gemspec
@@ -1,215 +0,0 @@
1
- require 'highline/import'
2
- require 'optparse'
3
- require 'rugged'
4
- require 'progress'
5
-
6
- module Uas2Git
7
- class Migration
8
- def initialize(args)
9
- @options = parse(args)
10
-
11
- show_help_message('Missing PROJECT_NAME parameter') if args.empty?
12
- show_help_message('Too many arguments') if args.size > 1
13
-
14
- @project_name = args.first
15
-
16
- begin
17
- show_help_message('The repository must be empty') unless Rugged::Repository.new('.').empty?
18
- rescue
19
- end
20
-
21
- if @options[:password].nil? then
22
- @options[:password] = ask('Enter password for ' + @options[:username] + '@' + @options[:host] + ': ') { |q| q.echo = false }
23
- end
24
- end
25
-
26
- def run!
27
- ActiveRecord::Base.establish_connection(
28
- :adapter => 'postgresql',
29
- :host => @options[:host],
30
- :port => '10733',
31
- :username => @options[:username],
32
- :password => @options[:password],
33
- :database => @project_name
34
- )
35
-
36
- # Initialize a git repository
37
- repo = Progress.start('Initializing a git repository', 1) do
38
- Progress.step do
39
- Rugged::Repository.init_at('.')
40
- end
41
- end
42
-
43
- # Import files
44
- oids = {}
45
- meta_oids = {}
46
-
47
- asset_versions = Uas2Git::Uas::Model::AssetVersion.joins(:type).where('assettype.description <> \'dir\'')
48
- Progress.start('Importing ' + asset_versions.count.to_s + ' files', asset_versions.count) do
49
- asset_versions.find_each do |asset_version|
50
- Progress.step do
51
- asset_version.contents.each do |contents|
52
- oid = LOReader.new(asset_version.class.connection.raw_connection).open(contents.stream) do |lo|
53
- Rugged::Blob.from_chunks(repo, lo)
54
- end
55
-
56
- if contents.tag == 'asset' then
57
- oids[asset_version.asset.serial] = {} if oids[asset_version.asset.serial].nil?
58
- oids[asset_version.asset.serial][asset_version.revision] = oid
59
- elsif contents.tag == 'asset.meta' then
60
- meta_oids[asset_version.asset.serial] = {} if meta_oids[asset_version.asset.serial].nil?
61
- meta_oids[asset_version.asset.serial][asset_version.revision] = oid
62
- end
63
- end
64
- end
65
- end
66
- end
67
-
68
- # Precalculating directory paths from changesets
69
- dirs = {}
70
- prev_changeset = nil
71
-
72
- Progress.start('Precalculating directory paths', Uas2Git::Uas::Model::Changeset.count) do
73
- Uas2Git::Uas::Model::Changeset.find_each do |changeset|
74
- Progress.step do
75
- dirs[changeset.serial] = prev_changeset ? dirs[prev_changeset.serial].clone : {}
76
-
77
- changeset.asset_versions.joins(:type).where('assettype.description = \'dir\'').find_each do |asset_version|
78
- if asset_version.parent then
79
- dirs[changeset.serial][asset_version.asset.serial] = dirs[changeset.serial][asset_version.parent.serial] + '/' + asset_version.name
80
- else
81
- dirs[changeset.serial][asset_version.asset.serial] = asset_version.name
82
- end
83
- end
84
-
85
- prev_changeset = changeset
86
- end
87
- end
88
- end
89
-
90
- # Importing changesets
91
- Progress.start('Importing ' + Uas2Git::Uas::Model::Changeset.count.to_s + ' changesets', Uas2Git::Uas::Model::Changeset.count) do
92
- Uas2Git::Uas::Model::Changeset.find_each do |changeset|
93
- Progress.step do
94
- index = Rugged::Index.new
95
-
96
- Uas2Git::Uas::Model::AssetVersion.joins(:type).where('assettype.description <> \'dir\'').where(
97
- 'created_in <= :c AND assetversion.serial IN (SELECT assetversion FROM changesetcontents WHERE changesetcontents.changeset <= :c) AND revision = (SELECT MAX(revision) FROM assetversion AV2 WHERE AV2.asset = assetversion.asset AND AV2.created_in <= :c)',
98
- { :c => changeset.serial }
99
- ).find_each do |asset_version|
100
- if asset_version.parent then
101
- path = dirs[changeset.serial][asset_version.parent.serial] + '/' + asset_version.name
102
- else
103
- path = 'ProjectSettings/' + asset_version.name
104
- end
105
-
106
- if !path.start_with?('Trash/') then
107
- index.add(:path => path, :oid => oids[asset_version.asset.serial][asset_version.revision], :mode => 0100644)
108
- if meta_oids.has_key?(asset_version.asset.serial) then
109
- index.add(:path => path + '.meta', :oid => meta_oids[asset_version.asset.serial][asset_version.revision], :mode => 0100644)
110
- end
111
- end
112
- end
113
-
114
- Uas2Git::Uas::Model::AssetVersion.joins(:type).where('assettype.description = \'dir\'').where(
115
- 'created_in <= :c AND assetversion.serial IN (SELECT assetversion FROM changesetcontents WHERE changesetcontents.changeset <= :c) AND revision = (SELECT MAX(revision) FROM assetversion AV2 WHERE AV2.asset = assetversion.asset AND AV2.created_in <= :c)',
116
- { :c => changeset.serial }
117
- ).find_each do |asset_version|
118
-
119
- next if asset_version.parent.nil?
120
-
121
- path = dirs[changeset.serial][asset_version.parent.serial] + '/' + asset_version.name
122
-
123
- next if path.start_with?('Trash/')
124
-
125
- index.add(
126
- :path => path + '.meta',
127
- :oid => repo.write(generate_directory_meta(asset_version.asset), :blob),
128
- :mode => 0100644
129
- )
130
- end
131
-
132
- author = {
133
- :name => changeset.creator.username,
134
- :email => '',
135
- :time => changeset.commit_time.nil? ? Time.now : changeset.commit_time
136
- }
137
-
138
- Rugged::Commit.create(repo, {
139
- :tree => index.write_tree(repo),
140
- :author => author,
141
- :committer => author,
142
- :message => changeset.description,
143
- :parents => repo.empty? ? [] : [ repo.head.target ].compact,
144
- :update_ref => 'HEAD'
145
- })
146
- end
147
- end
148
- end
149
-
150
- # Checking out the working copy
151
- Progress.start('Checking out the work tree', 1) do
152
- Progress.step do
153
- repo.reset('HEAD', :hard)
154
- end
155
- end
156
- end
157
-
158
- def parse(args)
159
- # Set up reasonable defaults for options.
160
- options = {}
161
- options[:host] = 'localhost'
162
- options[:username] = 'admin'
163
- options[:password] = nil
164
-
165
- @opts = OptionParser.new do |opts|
166
- opts.banner = 'Usage: uas2git PROJECT_NAME [options]'
167
-
168
- opts.separator ''
169
- opts.separator 'Specific options:'
170
-
171
- opts.on('-H', '--host NAME', 'Unity Asset Server host') do |host|
172
- options[:host] = host
173
- end
174
-
175
- opts.on('-u', '--username NAME', 'Crendential for Unity Asset Server') do |username|
176
- options[:username] = username
177
- end
178
-
179
- opts.on('-p', '--password PASSWD') do |password|
180
- options[:password] = password
181
- end
182
-
183
- opts.separator ''
184
-
185
- # No argument, shows at tail. This will print an options summary.
186
- # Try it and see!
187
- opts.on_tail('-h', '--help', 'Show this message') do
188
- puts opts
189
- exit
190
- end
191
- end
192
-
193
- @opts.parse! args
194
- options
195
- end
196
-
197
- def generate_directory_meta(asset)
198
- guid_string = [asset.guid].pack('B*').unpack("H*").join
199
-
200
- <<EOF
201
- fileFormatVersion: 2
202
- guid: #{guid_string}
203
- folderAsset: yes
204
- DefaultImporter:
205
- userData:\s
206
- EOF
207
- end
208
-
209
- def show_help_message(msg)
210
- puts "Error starting script: #{msg}\n\n"
211
- puts @opts.help
212
- exit
213
- end
214
- end
215
- end