def handle_result(operation, process_id, printer, result, thread):
    #print(thread.process_id)
    #print(thread.params)
    process_region = printer.panel.find(process_id,0)
    status_region = printer.panel.find('Result:',process_region.begin())

    try:
        result = json.loads(result)
        if operation == 'compile' and 'actions' in result and util.to_bool(result['success']) == False:
            diff_merge_settings = config.settings.get('mm_diff_server_conflicts', False)
            if diff_merge_settings:
                if sublime.ok_cancel_dialog(result["body"], result["actions"][0].title()):
                    printer.panel.run_command('write_operation_status', {"text": " Diffing with server", 'region': [status_region.end(), status_region.end()+10] })
                    th = MavensMateDiffThread(thread.window, thread.view, result['tmp_file_path'])
                    th.start()
                    
                else:
                    printer.panel.run_command('write_operation_status', {"text": " "+result["actions"][1].title(), 'region': [status_region.end(), status_region.end()+10] })
            else:
                if sublime.ok_cancel_dialog(result["body"], "Overwrite Server Copy"):
                    printer.panel.run_command('write_operation_status', {"text": " Overwriting server copy", 'region': [status_region.end(), status_region.end()+10] })
                    thread.params['action'] = 'overwrite'
                    sublime.set_timeout(lambda: call('compile', params=thread.params), 100)   
                else:
                    printer.panel.run_command('write_operation_status', {"text": " "+result["actions"][1].title(), 'region': [status_region.end(), status_region.end()+10] })
   
        else:
            print_result_message(operation, process_id, status_region, result, printer, thread) 
            if operation == 'new_metadata' and 'success' in result and util.to_bool(result['success']) == True:
                if 'messages' in result:
                    if type(result['messages']) is not list:
                        result['messages'] = [result['messages']]
                    for m in result['messages']:
                        if 'package.xml' not in m['fileName']:
                            file_name = m['fileName']
                            location = util.mm_project_directory() + "/" + file_name.replace('unpackaged/', 'src/')
                            sublime.active_window().open_file(location)
                            break
            if 'success' in result and util.to_bool(result['success']) == True:
                if printer != None and len(ThreadTracker.get_pending_mm_panel_threads(thread.window)) == 0:
                    printer.hide()  
            elif 'State' in result and result['State'] == 'Completed' and len(ThreadTracker.get_pending_mm_panel_threads(thread.window)) == 0:
                #tooling api
                if printer != None:
                    printer.hide()
            if operation == 'refresh':            
                sublime.set_timeout(lambda: sublime.active_window().active_view().run_command('revert'), 200)
                util.clear_marked_line_numbers()
    except AttributeError:   
        if printer != None:
            printer.write('\n[RESPONSE FROM MAVENSMATE]: '+result+'\n')
            msg = ' [OPERATION FAILED]: Whoops, unable to parse the response. Please report this issue at https://github.com/joeferraro/MavensMate-SublimeText\n'
            msg += '[RESPONSE FROM MAVENSMATE]: '+result
            printer.panel.run_command('write_operation_status', {'text': msg, 'region': [status_region.end(), status_region.end()+10] })
    except Exception:
        if printer != None:
            printer.write('\n[RESPONSE FROM MAVENSMATE]: '+result+'\n')
            msg = ' [OPERATION FAILED]: Whoops, unable to parse the response. Please report this issue at https://github.com/joeferraro/MavensMate-SublimeText\n'
            msg += '[RESPONSE FROM MAVENSMATE]: '+result
            printer.panel.run_command('write_operation_status', {'text': msg, 'region': [status_region.end(), status_region.end()+10] })
 def __finish(self):
     if 'success' in self.result and util.to_bool(self.result['success']) == True:
         if self.printer != None and len(ThreadTracker.get_pending_mm_panel_threads(self.thread.window)) == 0:
             self.printer.hide() 
     elif 'State' in self.result and self.result['State'] == 'Completed' and len(ThreadTracker.get_pending_mm_panel_threads(self.thread.window)) == 0:
         if self.printer != None:
             self.printer.hide()
     if self.operation == 'refresh':            
         sublime.set_timeout(lambda: sublime.active_window().active_view().run_command('revert'), 200)
         util.clear_marked_line_numbers()
Example #3
0
 def __finish(self):
     try:
         if 'success' in self.result and util.to_bool(self.result['success']) == True:
             if self.printer != None and len(ThreadTracker.get_pending_mm_panel_threads(self.thread.window)) == 0:
                 self.printer.hide() 
         elif 'State' in self.result and self.result['State'] == 'Completed' and len(ThreadTracker.get_pending_mm_panel_threads(self.thread.window)) == 0:
             if self.printer != None:
                 self.printer.hide()
         if self.operation == 'refresh':            
             sublime.set_timeout(lambda: sublime.active_window().active_view().run_command('revert'), 200)
             util.clear_marked_line_numbers()
     except:
         pass #TODO
Example #4
0
 def __handle_new_metadata(self):
     self.__handle_compile_response()
     if 'success' in self.result and util.to_bool(self.result['success']) == True:
         if 'messages' in self.result or 'details' in self.result:
             if 'details' in self.result and 'componentSuccesses' in self.result['details']:
                 self.result['messages'] = self.result['details'].pop('componentSuccesses')
             if type(self.result['messages']) is not list:
                 self.result['messages'] = [self.result['messages']]
             for m in self.result['messages']:
                 if 'package.xml' not in m['fileName']:
                     file_name = m['fileName']
                     location = os.path.join(util.mm_project_directory(),file_name.replace('unpackaged/', 'src/'))
                     sublime.active_window().open_file(location)
                     break
 def __handle_new_metadata(self):
     self.__handle_compile_response()
     if "success" in self.result and util.to_bool(self.result["success"]) == True:
         if "messages" in self.result or "details" in self.result:
             if "details" in self.result and "componentSuccesses" in self.result["details"]:
                 self.result["messages"] = self.result["details"].pop("componentSuccesses")
             if type(self.result["messages"]) is not list:
                 self.result["messages"] = [self.result["messages"]]
             for m in self.result["messages"]:
                 if "package.xml" not in m["fileName"]:
                     file_name = m["fileName"]
                     location = os.path.join(util.mm_project_directory(), file_name.replace("unpackaged/", "src/"))
                     sublime.active_window().open_file(location)
                     break
 def __finish(self):
     try:
         if "success" in self.result and util.to_bool(self.result["success"]) == True:
             if self.printer != None and len(ThreadTracker.get_pending_mm_panel_threads(self.thread.window)) == 0:
                 self.printer.hide()
         elif (
             "State" in self.result
             and self.result["State"] == "Completed"
             and len(ThreadTracker.get_pending_mm_panel_threads(self.thread.window)) == 0
         ):
             if self.printer != None:
                 self.printer.hide()
         if self.operation == "refresh":
             sublime.set_timeout(lambda: sublime.active_window().active_view().run_command("revert"), 200)
             util.clear_marked_line_numbers()
     except:
         pass  # TODO
def print_result_message(operation, process_id, status_region, res, printer, thread):
    try:
        if 'State' in res and res['State'] == 'Failed' and 'CompilerErrors' in res:
            #here we're parsing a response from the tooling endpoint
            errors = json.loads(res['CompilerErrors'])
            if type(errors) is not list:
                errors = [errors]
            error_message = None
            if "ErrorMsg" in res and res["ErrorMsg"] != None:
                error_message = res["ErrorMsg"]
            if len(errors) > 0:
                for e in errors:
                    line_col = ""
                    line, col = 1, 1
                    if 'line' in e:
                        line = int(e['line'])
                        line_col = ' (Line: '+str(line)
                        util.mark_line_numbers(thread.view, [line], "bookmark")
                    if 'column' in e:
                        col = int(e['column'])
                        line_col += ', Column: '+str(col)
                    if len(line_col):
                        line_col += ')'

                    #scroll to the line and column of the exception
                    #if settings.get('mm_compile_scroll_to_error', True):
                    #open file, if already open it will bring it to focus
                    #view = sublime.active_window().open_file(thread.active_file)
                    view = thread.view
                    pt = view.text_point(line-1, col-1)
                    view.sel().clear()
                    view.sel().add(sublime.Region(pt))
                    view.show(pt)
                    problem = e['problem']
                    problem = html_parser.unescape(problem)
                    if error_message != None:
                        problem += '\n'+error_message    
                    printer.panel.run_command('write_operation_status', {"text": " [COMPILE FAILED]: ({0}) {1} {2}".format(e['name'], problem, line_col), 'region': [status_region.end(), status_region.end()+10] })
            elif "ErrorMsg" in res:
                printer.panel.run_command('write_operation_status', {"text": " [COMPILE FAILED]: {0}".format(error_message), 'region': [status_region.end(), status_region.end()+10] })

        elif 'success' in res and util.to_bool(res['success']) == False and 'messages' in res:
            #here we're parsing a response from the metadata endpoint
            line_col = ""
            msg = None
            failures = None
            if type( res['messages'] ) == list:
                for m in res['messages']:
                    if 'problem' in m:
                        msg = m
                        break
                if msg == None: #must not have been a compile error, must be a test run error
                    if 'run_test_result' in res and 'failures' in res['run_test_result'] and type( res['run_test_result']['failures'] ) == list:
                        failures = res['run_test_result']['failures']
                    elif 'failures' in res['run_test_result']:
                        failures = [res['run_test_result']['failures']]
            else:
                msg = res['messages']
            if msg != None:
                if 'lineNumber' in msg:
                    line_col = ' (Line: '+msg['lineNumber']
                    util.mark_line_numbers(thread.view, [int(float(msg['lineNumber']))], "bookmark")
                if 'columnNumber' in msg:
                    line_col += ', Column: '+msg['columnNumber']
                if len(line_col) > 0:
                    line_col += ')'
                printer.panel.run_command('write_operation_status', {'text': ' [DEPLOYMENT FAILED]: ' + msg['fileName'] + ': ' + msg['problem'] + line_col, 'region': [status_region.end(), status_region.end()+10] })
            elif failures != None:
                msg = ' [DEPLOYMENT FAILED]:'
                for f in failures: 
                    msg += f['name'] + ', ' + f['methodName'] + ': ' + f['message'] + '\n'
                printer.panel.run_command('write_operation_status', {'text': msg, 'region': [status_region.end(), status_region.end()+10] })
        elif 'success' in res and res["success"] == False and 'line' in res:
            #this is a response from the apex compile api
            line_col = ""
            line, col = 1, 1
            if 'line' in res:
                line = int(res['line'])
                line_col = ' (Line: '+str(line)
                util.mark_line_numbers(thread.view, [line], "bookmark")
            if 'column' in res:
                col = int(res['column'])
                line_col += ', Column: '+str(col)
            if len(line_col):
                line_col += ')'

            #scroll to the line and column of the exception
            if settings.get('mm_compile_scroll_to_error', True):
                #open file, if already open it will bring it to focus
                #view = sublime.active_window().open_file(thread.active_file)
                view = thread.view
                pt = view.text_point(line-1, col-1)
                view.sel().clear()
                view.sel().add(sublime.Region(pt))
                view.show(pt)

            printer.panel.run_command('write_operation_status', {'text': ' [COMPILE FAILED]: ' + res['problem'] + line_col, 'region': [status_region.end(), status_region.end()+10] })
        elif 'success' in res and util.to_bool(res['success']) == True and 'Messages' in res and len(res['Messages']) > 0:
            msg = ' [Operation completed Successfully - With Compile Errors]\n'
            msg += '[COMPILE ERRORS] - Count:\n'
            for m in res['Messages']:
                msg += ' FileName: ' + m['fileName'] + ': ' + m['problem'] + 'Line: ' + m['lineNumber']
            printer.panel.run_command('write_operation_status', {'text': msg, 'region': [status_region.end(), status_region.end()+10] })
        elif 'success' in res and util.to_bool(res['success']) == True:
            printer.panel.run_command('write_operation_status', {'text': ' Success', 'region': [status_region.end(), status_region.end()+10] })
        elif 'success' in res and util.to_bool(res['success']) == False and 'body' in res:
            printer.panel.run_command('write_operation_status', {'text': ' [OPERATION FAILED]:' + res['body'], 'region': [status_region.end(), status_region.end()+10] })
        elif 'success' in res and util.to_bool(res['success']) == False:
            printer.panel.run_command('write_operation_status', {'text': ' [OPERATION FAILED]', 'region': [status_region.end(), status_region.end()+10] })
        else:
            printer.panel.run_command('write_operation_status', {'text': ' Success', 'region': [status_region.end(), status_region.end()+10] })
    except:
        printer.panel.run_command('write_operation_status', {"text": " [ERROR: COULD NOT PARSE RESPONSE FROM MM]: {0}".format(res), 'region': [status_region.end(), status_region.end()+10] })
def print_result_message(operation, process_id, status_region, res, printer, thread):
    try:
        if 'State' in res and res['State'] == 'Error' and 'ErrorMsg' in res:
            printer.panel.run_command('write_operation_status', {"text": " [OPERATION FAILED]: {0}\n\n{1}".format(res['ErrorMsg'], 'If you are having difficulty compiling, try toggling the mm_compile_with_tooling_api setting to \'false\' or cleaning your project.'), 'region': [status_region.end(), status_region.end()+10] })
        elif 'State' in res and res['State'] == 'Failed' and 'CompilerErrors' in res:
            #here we're parsing a response from the tooling endpoint
            errors = json.loads(res['CompilerErrors'])
            if type(errors) is not list:
                errors = [errors]
            if len(errors) > 0:
                for e in errors:
                    line_col = ""
                    line, col = 1, 1
                    if 'line' in e:
                        line = int(e['line'])
                        line_col = ' (Line: '+str(line)
                        util.mark_line_numbers(thread.view, [line], "bookmark")
                    if 'column' in e:
                        col = int(e['column'])
                        line_col += ', Column: '+str(col)
                    if len(line_col):
                        line_col += ')'

                    #scroll to the line and column of the exception
                    #if settings.get('mm_compile_scroll_to_error', True):
                    #open file, if already open it will bring it to focus
                    #view = sublime.active_window().open_file(thread.active_file)
                    view = thread.view
                    pt = view.text_point(line-1, col-1)
                    view.sel().clear()
                    view.sel().add(sublime.Region(pt))
                    view.show(pt)
                    problem = e['problem']
                    problem = html_parser.unescape(problem)
                    printer.panel.run_command('write_operation_status', {"text": " [COMPILE FAILED]: ({0}) {1} {2}".format(e['name'], problem, line_col), 'region': [status_region.end(), status_region.end()+10] })
            elif "ErrorMsg" in res:
                printer.panel.run_command('write_operation_status', {"text": " [COMPILE FAILED]: {0}".format(res['ErrorMsg']), 'region': [status_region.end(), status_region.end()+10] })

        elif 'success' in res and util.to_bool(res['success']) == False and ('messages' in res or 'Messages' in res):
            if 'Messages' in res:
                res['messages'] = res.pop('Messages')
            #here we're parsing a response from the metadata endpoint
            failures = None
            messages = res['messages']
            if type( messages ) is not list:
                messages = [messages]

            problems = 0
            for m in messages:
                if 'problem' in m:
                    problems += 1
                    break

            if problems == 0: #must not have been a compile error, must be a test run error
                if 'runTestResult' in res:
                    if 'runTestResult' in res and 'failures' in res['runTestResult'] and type( res['runTestResult']['failures'] ) == list:
                        failures = res['runTestResult']['failures']
                    elif 'failures' in res['runTestResult']:
                        failures = [res['runTestResult']['failures']]
                    
                    if failures != None:
                        msg = ' [DEPLOYMENT FAILED]:'
                        for f in failures: 
                            msg += f['name'] + ', ' + f['methodName'] + ': ' + f['message'] + '\n'
                        printer.panel.run_command('write_operation_status', {'text': msg, 'region': [status_region.end(), status_region.end()+10] })
                elif 'run_test_result' in res:
                    if 'run_test_result' in res and 'failures' in res['run_test_result'] and type( res['run_test_result']['failures'] ) == list:
                        failures = res['run_test_result']['failures']
                    elif 'failures' in res['run_test_result']:
                        failures = [res['run_test_result']['failures']]
                    
                    if failures != None:
                        msg = ' [DEPLOYMENT FAILED]:'
                        for f in failures: 
                            msg += f['name'] + ', ' + f['methodName'] + ': ' + f['message'] + '\n'
                        printer.panel.run_command('write_operation_status', {'text': msg, 'region': [status_region.end(), status_region.end()+10] })
            else: #compile error, build error message
                msg = ""
                for m in messages:
                    if "success" in m and m["success"] == False:
                        line_col = ""
                        if 'lineNumber' in m:
                            line_col = ' (Line: '+m['lineNumber']
                            util.mark_line_numbers(thread.view, [int(float(m['lineNumber']))], "bookmark")
                        if 'columnNumber' in m:
                            line_col += ', Column: '+m['columnNumber']
                        if len(line_col) > 0:
                            line_col += ')'
                        msg += m['fileName'] + ': ' + m['problem'] + line_col + "\n\n"

                printer.panel.run_command('write_operation_status', {'text': ' [DEPLOYMENT FAILED]: ' + msg, 'region': [status_region.end(), status_region.end()+10] })
                
        elif 'success' in res and res["success"] == False and 'line' in res:
            #this is a response from the apex compile api
            line_col = ""
            line, col = 1, 1
            if 'line' in res:
                line = int(res['line'])
                line_col = ' (Line: '+str(line)
                util.mark_line_numbers(thread.view, [line], "bookmark")
            if 'column' in res:
                col = int(res['column'])
                line_col += ', Column: '+str(col)
            if len(line_col):
                line_col += ')'

            #scroll to the line and column of the exception
            if settings.get('mm_compile_scroll_to_error', True):
                #open file, if already open it will bring it to focus
                #view = sublime.active_window().open_file(thread.active_file)
                view = thread.view
                pt = view.text_point(line-1, col-1)
                view.sel().clear()
                view.sel().add(sublime.Region(pt))
                view.show(pt)

            printer.panel.run_command('write_operation_status', {'text': ' [COMPILE FAILED]: ' + res['problem'] + line_col, 'region': [status_region.end(), status_region.end()+10] })
        elif 'success' in res and util.to_bool(res['success']) == True and 'Messages' in res and len(res['Messages']) > 0:
            msg = ' [Operation completed Successfully - With Compile Errors]\n'
            msg += '[COMPILE ERRORS] - Count:\n'
            for m in res['Messages']:
                msg += ' FileName: ' + m['fileName'] + ': ' + m['problem'] + 'Line: ' + m['lineNumber']
            printer.panel.run_command('write_operation_status', {'text': msg, 'region': [status_region.end(), status_region.end()+10] })
        elif 'success' in res and util.to_bool(res['success']) == True:
            printer.panel.run_command('write_operation_status', {'text': ' Success', 'region': [status_region.end(), status_region.end()+10] })
        elif 'success' in res and util.to_bool(res['success']) == False and 'body' in res:
            printer.panel.run_command('write_operation_status', {'text': ' [OPERATION FAILED]:' + res['body'], 'region': [status_region.end(), status_region.end()+10] })
        elif 'success' in res and util.to_bool(res['success']) == False:
            printer.panel.run_command('write_operation_status', {'text': ' [OPERATION FAILED]', 'region': [status_region.end(), status_region.end()+10] })
        else:
            printer.panel.run_command('write_operation_status', {'text': ' Success', 'region': [status_region.end(), status_region.end()+10] })
    except:
        msg = ""
        if type(res) is dict:
            msg = json.dumps(res)
        elif type(res) is str:
            msg = res
        else:
            msg = "Check Sublime Text console for error and report issue to MavensMate GitHub project."
        printer.panel.run_command('write_operation_status', {'text': ' [OPERATION FAILED]: ' + msg, 'region': [status_region.end(), status_region.end()+10] })
def handle_result(operation, process_id, printer, result, thread):
    #print(thread.process_id)
    #print(thread.params)
    process_region = printer.panel.find(process_id,0)
    status_region = printer.panel.find('Result:',process_region.begin())

    try:
        result = json.loads(result)
        if operation == 'compile' and 'actions' in result and util.to_bool(result['success']) == False:
            diff_merge_settings = config.settings.get('mm_diff_server_conflicts', False)
            if diff_merge_settings:
                if sublime.ok_cancel_dialog(result["body"], result["actions"][0].title()):
                    printer.panel.run_command('write_operation_status', {"text": " Diffing with server", 'region': [status_region.end(), status_region.end()+10] })
                    th = MavensMateDiffThread(thread.window, thread.view, result['tmp_file_path'])
                    th.start()
                    
                else:
                    printer.panel.run_command('write_operation_status', {"text": " "+result["actions"][1].title(), 'region': [status_region.end(), status_region.end()+10] })
            else:
                if sublime.ok_cancel_dialog(result["body"], "Overwrite Server Copy"):
                    printer.panel.run_command('write_operation_status', {"text": " Overwriting server copy", 'region': [status_region.end(), status_region.end()+10] })
                    thread.params['action'] = 'overwrite'
                    sublime.set_timeout(lambda: call('compile', params=thread.params), 100)   
                else:
                    printer.panel.run_command('write_operation_status', {"text": " "+result["actions"][1].title(), 'region': [status_region.end(), status_region.end()+10] })
   
        elif operation == 'test_async':
            responses = []
            if len(result) == 1:
                res = result[0]
                response_string = ""
                if 'detailed_results' in res:
                    all_tests_passed = True
                    for r in res['detailed_results']:
                        if r["Outcome"] != "Pass":
                            all_tests_passed = False
                            break

                    if all_tests_passed:
                        response_string += '[TEST RESULT]: PASS'
                    else:
                        response_string += '[TEST RESULT]: FAIL'
                    
                    for r in res['detailed_results']:
                        if r["Outcome"] == "Pass":
                            pass #dont need to write anything here...
                        else:
                            response_string += '\n'
                            rstring = "====METHOD RESULT===="
                            rstring += "\n"
                            rstring += "{0} : {1}".format(r["MethodName"], r["Outcome"])
                            
                            rstring += "\n\n"
                            rstring += "====STACK TRACE===="
                            rstring += "\n"
                            rstring += r["StackTrace"]

                            rstring += "\n\n"
                            rstring += "====MESSAGE===="
                            rstring += "\n"
                            rstring += r["Message"]
                            rstring += "\n"
                            #responses.append("{0} | {1} | {2} | {3}\n".format(r["MethodName"], r["Outcome"], r["StackTrace"], r["Message"]))
                            responses.append(rstring)
                    response_string += "\n"       
                    response_string += "\n\n".join(responses)
                    printer.panel.run_command('write_operation_status', {'text': response_string, 'region': [status_region.end(), status_region.end()+10] })
                    printer.scroll_to_bottom()
                else:
                    printer.panel.run_command('write_operation_status', {'text': json.dumps(result), 'region': [status_region.end(), status_region.end()+10] })
            else:
                pass #TODO
        
        elif operation == 'run_apex_script':
            if result["success"] == True and result["compiled"] == True:
                printer.panel.run_command('write_operation_status', {'text': " Success", 'region': [status_region.end(), status_region.end()+10] })
                thread.window.open_file(result["log_location"], sublime.TRANSIENT)
            elif result["success"] == False:
                message = " [OPERATION FAILED]: "
                if "compileProblem" in result and result["compileProblem"] != None:
                    message += "[Line: "+str(result["line"]) + ", Column: "+str(result["column"])+"] " + result["compileProblem"] + "\n"
                if "exceptionMessage" in result and result["exceptionMessage"] != None:
                    message += result["exceptionMessage"] + "\n"
                if "exceptionStackTrace" in result and result["exceptionStackTrace"] != None:
                    message += result["exceptionStackTrace"] + "\n"
                printer.panel.run_command('write_operation_status', {'text': message, 'region': [status_region.end(), status_region.end()+10] })
        else:
            print_result_message(operation, process_id, status_region, result, printer, thread) 
            if operation == 'new_metadata' and 'success' in result and util.to_bool(result['success']) == True:
                if 'messages' in result:
                    if type(result['messages']) is not list:
                        result['messages'] = [result['messages']]
                    for m in result['messages']:
                        if 'package.xml' not in m['fileName']:
                            file_name = m['fileName']
                            location = os.path.join(util.mm_project_directory(),file_name.replace('unpackaged/', 'src/'))
                            sublime.active_window().open_file(location)
                            break
            if 'success' in result and util.to_bool(result['success']) == True:
                if printer != None and len(ThreadTracker.get_pending_mm_panel_threads(thread.window)) == 0:
                    printer.hide()  
            elif 'State' in result and result['State'] == 'Completed' and len(ThreadTracker.get_pending_mm_panel_threads(thread.window)) == 0:
                #tooling api
                if printer != None:
                    printer.hide()
            if operation == 'refresh':            
                sublime.set_timeout(lambda: sublime.active_window().active_view().run_command('revert'), 200)
                util.clear_marked_line_numbers()
    except AttributeError as e:   
        if printer != None:
            printer.write('\n[RESPONSE FROM MAVENSMATE]: '+result+'\n')
            msg = ' [OPERATION FAILED]: Whoops, unable to parse the response. Please report this issue at https://github.com/joeferraro/MavensMate-SublimeText\n'
            msg += '[RESPONSE FROM MAVENSMATE]: '+result
            print(e)
            print(sys.exc_info()[0])
            printer.panel.run_command('write_operation_status', {'text': msg, 'region': [status_region.end(), status_region.end()+10] })
    except Exception as e:
        if printer != None:
            printer.write('\n[RESPONSE FROM MAVENSMATE]: '+result+'\n')
            msg = ' [OPERATION FAILED]: Whoops, unable to parse the response. Please report this issue at https://github.com/joeferraro/MavensMate-SublimeText\n'
            msg += '[RESPONSE FROM MAVENSMATE]: '+result
            print(e)
            print(sys.exc_info()[0])
            printer.panel.run_command('write_operation_status', {'text': msg, 'region': [status_region.end(), status_region.end()+10] })
Example #10
0
    def __handle_compile_response(self, **kwargs):
        debug("HANDLING COMPILE!")
        debug(self.result)

        #diffing with server
        if 'actions' in self.result and util.to_bool(
                self.result['success']) == False:
            diff_merge_settings = config.settings.get(
                'mm_diff_server_conflicts', False)
            if diff_merge_settings:
                if sublime.ok_cancel_dialog(self.result["body"],
                                            self.result["actions"][0].title()):
                    self.__print_to_panel("Diffing with server")
                    th = MavensMateDiffThread(self.thread.window,
                                              self.thread.view,
                                              self.result['tmp_file_path'])
                    th.start()
                else:
                    self.__print_to_panel(self.result["actions"][1].title())
            else:
                if sublime.ok_cancel_dialog(self.result["body"],
                                            "Overwrite Server Copy"):
                    self.__print_to_panel("Overwriting server copy")
                    self.thread.params['action'] = 'overwrite'
                    if kwargs.get("callback", None) != None:
                        sublime.set_timeout(
                            lambda: self.callback('compile',
                                                  params=self.thread.params),
                            100)
                else:
                    self.__print_to_panel(self.result["actions"][1].title())
        else:
            try:
                if 'State' in self.result and self.result[
                        'State'] == 'Error' and 'ErrorMsg' in self.result:
                    self.__print_to_panel(
                        "[OPERATION FAILED]: {0}\n\n{1}".format(
                            self.result['ErrorMsg'],
                            'If you are having difficulty compiling, try toggling the mm_compile_with_tooling_api setting to \'false\' or cleaning your project.'
                        ))
                elif 'State' in self.result and self.result[
                        'State'] == 'Failed' and 'CompilerErrors' in self.result:
                    #here we're parsing a response from the tooling endpoint
                    errors = json.loads(self.result['CompilerErrors'])
                    if type(errors) is not list:
                        errors = [errors]
                    if len(errors) > 0:
                        for e in errors:
                            line_col = ""
                            line, col = 1, 1
                            if 'line' in e:
                                if type(e['line']) is list:
                                    line = int(e['line'][0])
                                else:
                                    line = int(e['line'])
                                line_col = ' (Line: ' + str(line)
                            if 'column' in e:
                                if type(e['column']) is list:
                                    line = int(e['column'][0])
                                else:
                                    col = int(e['column'])
                                line_col += ', Column: ' + str(col)
                            if len(line_col):
                                line_col += ')'

                            #scroll to the line and column of the exception
                            #if settings.get('mm_compile_scroll_to_error', True):
                            #open file, if already open it will bring it to focus
                            #view = sublime.active_window().open_file(self.thread.active_file)
                            view = self.thread.view
                            pt = view.text_point(line - 1, col - 1)
                            view.sel().clear()
                            view.sel().add(sublime.Region(pt))
                            view.show(pt)
                            problem = e['problem']
                            if type(problem) is list:
                                problem = problem[0]
                            problem = html_parser.unescape(problem)
                            file_base_name = e['name']
                            if type(file_base_name) is list:
                                file_base_name = file_base_name[0]
                            #if self.thread.window.active_view().name():
                            current_active_view = sublime.active_window(
                            ).active_view()
                            if current_active_view.file_name() != None:
                                current_active_view_file_name = os.path.basename(
                                    current_active_view.file_name())
                                if "." in current_active_view_file_name:
                                    current_active_view_file_name = current_active_view_file_name.split(
                                        ".")[0]
                                debug(current_active_view_file_name)
                                debug(file_base_name)
                                if current_active_view_file_name != file_base_name:
                                    #this is the tooling api throwing a compile error against a different file
                                    msg = "[COMPILE FAILED]: ({0}) {1} {2}".format(
                                        file_base_name, problem, line_col)
                                    msg += "\n\nThe Tooling API has failed to compile a separate element of metadata in your current MetadataContainer. You can either:"
                                    msg += "\n1. Fix the compilation error on " + file_base_name
                                    msg += "\n2. Reset your MetadataContainer to clear this error: MavensMate > Utilities > Reset MetadataContainer"
                                    self.__print_to_panel(msg)
                                elif current_active_view_file_name == file_base_name:
                                    util.mark_line_numbers(
                                        self.thread.view, [line], "bookmark")
                                    self.__print_to_panel(
                                        "[COMPILE FAILED]: ({0}) {1} {2}".
                                        format(file_base_name, problem,
                                               line_col))
                    elif "ErrorMsg" in self.result:
                        msg = ''
                        if 'object has been modified on server' in self.result[
                                'ErrorMsg']:
                            msg = self.result[
                                'ErrorMsg'] + '. You may try resetting your MetadataContainer to clear this error: MavensMate > Utilities > Reset MetadataContainer.'
                        else:
                            msg = self.result['ErrorMsg']
                        self.__print_to_panel(
                            "[COMPILE FAILED]: {0}".format(msg))

                elif 'success' in self.result and util.to_bool(
                        self.result['success']) == False and (
                            ('messages' in self.result or 'Messages'
                             in self.result) or 'details' in self.result):
                    if 'details' in self.result and 'componentFailures' in self.result[
                            'details']:
                        self.result['messages'] = self.result['details'].pop(
                            'componentFailures')
                    elif 'Messages' in self.result:
                        self.result['messages'] = self.result.pop('Messages')

                    #here we're parsing a response from the metadata endpoint
                    failures = None
                    messages = self.result['messages']
                    if type(messages) is not list:
                        messages = [messages]

                    problems = 0
                    for m in messages:
                        if 'problem' in m:
                            problems += 1
                            break

                    if problems == 0:  #must not have been a compile error, must be a test run error
                        if 'runTestResult' in self.result:
                            if 'runTestResult' in self.result and 'failures' in self.result[
                                    'runTestResult'] and type(
                                        self.result['runTestResult']
                                        ['failures']) == list:
                                failures = self.result['runTestResult'][
                                    'failures']
                            elif 'failures' in self.result['runTestResult']:
                                failures = [
                                    self.result['runTestResult']['failures']
                                ]

                            if failures != None:
                                msg = ' [DEPLOYMENT FAILED]:'
                                for f in failures:
                                    msg += f['name'] + ', ' + f[
                                        'methodName'] + ': ' + f[
                                            'message'] + '\n'
                                    self.__print_to_panel(msg)
                        elif 'run_test_result' in self.result:
                            if 'run_test_result' in self.result and 'failures' in self.result[
                                    'run_test_result'] and type(
                                        self.result['run_test_result']
                                        ['failures']) == list:
                                failures = self.result['run_test_result'][
                                    'failures']
                            elif 'failures' in self.result['run_test_result']:
                                failures = [
                                    self.result['run_test_result']['failures']
                                ]

                            if failures != None:
                                msg = ' [DEPLOYMENT FAILED]:'
                                for f in failures:
                                    msg += f['name'] + ', ' + f[
                                        'methodName'] + ': ' + f[
                                            'message'] + '\n'
                                self.__print_to_panel(msg)
                    else:  #compile error, build error message
                        msg = ""
                        for m in messages:
                            if "success" in m and m["success"] == False:
                                line_col = ""
                                if 'lineNumber' in m:
                                    line_col = ' (Line: ' + m['lineNumber']
                                    util.mark_line_numbers(
                                        self.thread.view,
                                        [int(float(m['lineNumber']))],
                                        "bookmark")
                                if 'columnNumber' in m:
                                    line_col += ', Column: ' + m['columnNumber']
                                if len(line_col) > 0:
                                    line_col += ')'
                                filename = m['fileName']
                                filename = re.sub(r'unpackaged/[A-Z,a-z]*/',
                                                  '', filename)
                                msg += filename + ': ' + m[
                                    'problem'] + line_col + "\n"

                        self.__print_to_panel('[DEPLOYMENT FAILED]: ' + msg)

                elif 'success' in self.result and self.result[
                        "success"] == False and 'line' in self.result:
                    #this is a response from the apex compile api
                    line_col = ""
                    line, col = 1, 1
                    if 'line' in self.result:
                        line = int(self.result['line'])
                        line_col = ' (Line: ' + str(line)
                        util.mark_line_numbers(self.thread.view, [line],
                                               "bookmark")
                    if 'column' in self.result:
                        col = int(self.result['column'])
                        line_col += ', Column: ' + str(col)
                    if len(line_col):
                        line_col += ')'

                    #scroll to the line and column of the exception
                    if settings.get('mm_compile_scroll_to_error', True):
                        #open file, if already open it will bring it to focus
                        #view = sublime.active_window().open_file(self.thread.active_file)
                        view = self.thread.view
                        pt = view.text_point(line - 1, col - 1)
                        view.sel().clear()
                        view.sel().add(sublime.Region(pt))
                        view.show(pt)

                        self.__print_to_panel('[COMPILE FAILED]: ' +
                                              self.result['problem'] +
                                              line_col)
                elif 'success' in self.result and util.to_bool(
                        self.result['success']
                ) == True and 'Messages' in self.result and len(
                        self.result['Messages']) > 0:
                    msg = ' [Operation completed Successfully - With Compile Errors]\n'
                    msg += '[COMPILE ERRORS] - Count:\n'
                    for m in self.result['Messages']:
                        msg += ' FileName: ' + m['fileName'] + ': ' + m[
                            'problem'] + 'Line: ' + m['lineNumber']
                    self.__print_to_panel(msg)
                elif 'success' in self.result and util.to_bool(
                        self.result['success']) == True:
                    self.__print_to_panel("Success")
                elif 'success' in self.result and util.to_bool(
                        self.result['success']
                ) == False and 'body' in self.result:
                    self.__print_to_panel('[OPERATION FAILED]: ' +
                                          self.result['body'])
                elif 'success' in self.result and util.to_bool(
                        self.result['success']) == False:
                    self.__print_to_panel('[OPERATION FAILED]')
                else:
                    self.__print_to_panel("Success")
            except Exception as e:
                debug(e)
                debug(traceback.print_exc())
                debug(type(self.result))
                msg = ""
                if type(self.result) is dict:
                    if 'body' in self.result:
                        msg = self.result["body"]
                    else:
                        msg = json.dumps(self.result)
                elif type(self.result) is str:
                    try:
                        m = json.loads(self.result)
                        msg = m["body"]
                    except:
                        msg = self.result
                else:
                    msg = "Check Sublime Text console for error and report issue to MavensMate-SublimeText GitHub project."
                self.__print_to_panel('[OPERATION FAILED]: ' + msg)
    def __handle_compile_response(self, **kwargs):  
        debug("HANDLING COMPILE!")
        debug(self.result)

        #diffing with server
        if 'actions' in self.result and util.to_bool(self.result['success']) == False:
            diff_merge_settings = config.settings.get('mm_diff_server_conflicts', False)
            if diff_merge_settings:
                if sublime.ok_cancel_dialog(self.result["body"], self.result["actions"][0].title()):
                    self.__print_to_panel("Diffing with server", "general")
                    th = MavensMateDiffThread(self.thread.window, self.thread.view, self.result['tmp_file_path'])
                    th.start()
                else:
                    self.__print_to_panel(self.result["actions"][1].title(), "general")
            else:
                if sublime.ok_cancel_dialog(self.result["body"], "Overwrite Server Copy"):
                    self.__print_to_panel("Overwriting server copy", "general")
                    self.thread.params['action'] = 'overwrite'
                    if kwargs.get("callback", None) != None:
                        sublime.set_timeout(lambda: self.callback('compile', params=self.thread.params), 100)   
                else:
                    self.__print_to_panel(self.result["actions"][1].title(), "general")
        else:
            try:
                if 'State' in self.result and self.result['State'] == 'Error' and 'ErrorMsg' in self.result:
                    self.__print_to_panel("[OPERATION FAILED]: {0}\n\n{1}".format(self.result['ErrorMsg'], 'If you are having difficulty compiling, try toggling the mm_compile_with_tooling_api setting to \'false\' or cleaning your project.'), "failure")
                elif 'State' in self.result and self.result['State'] == 'Failed' and ('CompilerErrors' in self.result or 'DeployDetails' in self.result):
                    #here we're parsing a response from the tooling endpoint
                    isLegacy = False #pre 30.0

                    if 'DeployDetails' in self.result: #31.0 and up
                        errors = self.result['DeployDetails']['componentFailures']
                        lineKey = 'lineNumber'
                        colKey = 'columnNumber'
                    else:
                        errors = json.loads(self.result['CompilerErrors'])
                        isLegacy = True
                        lineKey = 'line'
                        colKey = 'column'

                    if type(errors) is not list:
                        errors = [errors]
                    if len(errors) > 0:
                        for e in errors:
                            line_col = ""
                            line, col = 1, 1
                            if lineKey in e:
                                if type(e[lineKey]) is list:
                                    line = int(e[lineKey][0])
                                else:
                                    line = int(e[lineKey])
                                line_col = ' (Line: '+str(line)
                            if colKey in e:
                                if type(e[colKey]) is list:
                                    line = int(e[colKey][0])
                                else:
                                    col = int(e[colKey])
                                line_col += ', Column: '+str(col)
                            if len(line_col):
                                line_col += ')' 

                            #scroll to the line and column of the exception
                            #if settings.get('mm_compile_scroll_to_error', True):
                            #open file, if already open it will bring it to focus
                            #view = sublime.active_window().open_file(self.thread.active_file)
                            view = self.thread.view
                            pt = view.text_point(line-1, col-1)
                            view.sel().clear()
                            view.sel().add(sublime.Region(pt))
                            view.show(pt)
                            problem = e['problem']
                            if type(problem) is list:
                                problem = problem[0]
                            problem = html_parser.unescape(problem)
                            if isLegacy:
                                file_base_name = e['name']
                            else:
                                file_base_name = e['fileName']
                            if type(file_base_name) is list:
                                file_base_name = file_base_name[0]
                            #if self.thread.window.active_view().name():
                            current_active_view = sublime.active_window().active_view()
                            if current_active_view.file_name() != None:
                                current_active_view_file_name = os.path.basename(current_active_view.file_name())
                                if "." in current_active_view_file_name:
                                    current_active_view_file_name = current_active_view_file_name.split(".")[0]
                                debug(current_active_view_file_name)
                                debug(file_base_name)
                                if current_active_view_file_name != file_base_name:
                                    #this is the tooling api throwing a compile error against a different file
                                    msg = "[COMPILE FAILED]: ({0}) {1} {2}".format(file_base_name, problem, line_col)
                                    msg += "\n\nThe Tooling API has failed to compile a separate element of metadata in your current MetadataContainer. You can either:"
                                    msg += "\n1. Fix the compilation error on "+file_base_name
                                    msg += "\n2. Reset your MetadataContainer to clear this error: MavensMate > Utilities > Reset MetadataContainer"
                                    self.__print_to_panel(msg, "failure")
                                elif current_active_view_file_name == file_base_name:
                                    util.mark_line_numbers(self.thread.view, [line], "bookmark")
                                    self.__print_to_panel("[COMPILE FAILED]: ({0}) {1} {2}".format(file_base_name, problem, line_col), "failure")
                    elif "ErrorMsg" in self.result:
                        msg = ''
                        if 'object has been modified on server' in self.result['ErrorMsg']:
                            msg = self.result['ErrorMsg'] + '. You may try resetting your MetadataContainer to clear this error: MavensMate > Utilities > Reset MetadataContainer.'
                        else:
                            msg = self.result['ErrorMsg']
                        self.__print_to_panel("[COMPILE FAILED]: {0}".format(msg), "failure")

                elif 'success' in self.result and util.to_bool(self.result['success']) == False and (('messages' in self.result or 'Messages' in self.result) or 'details' in self.result):
                    if 'details' in self.result and 'componentFailures' in self.result['details']:
                        self.result['messages'] = self.result['details'].pop('componentFailures')
                    elif 'Messages' in self.result:
                        self.result['messages'] = self.result.pop('Messages')
                    
                    #here we're parsing a response from the metadata endpoint
                    failures = None
                    messages = self.result['messages']
                    if type( messages ) is not list:
                        messages = [messages]

                    problems = 0
                    for m in messages:
                        if 'problem' in m:
                            problems += 1
                            break

                    if problems == 0: #must not have been a compile error, must be a test run error
                        if 'runTestResult' in self.result:
                            if 'runTestResult' in self.result and 'failures' in self.result['runTestResult'] and type( self.result['runTestResult']['failures'] ) == list:
                                failures = self.result['runTestResult']['failures']
                            elif 'failures' in self.result['runTestResult']:
                                failures = [self.result['runTestResult']['failures']]
                            
                            if failures != None:
                                msg = ' [DEPLOYMENT FAILED]:'
                                for f in failures: 
                                    msg += f['name'] + ', ' + f['methodName'] + ': ' + f['message'] + '\n'
                                    self.__print_to_panel(msg, "failure")
                        elif 'run_test_result' in self.result:
                            if 'run_test_result' in self.result and 'failures' in self.result['run_test_result'] and type( self.result['run_test_result']['failures'] ) == list:
                                failures = self.result['run_test_result']['failures']
                            elif 'failures' in self.result['run_test_result']:
                                failures = [self.result['run_test_result']['failures']]
                            
                            if failures != None:
                                msg = ' [DEPLOYMENT FAILED]:'
                                for f in failures: 
                                    msg += f['name'] + ', ' + f['methodName'] + ': ' + f['message'] + '\n'
                                self.__print_to_panel(msg, "failure")
                    else: #compile error, build error message
                        msg = ""
                        for m in messages:
                            if "success" in m and m["success"] == False:
                                line_col = ""
                                if 'lineNumber' in m:
                                    line_col = ' (Line: '+m['lineNumber']
                                    util.mark_line_numbers(self.thread.view, [int(float(m['lineNumber']))], "bookmark")
                                if 'columnNumber' in m:
                                    line_col += ', Column: '+m['columnNumber']
                                if len(line_col) > 0:
                                    line_col += ')'
                                filename = m['fileName']
                                filename = re.sub(r'unpackaged/[A-Z,a-z]*/', '', filename)
                                msg += filename + ': ' + m['problem'] + line_col + "\n"

                        self.__print_to_panel('[DEPLOYMENT FAILED]: ' + msg, "failure")
                        
                elif 'success' in self.result and self.result["success"] == False and 'line' in self.result:
                    #this is a response from the apex compile api
                    line_col = ""
                    line, col = 1, 1
                    if 'line' in self.result:
                        line = int(self.result['line'])
                        line_col = ' (Line: '+str(line)
                        util.mark_line_numbers(self.thread.view, [line], "bookmark")
                    if 'column' in self.result:
                        col = int(self.result['column'])
                        line_col += ', Column: '+str(col)
                    if len(line_col):
                        line_col += ')'

                    #scroll to the line and column of the exception
                    if settings.get('mm_compile_scroll_to_error', True):
                        #open file, if already open it will bring it to focus
                        #view = sublime.active_window().open_file(self.thread.active_file)
                        view = self.thread.view
                        pt = view.text_point(line-1, col-1)
                        view.sel().clear()
                        view.sel().add(sublime.Region(pt))
                        view.show(pt)

                        self.__print_to_panel('[COMPILE FAILED]: ' + self.result['problem'] + line_col, "failure")
                elif 'success' in self.result and util.to_bool(self.result['success']) == True and 'Messages' in self.result and len(self.result['Messages']) > 0:
                    msg = ' [Operation completed Successfully - With Compile Errors]\n'
                    msg += '[COMPILE ERRORS] - Count:\n'
                    for m in self.result['Messages']:
                        msg += ' FileName: ' + m['fileName'] + ': ' + m['problem'] + 'Line: ' + m['lineNumber']
                    self.__print_to_panel(msg, "failure")
                elif 'success' in self.result and util.to_bool(self.result['success']) == True:
                    self.__print_to_panel("Success", "success")
                elif 'success' in self.result and util.to_bool(self.result['success']) == False and 'body' in self.result:
                    self.__print_to_panel('[OPERATION FAILED]: ' + self.result['body'], "failure")
                elif 'success' in self.result and util.to_bool(self.result['success']) == False:
                    self.__print_to_panel('[OPERATION FAILED]', "failure")
                else:
                    self.__print_to_panel("Success", "success")
            except Exception as e:
                debug(e)
                debug(traceback.print_exc())
                debug(type(self.result))
                msg = ""
                if type(self.result) is dict:
                    if 'body' in self.result:
                        msg = self.result["body"]
                    else:
                        msg = json.dumps(self.result)
                elif type(self.result) is str:
                    try:
                        m = json.loads(self.result)
                        msg = m["body"]
                    except:
                        msg = self.result
                else:
                    msg = "Check Sublime Text console for error and report issue to MavensMate-SublimeText GitHub project."
                self.__print_to_panel('[OPERATION FAILED]: ' + msg, "failure")
def print_result_message(operation, process_id, status_region, res, printer,
                         thread):
    if 'State' in res and res['State'] == 'Error' and 'ErrorMsg' in res:
        printer.panel.run_command(
            'write_operation_status', {
                "text":
                " [OPERATION FAILED]: {0}\n\n{1}".format(
                    res['ErrorMsg'],
                    'If you are having difficulty compiling, try toggling the mm_compile_with_tooling_api setting to \'false\''
                ),
                'region': [status_region.end(),
                           status_region.end() + 10]
            })
    elif 'State' in res and res[
            'State'] == 'Failed' and 'CompilerErrors' in res:
        #here we're parsing a response from the tooling endpoint
        errors = json.loads(res['CompilerErrors'])
        if type(errors) is not list:
            errors = [errors]
        if len(errors) > 0:
            for e in errors:
                line_col = ""
                line, col = 1, 1
                if 'line' in e:
                    line = int(e['line'])
                    line_col = ' (Line: ' + str(line)
                    util.mark_line_numbers(thread.view, [line], "bookmark")
                if 'column' in e:
                    col = int(e['column'])
                    line_col += ', Column: ' + str(col)
                if len(line_col):
                    line_col += ')'

                #scroll to the line and column of the exception
                #if settings.get('mm_compile_scroll_to_error', True):
                #open file, if already open it will bring it to focus
                #view = sublime.active_window().open_file(thread.active_file)
                view = thread.view
                pt = view.text_point(line - 1, col - 1)
                view.sel().clear()
                view.sel().add(sublime.Region(pt))
                view.show(pt)
                problem = e['problem']
                problem = html_parser.unescape(problem)
                printer.panel.run_command(
                    'write_operation_status', {
                        "text":
                        " [COMPILE FAILED]: ({0}) {1} {2}".format(
                            e['name'], problem, line_col),
                        'region':
                        [status_region.end(),
                         status_region.end() + 10]
                    })
        elif "ErrorMsg" in res:
            printer.panel.run_command(
                'write_operation_status', {
                    "text": " [COMPILE FAILED]: {0}".format(res['ErrorMsg']),
                    'region': [status_region.end(),
                               status_region.end() + 10]
                })

    elif 'success' in res and util.to_bool(
            res['success']) == False and ('messages' in res
                                          or 'Messages' in res):
        if 'Messages' in res:
            res['messages'] = res.pop('Messages')
        #here we're parsing a response from the metadata endpoint
        failures = None
        messages = res['messages']
        if type(messages) is not list:
            messages = [messages]

        problems = 0
        for m in messages:
            if 'problem' in m:
                problems += 1
                break

        if problems == 0:  #must not have been a compile error, must be a test run error
            if 'run_test_result' in res and 'failures' in res[
                    'run_test_result'] and type(
                        res['run_test_result']['failures']) == list:
                failures = res['run_test_result']['failures']
            elif 'failures' in res['run_test_result']:
                failures = [res['run_test_result']['failures']]

            if failures != None:
                msg = ' [DEPLOYMENT FAILED]:'
                for f in failures:
                    msg += f['name'] + ', ' + f['methodName'] + ': ' + f[
                        'message'] + '\n'
                printer.panel.run_command(
                    'write_operation_status', {
                        'text': msg,
                        'region':
                        [status_region.end(),
                         status_region.end() + 10]
                    })
        else:  #compile error, build error message
            msg = ""
            for m in messages:
                if "success" in m and m["success"] == False:
                    line_col = ""
                    if 'lineNumber' in m:
                        line_col = ' (Line: ' + m['lineNumber']
                        util.mark_line_numbers(thread.view,
                                               [int(float(m['lineNumber']))],
                                               "bookmark")
                    if 'columnNumber' in m:
                        line_col += ', Column: ' + m['columnNumber']
                    if len(line_col) > 0:
                        line_col += ')'
                    msg += m['fileName'] + ': ' + m[
                        'problem'] + line_col + "\n\n"

            printer.panel.run_command(
                'write_operation_status', {
                    'text': ' [DEPLOYMENT FAILED]: ' + msg,
                    'region': [status_region.end(),
                               status_region.end() + 10]
                })

    elif 'success' in res and res["success"] == False and 'line' in res:
        #this is a response from the apex compile api
        line_col = ""
        line, col = 1, 1
        if 'line' in res:
            line = int(res['line'])
            line_col = ' (Line: ' + str(line)
            util.mark_line_numbers(thread.view, [line], "bookmark")
        if 'column' in res:
            col = int(res['column'])
            line_col += ', Column: ' + str(col)
        if len(line_col):
            line_col += ')'

        #scroll to the line and column of the exception
        if settings.get('mm_compile_scroll_to_error', True):
            #open file, if already open it will bring it to focus
            #view = sublime.active_window().open_file(thread.active_file)
            view = thread.view
            pt = view.text_point(line - 1, col - 1)
            view.sel().clear()
            view.sel().add(sublime.Region(pt))
            view.show(pt)

        printer.panel.run_command(
            'write_operation_status', {
                'text': ' [COMPILE FAILED]: ' + res['problem'] + line_col,
                'region': [status_region.end(),
                           status_region.end() + 10]
            })
    elif 'success' in res and util.to_bool(
            res['success']) == True and 'Messages' in res and len(
                res['Messages']) > 0:
        msg = ' [Operation completed Successfully - With Compile Errors]\n'
        msg += '[COMPILE ERRORS] - Count:\n'
        for m in res['Messages']:
            msg += ' FileName: ' + m['fileName'] + ': ' + m[
                'problem'] + 'Line: ' + m['lineNumber']
        printer.panel.run_command(
            'write_operation_status', {
                'text': msg,
                'region': [status_region.end(),
                           status_region.end() + 10]
            })
    elif 'success' in res and util.to_bool(res['success']) == True:
        printer.panel.run_command(
            'write_operation_status', {
                'text': ' Success',
                'region': [status_region.end(),
                           status_region.end() + 10]
            })
    elif 'success' in res and util.to_bool(
            res['success']) == False and 'body' in res:
        printer.panel.run_command(
            'write_operation_status', {
                'text': ' [OPERATION FAILED]:' + res['body'],
                'region': [status_region.end(),
                           status_region.end() + 10]
            })
    elif 'success' in res and util.to_bool(res['success']) == False:
        printer.panel.run_command(
            'write_operation_status', {
                'text': ' [OPERATION FAILED]',
                'region': [status_region.end(),
                           status_region.end() + 10]
            })
    else:
        printer.panel.run_command(
            'write_operation_status', {
                'text': ' Success',
                'region': [status_region.end(),
                           status_region.end() + 10]
            })
def handle_result(operation, process_id, printer, result, thread):
    #print(thread.process_id)
    #print(thread.params)
    process_region = printer.panel.find(process_id, 0)
    status_region = printer.panel.find('Result:', process_region.begin())

    try:
        result = json.loads(result)
        if operation == 'compile' and 'actions' in result and util.to_bool(
                result['success']) == False:
            diff_merge_settings = config.settings.get(
                'mm_diff_server_conflicts', False)
            if diff_merge_settings:
                if sublime.ok_cancel_dialog(result["body"],
                                            result["actions"][0].title()):
                    printer.panel.run_command(
                        'write_operation_status', {
                            "text":
                            " Diffing with server",
                            'region':
                            [status_region.end(),
                             status_region.end() + 10]
                        })
                    th = MavensMateDiffThread(thread.window, thread.view,
                                              result['tmp_file_path'])
                    th.start()

                else:
                    printer.panel.run_command(
                        'write_operation_status', {
                            "text":
                            " " + result["actions"][1].title(),
                            'region':
                            [status_region.end(),
                             status_region.end() + 10]
                        })
            else:
                if sublime.ok_cancel_dialog(result["body"],
                                            "Overwrite Server Copy"):
                    printer.panel.run_command(
                        'write_operation_status', {
                            "text":
                            " Overwriting server copy",
                            'region':
                            [status_region.end(),
                             status_region.end() + 10]
                        })
                    thread.params['action'] = 'overwrite'
                    sublime.set_timeout(
                        lambda: call('compile', params=thread.params), 100)
                else:
                    printer.panel.run_command(
                        'write_operation_status', {
                            "text":
                            " " + result["actions"][1].title(),
                            'region':
                            [status_region.end(),
                             status_region.end() + 10]
                        })

        elif operation == 'test_async':
            responses = []
            if len(result) == 1:
                res = result[0]
                response_string = ""
                if 'detailed_results' in res:
                    all_tests_passed = True
                    for r in res['detailed_results']:
                        if r["Outcome"] != "Pass":
                            all_tests_passed = False
                            break

                    if all_tests_passed:
                        response_string += '[TEST RESULT]: PASS'
                    else:
                        response_string += '[TEST RESULT]: FAIL'

                    for r in res['detailed_results']:
                        if r["Outcome"] == "Pass":
                            pass  #dont need to write anything here...
                        else:
                            response_string += '\n'
                            rstring = "====METHOD RESULT===="
                            rstring += "\n"
                            rstring += "{0} : {1}".format(
                                r["MethodName"], r["Outcome"])

                            rstring += "\n\n"
                            rstring += "====STACK TRACE===="
                            rstring += "\n"
                            rstring += r["StackTrace"]

                            rstring += "\n\n"
                            rstring += "====MESSAGE===="
                            rstring += "\n"
                            rstring += r["Message"]
                            rstring += "\n"
                            #responses.append("{0} | {1} | {2} | {3}\n".format(r["MethodName"], r["Outcome"], r["StackTrace"], r["Message"]))
                            responses.append(rstring)
                    response_string += "\n"
                    response_string += "\n\n".join(responses)
                    printer.panel.run_command(
                        'write_operation_status', {
                            'text':
                            response_string,
                            'region':
                            [status_region.end(),
                             status_region.end() + 10]
                        })
                    printer.scroll_to_bottom()
                else:
                    printer.panel.run_command(
                        'write_operation_status', {
                            'text':
                            json.dumps(result),
                            'region':
                            [status_region.end(),
                             status_region.end() + 10]
                        })
            else:
                pass  #TODO

        elif operation == 'run_apex_script':
            if result["success"] == True and result["compiled"] == True:
                printer.panel.run_command(
                    'write_operation_status', {
                        'text': " Success",
                        'region':
                        [status_region.end(),
                         status_region.end() + 10]
                    })
                thread.window.open_file(result["log_location"],
                                        sublime.TRANSIENT)
            elif result["success"] == False:
                message = " [OPERATION FAILED]: "
                if "compileProblem" in result and result[
                        "compileProblem"] != None:
                    message += "[Line: " + str(
                        result["line"]) + ", Column: " + str(
                            result["column"]
                        ) + "] " + result["compileProblem"] + "\n"
                if "exceptionMessage" in result and result[
                        "exceptionMessage"] != None:
                    message += result["exceptionMessage"] + "\n"
                if "exceptionStackTrace" in result and result[
                        "exceptionStackTrace"] != None:
                    message += result["exceptionStackTrace"] + "\n"
                printer.panel.run_command(
                    'write_operation_status', {
                        'text': message,
                        'region':
                        [status_region.end(),
                         status_region.end() + 10]
                    })
        else:
            print_result_message(operation, process_id, status_region, result,
                                 printer, thread)
            if operation == 'new_metadata' and 'success' in result and util.to_bool(
                    result['success']) == True:
                if 'messages' in result:
                    if type(result['messages']) is not list:
                        result['messages'] = [result['messages']]
                    for m in result['messages']:
                        if 'package.xml' not in m['fileName']:
                            file_name = m['fileName']
                            location = os.path.join(
                                util.mm_project_directory(),
                                file_name.replace('unpackaged/', 'src/'))
                            sublime.active_window().open_file(location)
                            break
            if 'success' in result and util.to_bool(result['success']) == True:
                if printer != None and len(
                        ThreadTracker.get_pending_mm_panel_threads(
                            thread.window)) == 0:
                    printer.hide()
            elif 'State' in result and result['State'] == 'Completed' and len(
                    ThreadTracker.get_pending_mm_panel_threads(
                        thread.window)) == 0:
                #tooling api
                if printer != None:
                    printer.hide()
            if operation == 'refresh':
                sublime.set_timeout(
                    lambda: sublime.active_window().active_view().run_command(
                        'revert'), 200)
                util.clear_marked_line_numbers()
    except AttributeError as e:
        if printer != None:
            printer.write('\n[RESPONSE FROM MAVENSMATE]: ' + result + '\n')
            msg = ' [OPERATION FAILED]: Whoops, unable to parse the response. Please report this issue at https://github.com/joeferraro/MavensMate-SublimeText\n'
            msg += '[RESPONSE FROM MAVENSMATE]: ' + result
            print(e)
            print(sys.exc_info()[0])
            printer.panel.run_command(
                'write_operation_status', {
                    'text': msg,
                    'region': [status_region.end(),
                               status_region.end() + 10]
                })
    except Exception as e:
        if printer != None:
            printer.write('\n[RESPONSE FROM MAVENSMATE]: ' + result + '\n')
            msg = ' [OPERATION FAILED]: Whoops, unable to parse the response. Please report this issue at https://github.com/joeferraro/MavensMate-SublimeText\n'
            msg += '[RESPONSE FROM MAVENSMATE]: ' + result
            print(e)
            print(sys.exc_info()[0])
            printer.panel.run_command(
                'write_operation_status', {
                    'text': msg,
                    'region': [status_region.end(),
                               status_region.end() + 10]
                })
    def __handle_compile_response(self, **kwargs):
        # print("HANDLING COMPILE!")

        # diffing with server
        if "actions" in self.result and util.to_bool(self.result["success"]) == False:
            diff_merge_settings = config.settings.get("mm_diff_server_conflicts", False)
            if diff_merge_settings:
                if sublime.ok_cancel_dialog(self.result["body"], self.result["actions"][0].title()):
                    self.__print_to_panel("Diffing with server")
                    th = MavensMateDiffThread(self.thread.window, self.thread.view, self.result["tmp_file_path"])
                    th.start()
                else:
                    self.__print_to_panel(self.result["actions"][1].title())
            else:
                if sublime.ok_cancel_dialog(self.result["body"], "Overwrite Server Copy"):
                    self.__print_to_panel("Overwriting server copy")
                    self.thread.params["action"] = "overwrite"
                    if kwargs.get("callback", None) != None:
                        sublime.set_timeout(lambda: self.callback("compile", params=self.thread.params), 100)
                else:
                    self.__print_to_panel(self.result["actions"][1].title())
        else:
            try:
                if "State" in self.result and self.result["State"] == "Error" and "ErrorMsg" in self.result:
                    self.__print_to_panel(
                        "[OPERATION FAILED]: {0}\n\n{1}".format(
                            self.result["ErrorMsg"],
                            "If you are having difficulty compiling, try toggling the mm_compile_with_tooling_api setting to 'false' or cleaning your project.",
                        )
                    )
                elif "State" in self.result and self.result["State"] == "Failed" and "CompilerErrors" in self.result:
                    # here we're parsing a response from the tooling endpoint
                    errors = json.loads(self.result["CompilerErrors"])
                    if type(errors) is not list:
                        errors = [errors]
                    if len(errors) > 0:
                        for e in errors:
                            line_col = ""
                            line, col = 1, 1
                            if "line" in e:
                                line = int(e["line"])
                                line_col = " (Line: " + str(line)
                            if "column" in e:
                                col = int(e["column"])
                                line_col += ", Column: " + str(col)
                            if len(line_col):
                                line_col += ")"

                            # scroll to the line and column of the exception
                            # if settings.get('mm_compile_scroll_to_error', True):
                            # open file, if already open it will bring it to focus
                            # view = sublime.active_window().open_file(self.thread.active_file)
                            view = self.thread.view
                            pt = view.text_point(line - 1, col - 1)
                            view.sel().clear()
                            view.sel().add(sublime.Region(pt))
                            view.show(pt)
                            problem = e["problem"]
                            problem = html_parser.unescape(problem)
                            file_base_name = e["name"]
                            # if self.thread.window.active_view().name():
                            current_active_view = sublime.active_window().active_view()
                            if current_active_view.file_name() != None:
                                current_active_view_file_name = os.path.basename(current_active_view.file_name())
                                if "." in current_active_view_file_name:
                                    current_active_view_file_name = current_active_view_file_name.split(".")[0]
                                debug(current_active_view_file_name)
                                debug(file_base_name)
                                if current_active_view_file_name != file_base_name:
                                    # this is the tooling api throwing a compile error against a different file
                                    msg = "[COMPILE FAILED]: ({0}) {1} {2}".format(file_base_name, problem, line_col)
                                    msg += "\n\nThe Tooling API has failed to compile a separate element of metadata in your current MetadataContainer. You can either:"
                                    msg += "\n1. Fix the compilation error on " + file_base_name
                                    msg += "\n2. Reset your MetadataContainer to clear this error: MavensMate > Utilities > Reset MetadataContainer"
                                    self.__print_to_panel(msg)
                                elif current_active_view_file_name == file_base_name:
                                    util.mark_line_numbers(self.thread.view, [line], "bookmark")
                                    self.__print_to_panel(
                                        "[COMPILE FAILED]: ({0}) {1} {2}".format(file_base_name, problem, line_col)
                                    )
                    elif "ErrorMsg" in self.result:
                        self.__print_to_panel("[COMPILE FAILED]: {0}".format(self.result["ErrorMsg"]))

                elif (
                    "success" in self.result
                    and util.to_bool(self.result["success"]) == False
                    and (("messages" in self.result or "Messages" in self.result) or "details" in self.result)
                ):
                    if "details" in self.result and "componentFailures" in self.result["details"]:
                        self.result["messages"] = self.result["details"].pop("componentFailures")
                    elif "Messages" in self.result:
                        self.result["messages"] = self.result.pop("Messages")

                    # here we're parsing a response from the metadata endpoint
                    failures = None
                    messages = self.result["messages"]
                    if type(messages) is not list:
                        messages = [messages]

                    problems = 0
                    for m in messages:
                        if "problem" in m:
                            problems += 1
                            break

                    if problems == 0:  # must not have been a compile error, must be a test run error
                        if "runTestResult" in self.result:
                            if (
                                "runTestResult" in self.result
                                and "failures" in self.result["runTestResult"]
                                and type(self.result["runTestResult"]["failures"]) == list
                            ):
                                failures = self.result["runTestResult"]["failures"]
                            elif "failures" in self.result["runTestResult"]:
                                failures = [self.result["runTestResult"]["failures"]]

                            if failures != None:
                                msg = " [DEPLOYMENT FAILED]:"
                                for f in failures:
                                    msg += f["name"] + ", " + f["methodName"] + ": " + f["message"] + "\n"
                                    self.__print_to_panel(msg)
                        elif "run_test_result" in self.result:
                            if (
                                "run_test_result" in self.result
                                and "failures" in self.result["run_test_result"]
                                and type(self.result["run_test_result"]["failures"]) == list
                            ):
                                failures = self.result["run_test_result"]["failures"]
                            elif "failures" in self.result["run_test_result"]:
                                failures = [self.result["run_test_result"]["failures"]]

                            if failures != None:
                                msg = " [DEPLOYMENT FAILED]:"
                                for f in failures:
                                    msg += f["name"] + ", " + f["methodName"] + ": " + f["message"] + "\n"
                                self.__print_to_panel(msg)
                    else:  # compile error, build error message
                        msg = ""
                        for m in messages:
                            if "success" in m and m["success"] == False:
                                line_col = ""
                                if "lineNumber" in m:
                                    line_col = " (Line: " + m["lineNumber"]
                                    util.mark_line_numbers(self.thread.view, [int(float(m["lineNumber"]))], "bookmark")
                                if "columnNumber" in m:
                                    line_col += ", Column: " + m["columnNumber"]
                                if len(line_col) > 0:
                                    line_col += ")"
                                filename = m["fileName"]
                                filename = re.sub(r"unpackaged/[A-Z,a-z]*/", "", filename)
                                msg += filename + ": " + m["problem"] + line_col + "\n"

                        self.__print_to_panel("[DEPLOYMENT FAILED]: " + msg)

                elif "success" in self.result and self.result["success"] == False and "line" in self.result:
                    # this is a response from the apex compile api
                    line_col = ""
                    line, col = 1, 1
                    if "line" in self.result:
                        line = int(self.result["line"])
                        line_col = " (Line: " + str(line)
                        util.mark_line_numbers(self.thread.view, [line], "bookmark")
                    if "column" in self.result:
                        col = int(self.result["column"])
                        line_col += ", Column: " + str(col)
                    if len(line_col):
                        line_col += ")"

                    # scroll to the line and column of the exception
                    if settings.get("mm_compile_scroll_to_error", True):
                        # open file, if already open it will bring it to focus
                        # view = sublime.active_window().open_file(self.thread.active_file)
                        view = self.thread.view
                        pt = view.text_point(line - 1, col - 1)
                        view.sel().clear()
                        view.sel().add(sublime.Region(pt))
                        view.show(pt)

                        self.__print_to_panel("[COMPILE FAILED]: " + self.result["problem"] + line_col)
                elif (
                    "success" in self.result
                    and util.to_bool(self.result["success"]) == True
                    and "Messages" in self.result
                    and len(self.result["Messages"]) > 0
                ):
                    msg = " [Operation completed Successfully - With Compile Errors]\n"
                    msg += "[COMPILE ERRORS] - Count:\n"
                    for m in self.result["Messages"]:
                        msg += " FileName: " + m["fileName"] + ": " + m["problem"] + "Line: " + m["lineNumber"]
                    self.__print_to_panel(msg)
                elif "success" in self.result and util.to_bool(self.result["success"]) == True:
                    self.__print_to_panel("Success")
                elif (
                    "success" in self.result and util.to_bool(self.result["success"]) == False and "body" in self.result
                ):
                    self.__print_to_panel("[OPERATION FAILED]: " + self.result["body"])
                elif "success" in self.result and util.to_bool(self.result["success"]) == False:
                    self.__print_to_panel("[OPERATION FAILED]")
                else:
                    self.__print_to_panel("Success")
            except Exception as e:
                debug(e)
                debug(type(self.result))
                msg = ""
                if type(self.result) is dict:
                    if "body" in self.result:
                        msg = self.result["body"]
                    else:
                        msg = json.dumps(self.result)
                elif type(self.result) is str:
                    try:
                        m = json.loads(self.result)
                        msg = m["body"]
                    except:
                        msg = self.result
                else:
                    msg = "Check Sublime Text console for error and report issue to MavensMate-SublimeText GitHub project."
                self.__print_to_panel("[OPERATION FAILED]: " + msg)
def handle_result(operation, process_id, printer, result, thread):
    #print(thread.process_id)
    #print(thread.params)
    process_region = printer.panel.find(process_id, 0)
    status_region = printer.panel.find('Result:', process_region.begin())

    try:
        result = json.loads(result)
        if operation == 'compile' and 'actions' in result and util.to_bool(
                result['success']) == False:
            diff_merge_settings = config.settings.get(
                'mm_diff_server_conflicts', False)
            if diff_merge_settings:
                if sublime.ok_cancel_dialog(result["body"],
                                            result["actions"][0].title()):
                    printer.panel.run_command(
                        'write_operation_status', {
                            "text":
                            " Diffing with server",
                            'region':
                            [status_region.end(),
                             status_region.end() + 10]
                        })
                    th = MavensMateDiffThread(thread.window, thread.view,
                                              result['tmp_file_path'])
                    th.start()

                else:
                    printer.panel.run_command(
                        'write_operation_status', {
                            "text":
                            " " + result["actions"][1].title(),
                            'region':
                            [status_region.end(),
                             status_region.end() + 10]
                        })
            else:
                if sublime.ok_cancel_dialog(result["body"],
                                            "Overwrite Server Copy"):
                    printer.panel.run_command(
                        'write_operation_status', {
                            "text":
                            " Overwriting server copy",
                            'region':
                            [status_region.end(),
                             status_region.end() + 10]
                        })
                    thread.params['action'] = 'overwrite'
                    sublime.set_timeout(
                        lambda: call('compile', params=thread.params), 100)
                else:
                    printer.panel.run_command(
                        'write_operation_status', {
                            "text":
                            " " + result["actions"][1].title(),
                            'region':
                            [status_region.end(),
                             status_region.end() + 10]
                        })

        else:
            print_result_message(operation, process_id, status_region, result,
                                 printer, thread)
            if operation == 'new_metadata' and 'success' in result and util.to_bool(
                    result['success']) == True:
                if 'messages' in result:
                    if type(result['messages']) is not list:
                        result['messages'] = [result['messages']]
                    for m in result['messages']:
                        if 'package.xml' not in m['fileName']:
                            file_name = m['fileName']
                            location = util.mm_project_directory(
                            ) + "/" + file_name.replace('unpackaged/', 'src/')
                            sublime.active_window().open_file(location)
                            break
            if 'success' in result and util.to_bool(result['success']) == True:
                if printer != None and len(
                        ThreadTracker.get_pending_mm_panel_threads(
                            thread.window)) == 0:
                    printer.hide()
            elif 'State' in result and result['State'] == 'Completed' and len(
                    ThreadTracker.get_pending_mm_panel_threads(
                        thread.window)) == 0:
                #tooling api
                if printer != None:
                    printer.hide()
            if operation == 'refresh':
                sublime.set_timeout(
                    lambda: sublime.active_window().active_view().run_command(
                        'revert'), 200)
                util.clear_marked_line_numbers()
    except AttributeError:
        if printer != None:
            printer.write('\n[RESPONSE FROM MAVENSMATE]: ' + result + '\n')
            msg = ' [OPERATION FAILED]: Whoops, unable to parse the response. Please report this issue at https://github.com/joeferraro/MavensMate-SublimeText\n'
            msg += '[RESPONSE FROM MAVENSMATE]: ' + result
            printer.panel.run_command(
                'write_operation_status', {
                    'text': msg,
                    'region': [status_region.end(),
                               status_region.end() + 10]
                })
    except Exception:
        if printer != None:
            printer.write('\n[RESPONSE FROM MAVENSMATE]: ' + result + '\n')
            msg = ' [OPERATION FAILED]: Whoops, unable to parse the response. Please report this issue at https://github.com/joeferraro/MavensMate-SublimeText\n'
            msg += '[RESPONSE FROM MAVENSMATE]: ' + result
            printer.panel.run_command(
                'write_operation_status', {
                    'text': msg,
                    'region': [status_region.end(),
                               status_region.end() + 10]
                })