blob: 1ce26dccb97a06cce0a4deb88bb2409a10332d75 [file] [log] [blame]
# Copyright 2008 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import logging
from google.appengine.api import users
from google.appengine.ext import db
from codereview import models
from change_pb2 import ChangeService
from complete_patchset_pb2 import *
from upload_patchset_file_pb2 import *
from submit_change_pb2 import *
from util import *
class ChangeServiceImp(ChangeService, InternalAPI):
@automatic_retry
def SubmitChange(self, rpc_controller, req, done):
rsp = SubmitChangeResponse()
user = users.User(req.owner)
branch = db.get(db.Key(req.dest_branch_key))
if not branch:
rsp.status_code = SubmitChangeResponse.UNKNOWN_BRANCH
done(rsp)
rev = commit_to_revision(branch.project, req.commit)
if rev.patchset:
rsp.status_code = SubmitChangeResponse.PATCHSET_EXISTS
done(rsp)
subject = u(req.commit.subject)[0:100]
def trans():
change = models.Change(
subject = subject,
description = u(req.commit.message),
owner = user,
dest_project = branch.project,
dest_branch = branch,
n_patchsets = 1)
change.put()
patchset = models.PatchSet(
change = change,
owner = user,
parent = change,
revision = rev,
id = 1)
patchset.put()
return (change, patchset)
change, patchset = db.run_in_transaction(trans)
if rev.link_patchset(patchset):
rsp.status_code = SubmitChangeResponse.CREATED
rsp.change_id = change.key().id()
rsp.patchset_id = patchset.id
rsp.patchset_key = str(patchset.key())
else:
db.delete([change, patchset])
rsp.status_code = SubmitChangeResponse.PATCHSET_EXISTS
done(rsp)
@automatic_retry
def UploadPatchsetFile(self, rpc_controller, req, done):
rsp = UploadPatchsetFileResponse()
patchset = db.get(db.Key(req.patchset_key))
if not patchset:
rsp.status_code = UploadPatchsetFileResponse.UNKNOWN_PATCHSET
done(rsp)
return
if patchset.complete or patchset.change.closed:
rsp.status_code = UploadPatchsetFileResponse.CLOSED
done(rsp)
return
if UploadPatchsetFileRequest.ADD == req.status:
status = 'A'
elif UploadPatchsetFileRequest.MODIFY == req.status:
status = 'M'
elif UploadPatchsetFileRequest.DELETE == req.status:
status = 'D'
else:
status = '?'
try:
if req.base_id:
old_data = models.DeltaContent.create_content(
id = req.base_id,
text_z = req.base_z)
new_data = models.DeltaContent.create_content(
id = req.final_id,
text_z = req.patch_z,
base = old_data)
if new_data.text_z == req.patch_z:
diff_data = new_data
else:
diff_data = models.DeltaContent.create_patch(
id = req.patch_id,
text_z = req.patch_z)
else:
old_data = None
new_data = None
diff_data = models.DeltaContent.create_patch(
id = req.patch_id,
text_z = req.patch_z)
except models.DeltaPatchingException:
logging.error("Patch error on change %s, patch set %s, file %s"
% (patchset.change.key().id(),
str(patchset.id),
u(req.file_name))
)
rsp.status_code = UploadPatchsetFileResponse.PATCHING_ERROR
done(rsp)
return
patch = models.Patch.get_or_insert_patch(
patchset = patchset,
filename = u(req.file_name),
status = status,
n_comments = 0,
old_data = old_data,
new_data = new_data,
diff_data = diff_data)
if old_data:
models.CachedDeltaContent.get(old_data.key())
models.CachedDeltaContent.get(new_data.key())
if diff_data != new_data:
models.CachedDeltaContent.get(diff_data.key())
else:
models.CachedDeltaContent.get(diff_data.key())
rsp.status_code = UploadPatchsetFileResponse.CREATED
done(rsp)
@automatic_retry
def CompletePatchset(serlf, rpc_controller, req, done):
rsp = CompletePatchsetResponse()
patchset = db.get(db.Key(req.patchset_key))
if not patchset.complete:
patchset.complete = True
patchset.put()
if len(req.compressed_filenames) > 0:
models.PatchSetFilenames.store_compressed(
patchset,
req.compressed_filenames)
done(rsp)