├── .gitignore ├── LICENSE ├── README.md ├── bin ├── gistup ├── gistup-open └── gistup-rename ├── lib └── gistup │ ├── api.js │ ├── get-settings.js │ ├── quote.js │ ├── unless.js │ └── user-error.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, Michael Bostock 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * The name Michael Bostock may not be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL MICHAEL BOSTOCK BE LIABLE FOR ANY DIRECT, 21 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 22 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 24 | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 26 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Gistup 2 | 3 | Create a gist from the command line! Then just use git to update it. 4 | 5 | For more, read the tutorial: [Let’s Make a Block](http://bost.ocks.org/mike/block/). 6 | 7 | ## Installation 8 | 9 | ```bash 10 | npm install -g gistup 11 | ``` 12 | 13 | The first time you run gistup, you’ll be prompted to create a GitHub *personal access token*. You can revoke the token in the future from your GitHub [developer settings](https://github.com/settings/tokens). 14 | 15 | ## Usage 16 | 17 | To upload all files in the current directory to your new gist: 18 | 19 | ```bash 20 | gistup 21 | ``` 22 | 23 | If you just want to create a gist from a single file, try this instead: 24 | 25 | ```bash 26 | gistup index.html 27 | ``` 28 | 29 | If you specify any options, such as a private gist, you must separate files from options with a double-dash (--) like this: 30 | 31 | ```bash 32 | gistup --private -- index.html 33 | ``` 34 | 35 | If you want to update your gist later, just use git: 36 | 37 | ```bash 38 | edit index.html 39 | git commit -m 'Made some awesome changes.' 40 | git push 41 | ``` 42 | 43 | Gistup works with binary files, too! 44 | 45 | Arguments: 46 | 47 | * --description, -m - provide an optional description 48 | * --interactive, -i - request confirmation of every file before adding 49 | * --exclude, -x - skip files matching pattern; may use wildcards 50 | * --private, --no-public - make a secret gist 51 | * --open [url] - specify the URL to open after creating the gist 52 | * --no-open - don’t open the created gist in your web browser when done 53 | * --remote - specify the name of the git remote 54 | * --help - show some help 55 | * --version - print the current version of gistup 56 | 57 | Gistup comes bundled with two helper programs: `gistup-rename` and `gistup-open`. Use `gistup-rename "description of gist"` to update the description of the gist in the current directory and `gistup-open` to open it for viewing in your default browser. 58 | 59 | ## Troubleshooting 60 | 61 | If you see the following error: 62 | 63 | ``` 64 | Error: Command failed: Permission denied (publickey). 65 | fatal: Could not read from remote repository. 66 | 67 | Please make sure you have the correct access rights and the repository exists. 68 | ``` 69 | 70 | You probably need to [generate your SSH keys](https://help.github.com/articles/generating-ssh-keys) for GitHub. These keys give you permission to git push to your repositories, including Gists. 71 | 72 | If you’re unable to follow the first-time setup to create a personal access token, you can [create a new access token](https://github.com/settings/tokens/new) by hand. The only required permission is "gist". You can then create a .gistup.json file in your home directory, with the following contents: 73 | 74 | ```json 75 | { 76 | "token": "0123456789012345678901234567890123456789" 77 | } 78 | ``` 79 | 80 | Replace the numbers 0123456789… with your access token and save. 81 | -------------------------------------------------------------------------------- /bin/gistup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var os = require("os"), 4 | child = require("child_process"), 5 | readline = require("readline"); 6 | 7 | var queue = require("queue-async"), 8 | optimist = require("optimist"); 9 | 10 | var quote = require("../lib/gistup/quote"), 11 | getSettings = require("../lib/gistup/get-settings"), 12 | unless = require("../lib/gistup/unless"), 13 | api = require("../lib/gistup/api"), 14 | UserError = require("../lib/gistup/user-error"); 15 | 16 | var argv = optimist.usage("Usage: \033[1mgistup\033[0m [options] -- [file …]" + os.EOL + os.EOL 17 | 18 | + "Version: " + require("../package.json").version + os.EOL + os.EOL 19 | 20 | + "Uploads the specified files to create a new Gist. If no files are specified," + os.EOL 21 | + "all files in the current directory are uploaded.") 22 | .options("public", { 23 | default: true, 24 | describe: "true for a public gist; false for a secret one" 25 | }) 26 | .options("private", { 27 | default: false, 28 | describe: "alias for --no-public" 29 | }) 30 | .options("description", { 31 | alias: "m", 32 | default: "", 33 | describe: "an optional description for your gist" 34 | }) 35 | .options("interactive", { 36 | alias: "i", 37 | default: false, 38 | describe: "request confirmation of every file before adding" 39 | }) 40 | .options("exclude", { 41 | alias: "x", 42 | default: ".DS_Store", 43 | describe: "skip files matching pattern; may use wildcards" 44 | }) 45 | .options("open", { 46 | default: "https://gist.github.com/", 47 | describe: "URL to open in your web browser after creating gist" 48 | }) 49 | .options("remote", { 50 | default: "origin", 51 | describe: "name of the git remote" 52 | }) 53 | .options("version", { 54 | default: false, 55 | describe: "print the current version of gistup" 56 | }) 57 | .options("help", { 58 | alias: "h", 59 | describe: "display this useful message" 60 | }) 61 | .check(function(argv) { 62 | if (argv.help) optimist.showHelp(), process.exit(0); 63 | if (argv.version) console.log(require("../package.json").version), process.exit(0); 64 | if (argv.private) argv.public = false; 65 | if (argv.exclude === false) argv.exclude = []; 66 | else if (!Array.isArray(argv.exclude)) argv.exclude = [argv.exclude]; 67 | }) 68 | .argv; 69 | 70 | queue(1) 71 | .defer(getSettings) 72 | .defer(gitInit) 73 | .defer(gitRemoteDoesNotExist) 74 | .defer(gitListUntrackedFiles) 75 | .await(function(error, settings, _, _, files) { 76 | unless(error) 77 | .defer(confirmFiles, files) 78 | .defer(gitAdd, files) 79 | .defer(gitCommit) 80 | .defer(createGist, settings.token) 81 | .await(function(error, _, _, _, id) { 82 | unless(error) 83 | .defer(gitRemoteAdd, id) 84 | .defer(gitPush) 85 | .defer(openBrowser, argv.open && settings.open, id) 86 | .await(unless); 87 | }); 88 | }); 89 | 90 | function gitInit(callback) { 91 | child.exec("git init", function(error, stdout, stderr) { 92 | if (!error && stderr) process.stderr.write(stderr), error = new Error("git init failed."); 93 | if (!error && stdout) process.stdout.write(stdout); 94 | callback(error); 95 | }); 96 | } 97 | 98 | function gitRemoteDoesNotExist(callback) { 99 | child.exec("git config --get remote." + quote.single(argv.remote) + ".url || true", function(error, stdout, stderr) { 100 | if (!error && stderr) process.stderr.write(stderr), error = new Error("git config failed."); 101 | if (!error && stdout) error = new UserError("the remote \"" + argv.remote + "\" already exists." + os.EOL + os.EOL + "Are you trying to run gistup in a directory that already has a git" + os.EOL + "repository? This would overwrite your existing remote, which points to:" + os.EOL + os.EOL + " " + stdout + os.EOL + "If you’ve previously run gistup in this directory and you want to update" + os.EOL + "the contents of this gist, just push to the existing git remote:" + os.EOL + os.EOL + " git push" + os.EOL + os.EOL + "Or, if want to rename this gist:" + os.EOL + os.EOL + " gistup-rename 'New Description'" + os.EOL + os.EOL + "If you don’t need this remote anymore (say, if you cloned someone else’s" + os.EOL + "gist), gistup will replace it with a new one if you first run:" + os.EOL + os.EOL + " git remote rm " + argv.remote + os.EOL + os.EOL + "Lastly, you can also specify a different remote name for gistup, so that" + os.EOL + "you can push to multiple git remotes:" + os.EOL + os.EOL + " gistup --remote=gist" + os.EOL + os.EOL + "Please do one of the above and try again."); 102 | callback(error); 103 | }); 104 | } 105 | 106 | function gitListUntrackedFiles(callback) { 107 | if (argv._.length) return void callback(null, argv._); 108 | child.exec("git ls-files --others --exclude-standard --directory" + argv.exclude.map(function(x) { return " -x " + quote.single(x); }) + " -x '*/'", function(error, stdout, stderr) { 109 | if (!error && stderr) process.stderr.write(stderr), error = new Error("git ls-files failed."); 110 | callback(error, error ? null : stdout.split(os.EOL).filter(Boolean)); 111 | }); 112 | } 113 | 114 | function confirmFiles(files, callback) { 115 | if (!argv.interactive) return void callback(null); 116 | var readin = readline.createInterface({ 117 | input: process.stdin, 118 | output: process.stdout 119 | }); 120 | 121 | var q = queue(1); 122 | 123 | files.forEach(function(file) { 124 | q.defer(confirmFile, file); 125 | }); 126 | 127 | q.awaitAll(function(error) { 128 | readin.close(); 129 | callback(error); 130 | }); 131 | 132 | function confirmFile(file, callback) { 133 | readin.question("add " + file + "? ", function(answer) { 134 | if (/^y|yes$/i.test(answer)) return void callback(null); 135 | if (/^n|no$/i.test(answer)) return files.splice(files.indexOf(file), 1), void callback(null); 136 | confirmFile(file, callback); 137 | }); 138 | } 139 | } 140 | 141 | function gitAdd(files, callback) { 142 | if (!files.length) return void callback(null); 143 | child.exec("git add " + files.map(quote.double).join(" "), function(error, stdout, stderr) { 144 | if (!error && stderr) process.stderr.write(stderr), error = new Error("git add failed."); 145 | if (!error && stdout) process.stdout.write(stdout); 146 | callback(error); 147 | }); 148 | } 149 | 150 | function gitCommit(callback) { 151 | child.exec("git commit --allow-empty -m 'Initial gistup commit.'", function(error, stdout, stderr) { 152 | if (!error && stderr) process.stderr.write(stderr), error = new Error("git commit failed."); 153 | if (!error && stdout) process.stdout.write(stdout); 154 | callback(error); 155 | }); 156 | } 157 | 158 | function createGist(token, callback) { 159 | api("POST", "/gists", token, { 160 | "description": argv.description, 161 | "public": argv.public, 162 | "files": { 163 | ".gistup": { 164 | "content": "gistup" 165 | } 166 | } 167 | }, function(error, response) { 168 | var id = null; 169 | if (!error && !/^[0-9a-f]+$/i.test(id = response.id)) error = new Error("invalid gist id: " + id); // for safety 170 | if (!error) { 171 | console.log("gist " + id + " created!"); 172 | console.log(response.html_url); 173 | } 174 | callback(error, id); 175 | }); 176 | } 177 | 178 | function gitRemoteAdd(id, callback) { 179 | child.exec("git remote add --track main " + quote.single(argv.remote) + " git@gist.github.com:" + id + ".git", function(error, stdout, stderr) { 180 | if (!error && stderr) process.stderr.write(stderr), error = new Error("git remote failed."); 181 | if (!error && stdout) process.stdout.write(stdout); 182 | callback(error); 183 | }); 184 | } 185 | 186 | function gitPush(callback) { 187 | child.exec("git push -fu " + quote.single(argv.remote) + " main", function(error, stdout, stderr) { 188 | if (!error && stderr) process.stderr.write(stderr); // ignore warnings 189 | if (!error && stdout) process.stdout.write(stdout); 190 | callback(error); 191 | }); 192 | } 193 | 194 | function openBrowser(open, id, callback) { 195 | if (!open) return void callback(null); 196 | child.exec(open + " " + quote.single(argv.open) + id, function(error, stdout, stderr) { 197 | if (!error && stderr) process.stderr.write(stderr); // ignore errors 198 | callback(null); 199 | }); 200 | } 201 | -------------------------------------------------------------------------------- /bin/gistup-open: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var os = require("os"), 4 | child = require("child_process"); 5 | 6 | var queue = require("queue-async"), 7 | optimist = require("optimist"); 8 | 9 | var quote = require("../lib/gistup/quote"), 10 | getSettings = require("../lib/gistup/get-settings"), 11 | unless = require("../lib/gistup/unless"), 12 | UserError = require("../lib/gistup/user-error"); 13 | 14 | var argv = optimist.usage("Usage: \033[1mgistup-open\033[0m" + os.EOL + os.EOL 15 | 16 | + "Version: " + require("../package.json").version + os.EOL + os.EOL 17 | 18 | + "Opens the gist in the current directory.") 19 | .options("version", { 20 | default: false, 21 | describe: "print the current version of gistup" 22 | }) 23 | .options("open", { 24 | default: "https://gist.github.com/", 25 | describe: "URL to open in your web browser after creating gist" 26 | }) 27 | .options("remote", { 28 | default: "origin", 29 | describe: "name of the git remote" 30 | }) 31 | .options("help", { 32 | alias: "h", 33 | describe: "display this useful message" 34 | }) 35 | .check(function(argv) { 36 | if (argv.help) optimist.showHelp(), process.exit(0); 37 | if (argv.version) console.log(require("../package.json").version), process.exit(0); 38 | if (argv._.length) throw new Error("requires exactly zero arguments"); 39 | }) 40 | .argv; 41 | 42 | queue(1) 43 | .defer(getSettings) 44 | .defer(getGistId) 45 | .await(function(error, settings, id) { 46 | unless(error) 47 | .defer(openBrowser, settings.open, id) 48 | .await(unless); 49 | }); 50 | 51 | function getGistId(callback) { 52 | child.exec("git config --get remote." + quote.single(argv.remote) + ".url", function(error, stdout, stderr) { 53 | if (!error && stderr) process.stderr.write(stderr), error = new Error("git config failed."); 54 | if (error) return void callback(error); 55 | var match = /^git@gist\.github\.com:([0-9a-f]+)\.git$/.exec(stdout = stdout.trim()); 56 | if (!match) return void callback(new UserError("the remote \"" + argv.remote + "\" looks funny." + os.EOL + "I was expecting something like" + os.EOL + os.EOL + " git@gist.github.com:123456789.git" + os.EOL + os.EOL + "but instead the remote URL is" + os.EOL + os.EOL + " " + stdout + os.EOL + os.EOL + "so I’m giving up. Sorry.")); 57 | callback(null, match[1]); 58 | }); 59 | } 60 | 61 | function openBrowser(open, id, callback) { 62 | child.exec(open + " " + quote.single(argv.open) + id, callback); 63 | } 64 | -------------------------------------------------------------------------------- /bin/gistup-rename: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var os = require("os"), 4 | child = require("child_process"); 5 | 6 | var queue = require("queue-async"), 7 | optimist = require("optimist"); 8 | 9 | var quote = require("../lib/gistup/quote"), 10 | getSettings = require("../lib/gistup/get-settings"), 11 | unless = require("../lib/gistup/unless"), 12 | api = require("../lib/gistup/api"), 13 | UserError = require("../lib/gistup/user-error"); 14 | 15 | var argv = optimist.usage("Usage: \033[1mgistup-rename\033[0m description" + os.EOL + os.EOL 16 | 17 | + "Version: " + require("../package.json").version + os.EOL + os.EOL 18 | 19 | + "Updates the description of the gist in the current directory.") 20 | .options("version", { 21 | default: false, 22 | describe: "print the current version of gistup" 23 | }) 24 | .options("remote", { 25 | default: "origin", 26 | describe: "name of the git remote" 27 | }) 28 | .options("help", { 29 | alias: "h", 30 | describe: "display this useful message" 31 | }) 32 | .check(function(argv) { 33 | if (argv.help) optimist.showHelp(), process.exit(0); 34 | if (argv.version) console.log(require("../package.json").version), process.exit(0); 35 | if (argv._.length !== 1) throw new Error("requires exactly one argument"); 36 | }) 37 | .argv; 38 | 39 | queue(1) 40 | .defer(getSettings) 41 | .defer(getGistId) 42 | .await(function(error, settings, id) { 43 | unless(error) 44 | .defer(renameGist, settings.token, id) 45 | .await(unless); 46 | }); 47 | 48 | function getGistId(callback) { 49 | child.exec("git config --get remote." + quote.single(argv.remote) + ".url", function(error, stdout, stderr) { 50 | if (!error && stderr) process.stderr.write(stderr), error = new Error("git config failed."); 51 | if (error) return void callback(error); 52 | var match = /^git@gist\.github\.com:([0-9a-f]+)\.git$/.exec(stdout = stdout.trim()); 53 | if (!match) return void callback(new UserError("the remote \"" + argv.remote + "\" looks funny." + os.EOL + "I was expecting something like" + os.EOL + os.EOL + " git@gist.github.com:123456789.git" + os.EOL + os.EOL + "but instead the remote URL is" + os.EOL + os.EOL + " " + stdout + os.EOL + os.EOL + "so I’m giving up. Sorry.")); 54 | callback(null, match[1]); 55 | }); 56 | } 57 | 58 | function renameGist(token, id, callback) { 59 | api("PATCH", "/gists/" + id, token, { 60 | "description": argv._[0] 61 | }, function(error, response) { 62 | if (!error) console.log("gist " + id + " renamed!"); 63 | callback(error); 64 | }); 65 | } 66 | -------------------------------------------------------------------------------- /lib/gistup/api.js: -------------------------------------------------------------------------------- 1 | var https = require("https"); 2 | 3 | module.exports = function(method, url, token, message, callback) { 4 | var json = JSON.stringify(message); 5 | 6 | var request = https.request({ 7 | hostname: "api.github.com", 8 | port: 443, 9 | path: url, 10 | method: method, 11 | headers: { 12 | "Accept": "application/vnd.github.v3+json", 13 | "Authorization": "token " + token, 14 | "User-Agent": "mbostock/gistup", 15 | "Content-Type": "application/json;charset=utf8", 16 | "Content-Length": Buffer.byteLength(json, "utf8") 17 | } 18 | }, function(response) { 19 | var chunks = []; 20 | response.setEncoding("utf8"); 21 | response.on("data", function(chunk) { chunks.push(chunk); }); 22 | response.on("end", function() { 23 | var response, id = null, error; 24 | try { response = JSON.parse(chunks.join("")); } 25 | catch (e) { error = e; } 26 | if (!error && !response) error = new Error("empty API response"); 27 | if (error) console.warn(os.EOL + chunks.join("")); 28 | callback(error, response); 29 | }); 30 | }); 31 | 32 | request.on("error", callback); 33 | request.write(json); 34 | request.end(); 35 | } 36 | -------------------------------------------------------------------------------- /lib/gistup/get-settings.js: -------------------------------------------------------------------------------- 1 | var fs = require("fs"), 2 | path = require("path"), 3 | child = require("child_process"), 4 | readline = require("readline"); 5 | 6 | var open = process.platform === "linux" ? "xdg-open" : "open"; 7 | 8 | module.exports = function(callback) { 9 | var home = process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE, 10 | settingsPath = path.join(home, ".gistup.json"), 11 | settings; 12 | 13 | fs.readFile(settingsPath, "utf8", function(error, settings) { 14 | if (!error) { 15 | try { 16 | settings = JSON.parse(settings); 17 | } catch (e) { 18 | error = e; 19 | } 20 | } 21 | 22 | if (error) { 23 | console.log("Welcome to GISTUP!"); 24 | console.log(""); 25 | console.log("Since this is your first time using gistup, we need to create a"); 26 | console.log("GitHub \033[93mpersonal access token\033[0m to grant gistup permission to create"); 27 | console.log("gists on your behalf. You’ll only have to do this once, and you"); 28 | console.log("can easily revoke this token in the future if desired."); 29 | console.log(""); 30 | console.log("When you press any key to continue, your web browser will open."); 31 | console.log("Please login (if needed) and fill out the resulting form to create"); 32 | console.log("an access token. When you’re done, copy the access token to the"); 33 | console.log("clipboard and paste it back into the terminal."); 34 | console.log(""); 35 | process.stdout.write("Press any key to open GitHub… "); 36 | 37 | process.stdin.setRawMode(true); 38 | process.stdin.resume(); 39 | process.stdin.once("data", function() { 40 | child.exec(open + " 'https://github.com/settings/tokens/new?scopes=gist'", function(error) { 41 | if (error) { 42 | console.log(""); 43 | console.log("Oops, unable to open your web browser! Please visit this URL:"); 44 | console.log(""); 45 | console.log("https://github.com/settings/tokens/new?scopes=gist"); 46 | console.log(""); 47 | } 48 | 49 | var readin = readline.createInterface({ 50 | input: process.stdin, 51 | output: process.stdout 52 | }); 53 | 54 | readin.question("Enter personal access token: ", function(token) { 55 | readin.close(); 56 | token = token.trim().toLowerCase(); 57 | if (!/^[0-9a-f]{40}$/.test(token)) return void callback(new UserError("The access token \"" + token + "\" is invalid." + os.EOL + os.EOL + "Did you copy and paste the access token correctly? It should be a" + os.EOL + "forty-character hexadecimal string. Please fix and try again.")); 58 | settings = {token: token, open: error ? null : open}; 59 | fs.writeFile(settingsPath, JSON.stringify(settings, null, 2), {mode: parseInt("0600", 8)}, function(error) { 60 | callback(error, error ? null : settings); 61 | }); 62 | }); 63 | }); 64 | }); 65 | 66 | return; 67 | } 68 | 69 | if (!("open" in settings)) settings.open = open; 70 | callback(null, settings); 71 | }); 72 | }; 73 | -------------------------------------------------------------------------------- /lib/gistup/quote.js: -------------------------------------------------------------------------------- 1 | exports.single = function(string) { 2 | return "'" + string.replace(/'/g, "'\\''") + "'"; 3 | }; 4 | 5 | exports.double = function(string) { 6 | return '"' + string.replace(/(["\s'$`\\])/g, "\\$1") + '"'; 7 | }; 8 | -------------------------------------------------------------------------------- /lib/gistup/unless.js: -------------------------------------------------------------------------------- 1 | var queue = require("queue-async"); 2 | 3 | var UserError = require("./user-error"); 4 | 5 | module.exports = function(error) { 6 | if (error) { 7 | if (error.type === UserError) { 8 | console.warn("\033[91mERROR:\033[0m " + error.message); 9 | process.exit(1); 10 | } 11 | throw error; 12 | } 13 | return queue(1); 14 | }; 15 | -------------------------------------------------------------------------------- /lib/gistup/user-error.js: -------------------------------------------------------------------------------- 1 | module.exports = function UserError(message) { 2 | var error = new Error(message); 3 | error.type = UserError; 4 | return error; 5 | }; 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gistup", 3 | "version": "0.1.2", 4 | "description": "Initialize a gist from the command-line.", 5 | "keywords": [ 6 | "gist", 7 | "github", 8 | "git" 9 | ], 10 | "author": { 11 | "name": "Mike Bostock", 12 | "url": "http://bost.ocks.org/mike" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "https://github.com/mbostock/gistup.git" 17 | }, 18 | "dependencies": { 19 | "optimist": "0.3", 20 | "queue-async": "1" 21 | }, 22 | "bin": { 23 | "gistup": "./bin/gistup", 24 | "gistup-open": "./bin/gistup-open", 25 | "gistup-rename": "./bin/gistup-rename" 26 | }, 27 | "licenses": [ 28 | { 29 | "type": "BSD", 30 | "url": "https://github.com/mbostock/gistup/blob/master/LICENSE" 31 | } 32 | ], 33 | "engines": { 34 | "node": ">=0.10" 35 | } 36 | } 37 | --------------------------------------------------------------------------------