uas2git 0.9.4 → 0.9.9

Sign up to get free protection for your applications and to get access to all the features.
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