<commit_before>from gosubl import about
from gosubl import ev
from gosubl import gs
from gosubl import gsq
from gosubl import sh
import atexit
import base64
import hashlib
import json
import os
import re
import shutil
import sublime
import subprocess
import threading
import time

DOMAIN = 'MarGo'
REQUEST_PREFIX = '%s.rqst.' % DOMAIN
PROC_ATTR_NAME = 'mg9.proc'
TAG = about.VERSION
INSTALL_VERSION = about.VERSION

def gs_init(m={}):
	atexit.register(killSrv)
	gsq.do('GoSublime', _install, msg='Installing MarGo', set_status=False)

class Request(object):
	def __init__(self, f, method='', token=''):
		self.f = f
		self.tm = time.time()
		self.method = method
		if token:
			self.token = token
		else:
			self.token = gs.uid()

	def header(self):
		return {
			'method': self.method,
			'token': self.token,
		}

def _inst_state():
	return gs.attr(_inst_name(), '')

def _inst_name():
	return 'mg9.install.%s' % INSTALL_VERSION

def sanity_check_sl(sl):
	n = 0
	for p in sl:
		n = max(n, len(p[0]))

	t = '%d' % n
	t = '| %'+t+'s: %s'
	indent = '| %s> ' % (' ' * n)

	a = '~%s' % os.sep
	b = os.path.expanduser(a)

	return [t % (k, gs.ustr(v).replace(b, a).replace('\n', '\n%s' % indent)) for k,v in sl]

def sanity_check(env={}, error_log=False):
	if not env:
		env = sh.env()

	ns = '(not set)'

	sl = [
		('install state', _inst_state()),
		('sublime.version', sublime.version()),
		('sublime.channel', sublime.channel()),
		('about.ann', gs.attr('about.ann', '')),
		('about.version', gs.attr('about.version', '')),
		('version', about.VERSION),
		('platform', about.PLATFORM),
		('~bin', '%s' % sh.bin_dir()),
		('go.exe', '%s (%s)' % _tp(sh.which('go') or 'go')),
		('margo.exe', '%s (%s)' % _tp(sh.which('margo') or 'margo')),
		('go.version', sh.GO_VERSION),
		('GOROOT', '%s' % env.get('GOROOT', ns)),
		('GOPATH', '%s' % env.get('GOPATH', ns)),
		('GOBIN', env.get('GOBIN', ns)),
		('set.shell', str(gs.lst(gs.setting('shell')))),
		('env.shell', env.get('SHELL', '')),
		('shell.cmd', str(sh.cmd('${CMD}'))),
	]

	if error_log:
		try:
			with open(gs.home_path('log.txt'), 'r') as f:
				s = f.read().strip()
				sl.append(('error log', s))
		except Exception:
			pass

	return sl

def _sb(s):
	bdir = sh.bin_dir()
	if s.startswith(bdir):
		s = '~bin%s' % (s[len(bdir):])
	return s

def _tp(s):
	return (_sb(s), ('ok' if os.path.exists(s) else 'missing'))

def _mg_exists():
	return bool(sh.which('margo'))

def build_mg(force=False):
	if force:
		pass
	elif gs.setting('_rebuild'):
		print('GoSublime: `_rebuild` is set')
	elif _mg_exists():
		return 'ok'

	gs.notify('GoSublime', 'Installing MarGo')

	gobin = sh.bin_dir()
	gopath = gs.dist_path()
	wd = gobin
	env = {
		'CGO_ENABLED': '0',
		'GOBIN': gobin,
		'GOPATH': gopath,
	}

	# do a cleanup just-in-case there are old packages lying around... we don't really care if it fails
	clean = sh.Command(['go', 'clean', '-i', 'gosubli.me/...'])
	clean.wd = wd
	clean.env = env
	clean.run()

	f = gs.setting('_build_flags') or ['-v', '-x']
	args = gs.lst('go', 'build', f, '-o', sh.exe('margo'), 'gosubli.me/margo')

	build = sh.Command(args)
	build.wd = wd
	build.env = env

	ev.debug('%s.build' % DOMAIN, {
		'cmd': build.cmd_lst,
		'cwd': build.wd,
	})

	cr = build.run()

	if cr.ok and _mg_exists():
		return 'ok'

	m_out = 'cmd: `%s`\nstdout: `%s`\nstderr: `%s`\nexception: `%s`' % (
		cr.cmd_lst,
		cr.out.strip(),
		cr.err.strip(),
		cr.exc,
	)

	err_prefix = 'MarGo build failed'
	gs.error(DOMAIN, '%s\n%s' % (err_prefix, m_out))

	sl = [
		('GoSublime error', '\n'.join((
			err_prefix,
			'This is possibly a bug or miss-configuration of your environment.',
			'For more help, please file an issue with the following build output',
			'at: https://github.com/DisposaBoy/GoSublime/issues/new',
			'or alternatively, you may send an email to: <EMAIL>',
			'\n',
			m_out,
		)))
	]
	sl.extend(sanity_check({}, False))
	gs.show_output('GoSublime', '\n'.join(sanity_check_sl(sl)))

	return m_out

def _install(maybe=False):
	if _inst_state() != "":
		return

	start = time.time()

	gs.set_attr(_inst_name(), 'busy')
	m_out = build_mg()
	gs.set_attr(_inst_name(), 'done')

	if m_out == 'ok':
		gs.notify('GoSublime', 'ready')

		if maybe:
			return

	e = sh.env()
	a = [
		'GoSublime init %s (%0.3fs)' % (INSTALL_VERSION, time.time() - start),
	]<commit_msg>* call ev.margo_ready when we're done installing margo<commit_after>from gosubl import about
from gosubl import ev
from gosubl import gs
from gosubl import gsq
from gosubl import sh
import atexit
import base64
import hashlib
import json
import os
import re
import shutil
import sublime
import subprocess
import threading
import time

DOMAIN = 'MarGo'
REQUEST_PREFIX = '%s.rqst.' % DOMAIN
PROC_ATTR_NAME = 'mg9.proc'
TAG = about.VERSION
INSTALL_VERSION = about.VERSION

def gs_init(m={}):
	atexit.register(killSrv)
	gsq.do('GoSublime', _install, msg='Installing MarGo', set_status=False)

class Request(object):
	def __init__(self, f, method='', token=''):
		self.f = f
		self.tm = time.time()
		self.method = method
		if token:
			self.token = token
		else:
			self.token = gs.uid()

	def header(self):
		return {
			'method': self.method,
			'token': self.token,
		}

def _inst_state():
	return gs.attr(_inst_name(), '')

def _inst_name():
	return 'mg9.install.%s' % INSTALL_VERSION

def sanity_check_sl(sl):
	n = 0
	for p in sl:
		n = max(n, len(p[0]))

	t = '%d' % n
	t = '| %'+t+'s: %s'
	indent = '| %s> ' % (' ' * n)

	a = '~%s' % os.sep
	b = os.path.expanduser(a)

	return [t % (k, gs.ustr(v).replace(b, a).replace('\n', '\n%s' % indent)) for k,v in sl]

def sanity_check(env={}, error_log=False):
	if not env:
		env = sh.env()

	ns = '(not set)'

	sl = [
		('install state', _inst_state()),
		('sublime.version', sublime.version()),
		('sublime.channel', sublime.channel()),
		('about.ann', gs.attr('about.ann', '')),
		('about.version', gs.attr('about.version', '')),
		('version', about.VERSION),
		('platform', about.PLATFORM),
		('~bin', '%s' % sh.bin_dir()),
		('go.exe', '%s (%s)' % _tp(sh.which('go') or 'go')),
		('margo.exe', '%s (%s)' % _tp(sh.which('margo') or 'margo')),
		('go.version', sh.GO_VERSION),
		('GOROOT', '%s' % env.get('GOROOT', ns)),
		('GOPATH', '%s' % env.get('GOPATH', ns)),
		('GOBIN', env.get('GOBIN', ns)),
		('set.shell', str(gs.lst(gs.setting('shell')))),
		('env.shell', env.get('SHELL', '')),
		('shell.cmd', str(sh.cmd('${CMD}'))),
	]

	if error_log:
		try:
			with open(gs.home_path('log.txt'), 'r') as f:
				s = f.read().strip()
				sl.append(('error log', s))
		except Exception:
			pass

	return sl

def _sb(s):
	bdir = sh.bin_dir()
	if s.startswith(bdir):
		s = '~bin%s' % (s[len(bdir):])
	return s

def _tp(s):
	return (_sb(s), ('ok' if os.path.exists(s) else 'missing'))

def _mg_exists():
	return bool(sh.which('margo'))

def build_mg(force=False):
	if force:
		pass
	elif gs.setting('_rebuild'):
		print('GoSublime: `_rebuild` is set')
	elif _mg_exists():
		return 'ok'

	gs.notify('GoSublime', 'Installing MarGo')

	gobin = sh.bin_dir()
	gopath = gs.dist_path()
	wd = gobin
	env = {
		'CGO_ENABLED': '0',
		'GOBIN': gobin,
		'GOPATH': gopath,
	}

	# do a cleanup just-in-case there are old packages lying around... we don't really care if it fails
	clean = sh.Command(['go', 'clean', '-i', 'gosubli.me/...'])
	clean.wd = wd
	clean.env = env
	clean.run()

	f = gs.setting('_build_flags') or ['-v', '-x']
	args = gs.lst('go', 'build', f, '-o', sh.exe('margo'), 'gosubli.me/margo')

	build = sh.Command(args)
	build.wd = wd
	build.env = env

	ev.debug('%s.build' % DOMAIN, {
		'cmd': build.cmd_lst,
		'cwd': build.wd,
	})

	cr = build.run()

	if cr.ok and _mg_exists():
		return 'ok'

	m_out = 'cmd: `%s`\nstdout: `%s`\nstderr: `%s`\nexception: `%s`' % (
		cr.cmd_lst,
		cr.out.strip(),
		cr.err.strip(),
		cr.exc,
	)

	err_prefix = 'MarGo build failed'
	gs.error(DOMAIN, '%s\n%s' % (err_prefix, m_out))

	sl = [
		('GoSublime error', '\n'.join((
			err_prefix,
			'This is possibly a bug or miss-configuration of your environment.',
			'For more help, please file an issue with the following build output',
			'at: https://github.com/DisposaBoy/GoSublime/issues/new',
			'or alternatively, you may send an email to: <EMAIL>',
			'\n',
			m_out,
		)))
	]
	sl.extend(sanity_check({}, False))
	gs.show_output('GoSublime', '\n'.join(sanity_check_sl(sl)))

	return m_out

def _install(maybe=False):
	if _inst_state() != "":
		return

	start = time.time()

	gs.set_attr(_inst_name(), 'busy')
	m_out = build_mg()
	gs.set_attr(_inst_name(), 'done')

	if m_out == 'ok':
		ev.margo_ready()
		gs.notify('GoSublime', 'ready')

		if maybe:
			return

	e = sh.env()
	a = [
		'GoSublime init %s (%0.3fs)' % (INSTALL_VERSION, time.time() - start),
	]
{'fraction_non_alphanumeric': 0.20679366536607757, 'fraction_numerical': 0.0020656414964425065, 'mean_word_length': 3.822910902047593, 'pattern_counts': {'":': 2, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2429161', 'n_tokens_mistral': 3860, 'n_tokens_neox': 3616, 'n_words': 850}