p4_web_api 2014.2.0.pre1 → 2014.2.0.pre2
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 +4 -4
- data/lib/p4_web_api/version.rb +1 -1
- data/lib/p4_web_api.rb +154 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 069a887b3fabfbb41e4014f0351e9ad79e699ee9
|
4
|
+
data.tar.gz: 6fc582c57a30740878523f1265eade7bd6d24749
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a055d9ca2f41db3f61c9f8d3969d8b5ef506759671437d157eec182af6eb8ff18ff0567704203b4c4755b2deff87806cc2867ac98e0f161de93c52245f3c24e2
|
7
|
+
data.tar.gz: fa442bde271cf8387ac423ae2ba3fc9b8a88d38bd396478998990a8c1c74fb14f37065700acdf0e2276a89562143a25705038a8a85ba95bae5813de9382595da
|
data/lib/p4_web_api/version.rb
CHANGED
data/lib/p4_web_api.rb
CHANGED
@@ -54,6 +54,7 @@ module P4WebAPI
|
|
54
54
|
configure do
|
55
55
|
set(:p4, 'host' => 'localhost', 'port' => '1666')
|
56
56
|
set(:token_path, '/tmp/p4_web_api/tokens')
|
57
|
+
set(:workspace_folder, '/tmp/p4_web_api/workspaces')
|
57
58
|
|
58
59
|
set(:run_get_blacklist, %w(add change changelist clean copy cstat
|
59
60
|
delete diff edit flush have integ integrate
|
@@ -111,6 +112,65 @@ module P4WebAPI
|
|
111
112
|
P4Util.open(options, &block)
|
112
113
|
end
|
113
114
|
|
115
|
+
# Block helper to open a p4 handle with a temporary client workspace.
|
116
|
+
# The client workspace will map the series of depot path expressions
|
117
|
+
# directly into the client workspace.
|
118
|
+
#
|
119
|
+
# The depot_paths are generally expected to be complete file path
|
120
|
+
# expressions, e.g., '//depot/dir1/dir2/file'. They'll be mapped directly
|
121
|
+
# to the temporary working area: '//client/depot/dir/1/dir2/file'
|
122
|
+
#
|
123
|
+
# The block handler here will be called with the arguments (p4, root),
|
124
|
+
# where root is the temporary client's root directory.
|
125
|
+
def open_p4_temp_client(depot_paths, &block)
|
126
|
+
open_p4 do |p4|
|
127
|
+
name = (0...8).map { (65 + rand(26)).chr }.join
|
128
|
+
dir = init_temp_workspace_dir(name)
|
129
|
+
init_temp_client(p4, name, dir, depot_paths)
|
130
|
+
|
131
|
+
ex = nil
|
132
|
+
begin
|
133
|
+
block.call(p4, dir)
|
134
|
+
rescue StandardError => e
|
135
|
+
ex = e
|
136
|
+
end
|
137
|
+
|
138
|
+
delete_temp_client(p4, name, dir)
|
139
|
+
|
140
|
+
fail ex unless ex.nil?
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def init_temp_workspace_dir(name)
|
146
|
+
dir = File.join(settings.workspace_folder, name)
|
147
|
+
unless Dir.exist?(dir)
|
148
|
+
FileUtils.mkpath(dir)
|
149
|
+
FileUtils.chmod(0700, dir)
|
150
|
+
end
|
151
|
+
dir
|
152
|
+
end
|
153
|
+
|
154
|
+
def init_temp_client(p4, name, dir, depot_paths)
|
155
|
+
spec = p4.fetch_client
|
156
|
+
spec._root = dir
|
157
|
+
spec._client = name
|
158
|
+
spec._description = 'p4_web_api temp client'
|
159
|
+
|
160
|
+
spec._view = depot_paths.map do |path|
|
161
|
+
stripped = path.gsub(/^[\/]*/, '')
|
162
|
+
"\"//#{stripped}\" \"//#{name}/#{stripped}\""
|
163
|
+
end
|
164
|
+
|
165
|
+
p4.save_client(spec)
|
166
|
+
p4.client = name
|
167
|
+
|
168
|
+
p4.run_sync('//...')
|
169
|
+
end
|
170
|
+
|
171
|
+
def delete_temp_client(p4, name, dir)
|
172
|
+
p4.run_client('-d', '-f', name)
|
173
|
+
FileUtils.rmtree(dir)
|
114
174
|
end
|
115
175
|
|
116
176
|
error do
|
@@ -686,6 +746,100 @@ module P4WebAPI
|
|
686
746
|
''
|
687
747
|
end
|
688
748
|
|
749
|
+
# The print method uses the print command underneath to output file content.
|
750
|
+
#
|
751
|
+
# Unlike most of the other methods, this does not output application/json.
|
752
|
+
# If the type contains 'text' we set the Content-Type to 'text/plain',
|
753
|
+
# otherwise it's 'application/octet-stream'.
|
754
|
+
get '/v1/print/*' do
|
755
|
+
path = params[:splat].join('')
|
756
|
+
path = "//#{path}"
|
757
|
+
|
758
|
+
results = nil
|
759
|
+
open_p4 do |p4|
|
760
|
+
results = p4.run_print(path)
|
761
|
+
end
|
762
|
+
|
763
|
+
file_type = results[0]
|
764
|
+
content = results[1]
|
765
|
+
|
766
|
+
if file_type['type'] =~ /text/
|
767
|
+
content_type 'text/plain'
|
768
|
+
else
|
769
|
+
content_type 'application/octet-stream'
|
770
|
+
end
|
771
|
+
|
772
|
+
content
|
773
|
+
end
|
774
|
+
|
775
|
+
# The upload method adds new file revisions.
|
776
|
+
#
|
777
|
+
# This is a multipart method that accepts and array of files, plus,
|
778
|
+
# a 'mappings' array to indicate the target depot path for each file.
|
779
|
+
# This should be a JSON encoded array of strings.
|
780
|
+
#
|
781
|
+
# An optional 'description' attribute can describe the changes to be made.
|
782
|
+
post '/v1/upload' do
|
783
|
+
# if mappings[] and files[] do not have equivalent lengths, the error
|
784
|
+
# might be kind of lame.
|
785
|
+
mappings = params[:mappings]
|
786
|
+
files = []
|
787
|
+
mappings.each_index { |idx| files << params["file_#{idx}".to_sym] }
|
788
|
+
|
789
|
+
open_p4_temp_client(mappings) do |p4, root|
|
790
|
+
message = params[:description] || 'Uploaded files'
|
791
|
+
change_id = init_changelist(p4, message)
|
792
|
+
|
793
|
+
# Information used to determine if the new rev should be an add or edit
|
794
|
+
files_results = p4.run_files(mappings)
|
795
|
+
|
796
|
+
(0...mappings.length).each do |idx|
|
797
|
+
type = existing_path?(files_results, mappings[idx]) ? 'edit' : 'add'
|
798
|
+
|
799
|
+
if type == 'edit'
|
800
|
+
mark_change('edit', p4, change_id, root, mappings[idx])
|
801
|
+
save_content(root, mappings[idx], files[idx])
|
802
|
+
else
|
803
|
+
save_content(root, mappings[idx], files[idx])
|
804
|
+
mark_change('add', p4, change_id, root, mappings[idx])
|
805
|
+
end
|
806
|
+
end
|
807
|
+
|
808
|
+
p4.run_submit('-c', change_id)
|
809
|
+
end
|
810
|
+
end
|
811
|
+
|
812
|
+
def init_changelist(p4, description)
|
813
|
+
change_spec = p4.fetch_change
|
814
|
+
change_spec._description = description
|
815
|
+
results = p4.save_change(change_spec)
|
816
|
+
results[0].gsub(/^Change (\d+) created./, '\1')
|
817
|
+
end
|
818
|
+
|
819
|
+
def save_content(root, depot_path, file)
|
820
|
+
local_file = local_path(depot_path, root)
|
821
|
+
dir = File.dirname(local_file)
|
822
|
+
FileUtils.mkpath(dir) unless Dir.exist?(dir)
|
823
|
+
|
824
|
+
IO.write(local_file, file[:tempfile].read)
|
825
|
+
end
|
826
|
+
|
827
|
+
def existing_path?(existing_results, depot_path)
|
828
|
+
existing_results.any? do |result|
|
829
|
+
result['depotFile'] == depot_path
|
830
|
+
end
|
831
|
+
end
|
832
|
+
|
833
|
+
def mark_change(type, p4, change_id, root, depot_path)
|
834
|
+
local_file = local_path(depot_path, root)
|
835
|
+
p4.run(type, '-c', change_id, local_file)
|
836
|
+
end
|
837
|
+
|
838
|
+
def local_path(depot_path, root)
|
839
|
+
stripped = depot_path.gsub(/^\/+/, '')
|
840
|
+
File.join(root, stripped)
|
841
|
+
end
|
842
|
+
|
689
843
|
# Basically a "blacklist" of things we know the frameworks going to add to
|
690
844
|
# the params array we don't want to pass on to the p4 command sets for spec
|
691
845
|
# input
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: p4_web_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2014.2.0.
|
4
|
+
version: 2014.2.0.pre2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Perforce Software, Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-12-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|