Closes #1224, see #1209. Improve error handling of Debug helper

This commit is contained in:
Glavin Wiechert 2016-09-25 15:10:59 -03:00
parent 803c35dfa4
commit db5469b73e
2 changed files with 235 additions and 221 deletions

View File

@ -124,7 +124,7 @@
"coffee-formatter": "^0.1.2", "coffee-formatter": "^0.1.2",
"coffee-script": "^1.10.0", "coffee-script": "^1.10.0",
"csscomb": "^3.1.7", "csscomb": "^3.1.7",
"diff": "^3.0.0", "diff": "3.0.0",
"editorconfig": "^0.13.2", "editorconfig": "^0.13.2",
"event-kit": "^2.1.0", "event-kit": "^2.1.0",
"expand-home-dir": "0.0.3", "expand-home-dir": "0.0.3",
@ -297,4 +297,4 @@
"lint": "coffeelint src/ spec/", "lint": "coffeelint src/ spec/",
"code-docs": "codo && open docs/code/index.html" "code-docs": "codo && open docs/code/index.html"
} }
} }

View File

@ -281,239 +281,253 @@ beautifyDirectory = ({target}) ->
return return
debug = () -> debug = () ->
try
open = require("open")
fs ?= require "fs"
GitHubApi = require("github")
github = new GitHubApi()
open = require("open") plugin.checkUnsupportedOptions()
fs ?= require "fs"
GitHubApi = require("github")
github = new GitHubApi()
plugin.checkUnsupportedOptions() # Get current editor
editor = atom.workspace.getActiveTextEditor()
# Get current editor linkifyTitle = (title) ->
editor = atom.workspace.getActiveTextEditor() title = title.toLowerCase()
p = title.split(/[\s,+#;,\/?:@&=+$]+/) # split into parts
sep = "-"
p.join(sep)
linkifyTitle = (title) -> # Check if there is an active editor
title = title.toLowerCase() if not editor?
p = title.split(/[\s,+#;,\/?:@&=+$]+/) # split into parts return confirm("Active Editor not found.\n" +
sep = "-" "Please select a Text Editor first to beautify.")
p.join(sep) return unless confirm('Are you ready to debug Atom Beautify?\n\n'+
'Warning: This will create an anonymous Gist on GitHub (publically accessible and cannot be easily deleted) '+
'containing the contents of your active Text Editor.\n'+
'Be sure to delete any private text from your active Text Editor before continuing '+
'to ensure you are not sharing undesirable private information.')
debugInfo = ""
headers = []
tocEl = "<TABLEOFCONTENTS/>"
addInfo = (key, val) ->
if key?
debugInfo += "**#{key}**: #{val}\n\n"
else
debugInfo += "#{val}\n\n"
addHeader = (level, title) ->
debugInfo += "#{Array(level+1).join('#')} #{title}\n\n"
headers.push({
level, title
})
addHeader(1, "Atom Beautify - Debugging information")
debugInfo += "The following debugging information was " +
"generated by `Atom Beautify` on `#{new Date()}`." +
"\n\n---\n\n" +
tocEl +
"\n\n---\n\n"
# Check if there is an active editor # Platform
if not editor? addInfo('Platform', process.platform)
return confirm("Active Editor not found.\n" + addHeader(2, "Versions")
"Please select a Text Editor first to beautify.")
return unless confirm('Are you ready to debug Atom Beautify?\n\n'+
'Warning: This will create an anonymous Gist on GitHub (publically accessible and cannot be easily deleted) '+
'containing the contents of your active Text Editor.\n'+
'Be sure to delete any private text from your active Text Editor before continuing '+
'to ensure you are not sharing undesirable private information.')
debugInfo = ""
headers = []
tocEl = "<TABLEOFCONTENTS/>"
addInfo = (key, val) ->
if key?
debugInfo += "**#{key}**: #{val}\n\n"
else
debugInfo += "#{val}\n\n"
addHeader = (level, title) ->
debugInfo += "#{Array(level+1).join('#')} #{title}\n\n"
headers.push({
level, title
})
addHeader(1, "Atom Beautify - Debugging information")
debugInfo += "The following debugging information was " +
"generated by `Atom Beautify` on `#{new Date()}`." +
"\n\n---\n\n" +
tocEl +
"\n\n---\n\n"
# Platform
addInfo('Platform', process.platform)
addHeader(2, "Versions")
# Atom Version # Atom Version
addInfo('Atom Version', atom.appVersion) addInfo('Atom Version', atom.appVersion)
# Atom Beautify Version # Atom Beautify Version
addInfo('Atom Beautify Version', pkg.version) addInfo('Atom Beautify Version', pkg.version)
addHeader(2, "Original file to be beautified") addHeader(2, "Original file to be beautified")
# Original file # Original file
#
# Get editor path and configurations for paths
filePath = editor.getPath()
# Path
addInfo('Original File Path', "`#{filePath}`")
# Get Grammar
grammarName = editor.getGrammar().name
# Grammar
addInfo('Original File Grammar', grammarName)
# Language
language = beautifier.getLanguage(grammarName, filePath)
addInfo('Original File Language', language?.name)
addInfo('Language namespace', language?.namespace)
# Beautifier
beautifiers = beautifier.getBeautifiers(language.name)
addInfo('Supported Beautifiers', _.map(beautifiers, 'name').join(', '))
selectedBeautifier = beautifier.getBeautifierForLanguage(language)
addInfo('Selected Beautifier', selectedBeautifier.name)
# Get current editor's text
text = editor.getText()
# Contents
codeBlockSyntax = (language?.name ? grammarName).toLowerCase().split(' ')[0]
addHeader(3, 'Original File Contents')
addInfo(null, "\n```#{codeBlockSyntax}\n#{text}\n```")
addHeader(3, 'Package Settings')
addInfo(null,
"The raw package settings options\n" +
"```json\n#{JSON.stringify(atom.config.get('atom-beautify'), undefined, 4)}\n```")
# Beautification Options
addHeader(2, "Beautification options")
# Get all options
allOptions = beautifier.getOptionsForPath(filePath, editor)
# Resolve options with promises
Promise.all(allOptions)
.then((allOptions) ->
# Extract options
[
editorOptions
configOptions
homeOptions
editorConfigOptions
] = allOptions
projectOptions = allOptions[4..]
preTransformedOptions = beautifier.getOptionsForLanguage(allOptions, language)
if selectedBeautifier
finalOptions = beautifier.transformOptions(selectedBeautifier, language.name, preTransformedOptions)
# Show options
# addInfo('All Options', "\n" +
# "All options extracted for file\n" +
# "```json\n#{JSON.stringify(allOptions, undefined, 4)}\n```")
addInfo('Editor Options', "\n" +
"Options from Atom Editor settings\n" +
"```json\n#{JSON.stringify(editorOptions, undefined, 4)}\n```")
addInfo('Config Options', "\n" +
"Options from Atom Beautify package settings\n" +
"```json\n#{JSON.stringify(configOptions, undefined, 4)}\n```")
addInfo('Home Options', "\n" +
"Options from `#{path.resolve(beautifier.getUserHome(), '.jsbeautifyrc')}`\n" +
"```json\n#{JSON.stringify(homeOptions, undefined, 4)}\n```")
addInfo('EditorConfig Options', "\n" +
"Options from [EditorConfig](http://editorconfig.org/) file\n" +
"```json\n#{JSON.stringify(editorConfigOptions, undefined, 4)}\n```")
addInfo('Project Options', "\n" +
"Options from `.jsbeautifyrc` files starting from directory `#{path.dirname(filePath)}` and going up to root\n" +
"```json\n#{JSON.stringify(projectOptions, undefined, 4)}\n```")
addInfo('Pre-Transformed Options', "\n" +
"Combined options before transforming them given a beautifier's specifications\n" +
"```json\n#{JSON.stringify(preTransformedOptions, undefined, 4)}\n```")
if selectedBeautifier
addHeader(3, 'Final Options')
addInfo(null,
"Final combined and transformed options that are used\n" +
"```json\n#{JSON.stringify(finalOptions, undefined, 4)}\n```")
# #
logs = "" # Get editor path and configurations for paths
logFilePathRegex = new RegExp('\\: \\[(.*)\\]') filePath = editor.getPath()
subscription = logger.onLogging((msg) ->
# console.log('logging', msg) # Path
sep = path.sep addInfo('Original File Path', "`#{filePath}`")
logs += msg.replace(logFilePathRegex, (a,b) ->
s = b.split(sep) # Get Grammar
i = s.indexOf('atom-beautify') grammarName = editor.getGrammar().name
p = s.slice(i+2).join(sep)
# console.log('logging', arguments, s, i, p) # Grammar
return ': ['+p+']' addInfo('Original File Grammar', grammarName)
# Language
language = beautifier.getLanguage(grammarName, filePath)
addInfo('Original File Language', language?.name)
addInfo('Language namespace', language?.namespace)
# Beautifier
beautifiers = beautifier.getBeautifiers(language.name)
addInfo('Supported Beautifiers', _.map(beautifiers, 'name').join(', '))
selectedBeautifier = beautifier.getBeautifierForLanguage(language)
addInfo('Selected Beautifier', selectedBeautifier.name)
# Get current editor's text
text = editor.getText() or ""
# Contents
codeBlockSyntax = (language?.name ? grammarName).toLowerCase().split(' ')[0]
addHeader(3, 'Original File Contents')
addInfo(null, "\n```#{codeBlockSyntax}\n#{text}\n```")
addHeader(3, 'Package Settings')
addInfo(null,
"The raw package settings options\n" +
"```json\n#{JSON.stringify(atom.config.get('atom-beautify'), undefined, 4)}\n```")
# Beautification Options
addHeader(2, "Beautification options")
# Get all options
allOptions = beautifier.getOptionsForPath(filePath, editor)
# Resolve options with promises
Promise.all(allOptions)
.then((allOptions) ->
# Extract options
[
editorOptions
configOptions
homeOptions
editorConfigOptions
] = allOptions
projectOptions = allOptions[4..]
preTransformedOptions = beautifier.getOptionsForLanguage(allOptions, language)
if selectedBeautifier
finalOptions = beautifier.transformOptions(selectedBeautifier, language.name, preTransformedOptions)
# Show options
# addInfo('All Options', "\n" +
# "All options extracted for file\n" +
# "```json\n#{JSON.stringify(allOptions, undefined, 4)}\n```")
addInfo('Editor Options', "\n" +
"Options from Atom Editor settings\n" +
"```json\n#{JSON.stringify(editorOptions, undefined, 4)}\n```")
addInfo('Config Options', "\n" +
"Options from Atom Beautify package settings\n" +
"```json\n#{JSON.stringify(configOptions, undefined, 4)}\n```")
addInfo('Home Options', "\n" +
"Options from `#{path.resolve(beautifier.getUserHome(), '.jsbeautifyrc')}`\n" +
"```json\n#{JSON.stringify(homeOptions, undefined, 4)}\n```")
addInfo('EditorConfig Options', "\n" +
"Options from [EditorConfig](http://editorconfig.org/) file\n" +
"```json\n#{JSON.stringify(editorConfigOptions, undefined, 4)}\n```")
addInfo('Project Options', "\n" +
"Options from `.jsbeautifyrc` files starting from directory `#{path.dirname(filePath)}` and going up to root\n" +
"```json\n#{JSON.stringify(projectOptions, undefined, 4)}\n```")
addInfo('Pre-Transformed Options', "\n" +
"Combined options before transforming them given a beautifier's specifications\n" +
"```json\n#{JSON.stringify(preTransformedOptions, undefined, 4)}\n```")
if selectedBeautifier
addHeader(3, 'Final Options')
addInfo(null,
"Final combined and transformed options that are used\n" +
"```json\n#{JSON.stringify(finalOptions, undefined, 4)}\n```")
#
logs = ""
logFilePathRegex = new RegExp('\\: \\[(.*)\\]')
subscription = logger.onLogging((msg) ->
# console.log('logging', msg)
sep = path.sep
logs += msg.replace(logFilePathRegex, (a,b) ->
s = b.split(sep)
i = s.indexOf('atom-beautify')
p = s.slice(i+2).join(sep)
# console.log('logging', arguments, s, i, p)
return ': ['+p+']'
)
) )
cb = (result) ->
subscription.dispose()
addHeader(2, "Results")
# Logs
addInfo('Beautified File Contents', "\n```#{codeBlockSyntax}\n#{result}\n```")
# Diff
JsDiff = require('diff')
if typeof result is "string"
diff = JsDiff.createPatch(filePath or "", text or "", \
result or "", "original", "beautified")
addInfo('Original vs. Beautified Diff', "\n```#{codeBlockSyntax}\n#{diff}\n```")
addHeader(3, "Logs")
addInfo(null, "```\n#{logs}\n```")
# Build Table of Contents
toc = "## Table Of Contents\n"
for header in headers
###
- Heading 1
- Heading 1.1
###
indent = " " # 2 spaces
bullet = "-"
indentNum = header.level - 2
if indentNum >= 0
toc += ("#{Array(indentNum+1).join(indent)}#{bullet} [#{header.title}](\##{linkifyTitle(header.title)})\n")
# Replace TABLEOFCONTENTS
debugInfo = debugInfo.replace(tocEl, toc)
# Save to clipboard
# atom.clipboard.write(debugInfo)
github.gists.create({
files: {
"debug.md": {
"content": debugInfo
}
},
public: true,
description: "Atom-Beautify debugging information"
}, (err, res) ->
# console.log(err, res)
if err
confirm("An error occurred when creating the Gist: "+err)
else
gistUrl = res.html_url
# Create Gist
open(gistUrl)
confirm("Your Atom Beautify debugging information can be found in the public Gist:\n#{res.html_url}\n\n" +
# 'You can now paste this into an Issue you are reporting here\n' +
# 'https://github.com/Glavin001/atom-beautify/issues/\n\n' +
# 'Please follow the contribution guidelines found at\n' +
# 'https://github.com/Glavin001/atom-beautify/blob/master/CONTRIBUTING.md\n\n' +
'Warning: Be sure to look over the debug info before you send it '+
'to ensure you are not sharing undesirable private information.\n\n'+
'If you want to delete this anonymous Gist read\n'+
'https://help.github.com/articles/deleting-an-anonymous-gist/'
)
# Create GitHub Issue
return unless confirm("Would you like to create a new Issue on GitHub now?")
issueTemplate = fs.readFileSync(path.resolve(__dirname, "../ISSUE_TEMPLATE.md")).toString()
body = issueTemplate.replace("<INSERT GIST HERE>", gistUrl)#.replace("<INSERT CODE HERE>", text)
open("https://github.com/Glavin001/atom-beautify/issues/new?body=#{encodeURIComponent(body)}")
)
try
beautifier.beautify(text, allOptions, grammarName, filePath)
.then(cb)
.catch(cb)
catch e
return cb(e)
) )
cb = (result) -> .catch((error) ->
subscription.dispose() stack = error.stack
addHeader(2, "Results") detail = error.description or error.message
atom?.notifications?.addError(error.message, {
# Logs stack, detail, dismissable : true
addInfo('Beautified File Contents', "\n```#{codeBlockSyntax}\n#{result}\n```") })
# Diff )
JsDiff = require('diff') catch error
diff = JsDiff.createPatch(filePath, text, \ stack = error.stack
result, "original", "beautified") detail = error.description or error.message
addInfo('Original vs. Beautified Diff', "\n```#{codeBlockSyntax}\n#{diff}\n```") atom?.notifications?.addError(error.message, {
stack, detail, dismissable : true
addHeader(3, "Logs") })
addInfo(null, "```\n#{logs}\n```")
# Build Table of Contents
toc = "## Table Of Contents\n"
for header in headers
###
- Heading 1
- Heading 1.1
###
indent = " " # 2 spaces
bullet = "-"
indentNum = header.level - 2
if indentNum >= 0
toc += ("#{Array(indentNum+1).join(indent)}#{bullet} [#{header.title}](\##{linkifyTitle(header.title)})\n")
# Replace TABLEOFCONTENTS
debugInfo = debugInfo.replace(tocEl, toc)
# Save to clipboard
# atom.clipboard.write(debugInfo)
github.gists.create({
files: {
"debug.md": {
"content": debugInfo
}
},
public: true,
description: "Atom-Beautify debugging information"
}, (err, res) ->
# console.log(err, res)
if err
confirm("An error occurred when creating the Gist: "+err)
else
gistUrl = res.html_url
# Create Gist
open(gistUrl)
confirm("Your Atom Beautify debugging information can be found in the public Gist:\n#{res.html_url}\n\n" +
# 'You can now paste this into an Issue you are reporting here\n' +
# 'https://github.com/Glavin001/atom-beautify/issues/\n\n' +
# 'Please follow the contribution guidelines found at\n' +
# 'https://github.com/Glavin001/atom-beautify/blob/master/CONTRIBUTING.md\n\n' +
'Warning: Be sure to look over the debug info before you send it '+
'to ensure you are not sharing undesirable private information.\n\n'+
'If you want to delete this anonymous Gist read\n'+
'https://help.github.com/articles/deleting-an-anonymous-gist/'
)
# Create GitHub Issue
return unless confirm("Would you like to create a new Issue on GitHub now?")
issueTemplate = fs.readFileSync(path.resolve(__dirname, "../ISSUE_TEMPLATE.md")).toString()
body = issueTemplate.replace("<INSERT GIST HERE>", gistUrl)#.replace("<INSERT CODE HERE>", text)
open("https://github.com/Glavin001/atom-beautify/issues/new?body=#{encodeURIComponent(body)}")
)
try
beautifier.beautify(text, allOptions, grammarName, filePath)
.then(cb)
.catch(cb)
catch e
return cb(e)
)
handleSaveEvent = -> handleSaveEvent = ->
atom.workspace.observeTextEditors (editor) -> atom.workspace.observeTextEditors (editor) ->