feat: 초기 프로젝트 설정 및 룰.md 파일 추가

This commit is contained in:
2025-07-28 09:53:31 +09:00
commit 09a4d38512
8165 changed files with 1021855 additions and 0 deletions

98
api.hyungi.net/node_modules/vizion/lib/cliCommand.js generated vendored Normal file
View File

@@ -0,0 +1,98 @@
var PLATFORM = {
WINDOWS: 'WINDOWS',
UNIX: 'UNIX'
};
function getPlatform() {
switch (process.platform) {
case 'win32':
case 'win64':
return PLATFORM.WINDOWS;
default:
return PLATFORM.UNIX;
}
}
function getCdCommand() {
switch (this.platform) {
case PLATFORM.WINDOWS:
return function cdToPath(folder) {
return 'cd \"' + folder + "\"";
};
case PLATFORM.UNIX:
return function cdToPath(folder) {
return "cd '" + folder + "'";
};
}
}
function getCleanseCommand(setEnvVar) {
switch (this.platform) {
case PLATFORM.WINDOWS:
return function (cmd) {
var envCmd = setEnvVar();
if (!envCmd.length)
return cmd;
return [envCmd, cmd].join(' ');
};
case PLATFORM.UNIX:
return function (cmd) {
return [setEnvVar("LC_ALL", "en_US.UTF-8"), cmd].join(' ');
};
}
}
function getSetEnv() {
switch (this.platform) {
case PLATFORM.WINDOWS:
return function (k, v) {
if (!k)
return "";
return "SET ".concat([k,v].join('='));
};
case PLATFORM.UNIX:
return function (k, v) {
if (!k)
return "";
return [k,v].join('=');
};
}
}
function getConcatenator() {
switch(this.platform) {
case PLATFORM.WINDOWS:
return function (cmds) {
return cmds.join(" && ");
};
case PLATFORM.UNIX:
return function (cmds) {
var cmdText = '';
for (var i = 0; i < cmds.length; i++) {
cmdText += cmds[i];
if (i < cmds.length - 1)
cmdText += ";";
}
return cmdText;
};
}
}
var cliCommand = (function getExecutor() {
this.platform = getPlatform();
var cdTo = getCdCommand.call(this);
var concat = getConcatenator.call(this);
var setEnvVar = getSetEnv.call(this);
var cleanse = getCleanseCommand.call(this, setEnvVar);
return function (folder, cmd) {
var cmds = [];
cmds.push(cdTo(folder));
cmds.push(cleanse(cmd));
return concat(cmds);
}
})();
module.exports = cliCommand;

330
api.hyungi.net/node_modules/vizion/lib/git/git.js generated vendored Normal file
View File

@@ -0,0 +1,330 @@
var fs = require('fs');
var waterfall = require('async/waterfall');
var exec = require('child_process').exec;
var ini = require('ini');
var path = require('path');
var helper = require('../helper.js');
var cliCommand = require('../cliCommand.js');
var jsGitService = require('./js-git-service.js');
var git = {};
var TIMEOUT = 5000;
var MAXBUFFER = 1024 * 64; // 16KB
git.parseGitConfig = function (folder, cb) {
fs.readFile(path.join(folder, '.git/config'), 'utf-8', function (err, data) {
if (err) {
return cb(err);
}
var config = ini.parse(data);
cb(null, config);
});
};
git.getUrl = function (folder, cb) {
git.parseGitConfig(folder, function (err, config) {
if (err) {
return cb(err);
}
var data = {};
data.type = 'git';
data.url = helper.get(config, 'remote "origin".url');
cb(null, data);
});
};
git.getCommitInfo = function (folder, data, cb) {
jsGitService.getHeadCommit(folder, function (err, commit) {
if (err) {
return cb(err);
}
data.revision = helper.get(commit, 'hash');
data.comment = helper.get(commit, 'message');
cb(null, data);
});
};
git.getStaged = function (folder, data, cb) {
exec(cliCommand(folder, 'git status -s'), {timeout: TIMEOUT, maxBuffer: MAXBUFFER},
function (err, stdout, stderr) {
if (err) {
return cb(err);
}
data.unstaged = (stdout === '') ? false : true;
return cb(null, data);
});
};
git.getBranch = function (folder, data, cb) {
fs.readFile(path.join(folder, '.git/HEAD'), 'utf-8', function (err, content) {
if (err) {
return cb(err);
}
var regex = /ref: refs\/heads\/(.*)/;
var match = regex.exec(content);
data.branch = match ? match[1] : 'HEAD';
return cb(null, data);
});
};
git.getRemote = function (folder, data, cb) {
git.parseGitConfig(folder, function (err, config) {
if (err) {
return cb(err);
}
data.remotes = [];
Object.keys(config).map(function (key) {
var regex = /remote "(.*)"/;
var match = regex.exec(key);
if (match) {
data.remotes.push(match[1]);
}
});
data.remote = (data.remotes.indexOf('origin') === -1) ? data.remotes[0] : 'origin';
cb(null, data);
});
};
git.isCurrentBranchOnRemote = function (folder, data, cb) {
jsGitService.getRefHash(folder, data.branch, data.remote, function (err, hash) {
if (err) {
return cb(err);
}
data.branch_exists_on_remote = !!hash;
return cb(null, data);
});
};
git.getPrevNext = function (folder, data, cb) {
var remote = data.branch_exists_on_remote ? data.remote : null;
jsGitService.getCommitHistory(folder, 100, data.branch, remote, function (err, commitHistory) {
if (err) {
return cb(err);
}
var currentCommitIndex = commitHistory.findIndex(({ hash }) => hash === data.revision);
if (currentCommitIndex === -1) {
data.ahead = true;
data.next_rev = null;
data.prev_rev = null;
}
else {
data.ahead = false;
data.next_rev = (currentCommitIndex === 0) ? null : commitHistory[currentCommitIndex - 1].hash;
data.prev_rev = (currentCommitIndex === (commitHistory.length - 1)) ? null : commitHistory[currentCommitIndex + 1].hash;
}
cb(null, data);
});
};
git.getUpdateTime = function (folder, data, cb) {
fs.stat(folder + ".git", function (err, stats) {
if (err) {
return cb(err);
}
data.update_time = helper.trimNewLine(stats.mtime);
return cb(null, data);
});
};
git.getTags = function (folder, data, cb) {
exec(cliCommand(folder, 'git tag'), {timeout: TIMEOUT, maxBuffer: MAXBUFFER},
function (err, stdout, stderr) {
if (err) {
return cb(err);
}
if (stdout.length) {
data.tags = stdout.split('\n');
data.tags.pop();
data.tags = data.tags.slice(0, 10);
}
return cb(null, data);
});
};
git.parse = function (folder, cb) {
waterfall([
git.getUrl.bind(null, folder),
git.getCommitInfo.bind(null, folder),
git.getStaged.bind(null, folder),
git.getBranch.bind(null, folder),
git.getRemote.bind(null, folder),
git.isCurrentBranchOnRemote.bind(null, folder),
git.getPrevNext.bind(null, folder),
git.getUpdateTime.bind(null, folder),
git.getTags.bind(null, folder)],
function (err, data) {
if (err) {
return cb(err);
}
return cb(null, data);
});
};
git.isUpdated = function (folder, cb) {
waterfall([
git.getCommitInfo.bind(null, folder, {}),
git.getBranch.bind(null, folder),
git.getRemote.bind(null, folder),
git.isCurrentBranchOnRemote.bind(null, folder),
],
function (err, data) {
if (err) {
return cb(err);
}
exec(cliCommand(folder, 'git remote update'), {timeout: 60000, maxBuffer: MAXBUFFER},
function (err, stdout, stderr) {
if (err) {
return cb(err);
}
var remote = data.branch_exists_on_remote ? data.remote : null;
jsGitService.getLastCommit(folder, data.branch, remote, function (err, commit) {
if (err) {
return cb(err);
}
var res = {
new_revision: commit.hash,
current_revision: data.revision,
is_up_to_date: (commit.hash === data.revision)
};
return cb(null, res);
});
});
});
};
git.revert = function (args, cb) {
var ret = {};
var command = cliCommand(args.folder, "git reset --hard " + args.revision);
ret.output = '';
ret.output += command + '\n';
ret.success = true;
exec(command, {timeout: TIMEOUT, maxBuffer: MAXBUFFER},
function (err, stdout, stderr) {
ret.output += stdout;
if (err !== null || stderr.substring(0, 6) === 'fatal:')
ret.success = false;
return cb(null, ret);
});
};
git.update = function (folder, cb) {
git.isUpdated(folder, function (err, data) {
if (err) {
return cb(err);
}
var res = {};
if (data.is_up_to_date === true) {
res.success = false;
res.current_revision = data.new_revision;
return cb(null, res);
}
else {
git.revert({folder: folder, revision: data.new_revision},
function (err, dt) {
if (err) {
return cb(err);
}
res.output = dt.output;
res.success = dt.success;
res.current_revision = (dt.success) ? data.new_revision : data.current_revision;
return cb(null, res);
});
}
});
};
git.prev = function (folder, cb) {
waterfall([
git.getCommitInfo.bind(null, folder, {}),
git.getBranch.bind(null, folder),
git.getRemote.bind(null, folder),
git.isCurrentBranchOnRemote.bind(null, folder),
git.getPrevNext.bind(null, folder),
], function (err, data) {
if (err) {
return cb(err);
}
var res = {};
if (data.prev_rev !== null) {
git.revert({folder: folder, revision: data.prev_rev}, function (err, meta) {
if (err) {
return cb(err);
}
res.output = meta.output;
res.success = meta.success;
res.current_revision = (res.success) ? data.prev_rev : data.revision;
return cb(null, res);
});
}
else {
res.success = false;
res.current_revision = data.revision;
return cb(null, res);
}
});
};
git.next = function (folder, cb) {
waterfall([
git.getCommitInfo.bind(null, folder, {}),
git.getBranch.bind(null, folder),
git.getRemote.bind(null, folder),
git.isCurrentBranchOnRemote.bind(null, folder),
git.getPrevNext.bind(null, folder),
], function (err, data) {
if (err) {
return cb(err);
}
var res = {};
if (data.next_rev !== null) {
git.revert({folder: folder, revision: data.next_rev}, function (err, meta) {
if (err) {
return cb(err);
}
res.output = meta.output;
res.success = meta.success;
res.current_revision = (res.success) ? data.next_rev : data.revision;
return cb(null, res);
});
}
else {
res.success = false;
res.current_revision = data.revision;
return cb(null, res);
}
});
};
module.exports = git;

View File

@@ -0,0 +1,157 @@
var path = require('path');
var whilst = require('async/whilst');
var helper = require('../helper.js');
var jsGitService = {};
jsGitService.loadRepo = function (folder) {
var repo = {};
// Mixin the base DB operations using local git database on disk.
require('git-node-fs/mixins/fs-db')(repo, path.join(folder, '.git'));
// Mixin the walker helpers.
require('js-git/mixins/walkers')(repo);
return repo;
};
jsGitService.getHeadCommit = function (folder, remote, cb) {
if (cb === undefined) {
cb = remote;
remote = null;
}
var repo = jsGitService.loadRepo(folder);
// Look up the hash that master currently points to.
// HEAD for local head
// refs/remotes/origin/HEAD for remote head
var ref = remote ? 'refs/remotes/' + remote + '/HEAD' : 'HEAD';
jsGitService.getLastCommitByRef(repo, ref, cb);
};
jsGitService.getLastCommit = function (folder, branch, remote, cb) {
if (cb === undefined) {
cb = remote;
remote = null;
}
var repo = jsGitService.loadRepo(folder);
var ref = remote ? 'refs/remotes/origin/' + branch : 'refs/heads/' + branch;
jsGitService.getLastCommitByRef(repo, ref, cb);
};
jsGitService.getLastCommitByRef = function (repo, ref, cb) {
repo.readRef(ref, function (err, commitHash) {
if (err) {
return cb(err);
}
if (!commitHash) {
return cb(null);
}
repo.logWalk(commitHash.replace(/ref: /g, ""), function (err, logStream) {
if (err) {
return cb(err);
}
if (!logStream) {
return cb(null);
}
logStream.read(function (err, commit) {
if (err) {
return cb(err);
}
cb(null, commit);
});
});
});
};
jsGitService.getCommitByHash = function (repo, hash, cb) {
repo.loadAs("commit", hash, function (err, commit) {
if (err) {
return cb(err);
}
cb(null, commit);
});
};
jsGitService.getCommitHistory = function (folder, n, branch, remote, cb) {
var commitHistory = [];
if (cb === undefined) {
cb = remote;
remote = null;
}
var repo = jsGitService.loadRepo(folder);
// HEAD for local head
// refs/remotes/origin/HEAD for remote head
// refs/heads/my-branch for local branch
// refs/remotes/origin/my-branch for remote branch
var ref;
if (branch === 'HEAD') {
ref = remote ? 'refs/remotes/' + remote + '/HEAD' : 'HEAD';
}
else {
ref = remote ? 'refs/remotes/origin/' + branch : 'refs/heads/' + branch;
}
jsGitService.getLastCommitByRef(repo, ref, function (err, commit) {
if (err) {
return cb(err);
}
if (!commit) {
return cb(null, commitHistory);
}
commitHistory.push(commit);
var count = 1;
var parentCommitHash = helper.last(commit.parents); // last parent is the parent in the 'git log' meaning
whilst(
function () {
return count < n && parentCommitHash;
},
function (callback) {
jsGitService.getCommitByHash(repo, parentCommitHash, function (err, commit) {
if (err) {
return callback(err);
}
if (!commit) {
parentCommitHash = null;
return callback(null);
}
commit.hash = parentCommitHash; // add hash back to commit as not a property when loaded by hash
count++;
commitHistory.push(commit);
parentCommitHash = helper.last(commit.parents);
callback(null);
});
},
function (err) {
if (err) {
return cb(err);
}
return cb(null, commitHistory);
}
);
});
};
jsGitService.getRefHash = function (folder, branch, remote, cb) {
var repo = jsGitService.loadRepo(folder);
repo.readRef('refs/remotes/' + remote + '/' + branch, cb);
};
module.exports = jsGitService;

28
api.hyungi.net/node_modules/vizion/lib/helper.js generated vendored Normal file
View File

@@ -0,0 +1,28 @@
function trimNewLine(input) {
return typeof(input) === 'string' ? input.replace(/\n/g, '') : input;
}
function get(object, path) {
const pathArray = path.split('.');
let result = object;
while (result != null && pathArray.length) {
const pathItem = pathArray.shift();
if (pathItem in result) {
result = result[pathItem];
} else {
return undefined;
}
}
return result;
}
function last(array) {
var length = array == null ? 0 : array.length;
return length ? array[length - 1] : undefined;
}
module.exports = {
get: get,
last: last,
trimNewLine: trimNewLine,
};

79
api.hyungi.net/node_modules/vizion/lib/hg/hg.js generated vendored Normal file
View File

@@ -0,0 +1,79 @@
var exec = require("child_process").exec;
var fs = require("fs");
var cliCommand = require('../cliCommand.js');
var halt = false;
function error(repoType, task, errorMsg, cb) {
if (halt) return false;
console.error("[Repo-Parser] An error occured while " + task + " in a " + repoType + " repository: " + errorMsg);
halt = true;
return cb("[Repo-Parser] An error occured while " + task + " in a " + repoType + " repository: " + errorMsg);
}
function checkReturn(dataArray, cb) {
if (halt) {
return false;
}
if (Object.keys(dataArray).length > 6) {
Object.keys(dataArray).forEach(function(key) {
if (typeof(dataArray[key]) === 'string') {
dataArray[key] = dataArray[key].replace(/\n/g, '');
}
});
cb(null, dataArray);
}
};
module.exports.parse = function parseHg(folder, cb) {
var data = {};
data.type = 'mercurial';
data.commit_history = []; // temporary
exec(cliCommand(folder, "hg paths default"), function(err, stdout, stderr) {
if(err !== null) {
error("mercurial", "fetching path", stderr, cb);
}
else {
data.url = stdout;
checkReturn(data, cb);
}
});
exec(cliCommand(folder, "hg log --limit 1 --template 'changeset: {rev}:{node|short}\nsummary: {desc}'"), function(err, stdout, stderr) {
if(err !== null) {
error("mercurial", "fetching log", stderr, cb);
}
else {
var changeset = stdout.match(/^changeset:\s+([^\n]+)$/m);
//date = stdout.match(/^date:\s+:([^\n]+)$/m);
var summary = stdout.match(/^summary:\s+([^\n]+)$/m);
data.revision = changeset[1];
data.comment = summary[1];
//data.update_time = date;
checkReturn(data, cb);
}
});
exec(cliCommand(folder, "hg branch"), function(err, stdout, stderr) {
if(err !== null) {
error("mercurial", "fetching branch", stderr, cb);
}
else {
data.branch = stdout;
checkReturn(data, cb);
}
});
fs.stat(folder+".hg", function(err, stats) {
if(err !== null) {
error("mercurial", "fetching stats", "no error available", cb);
}
else {
data.update_time = stats.mtime;
checkReturn(data, cb);
}
});
}

20
api.hyungi.net/node_modules/vizion/lib/identify.js generated vendored Normal file
View File

@@ -0,0 +1,20 @@
var fs = require('fs');
var eachSeries = require('async/eachSeries');
module.exports = function(folder, cb) {
if (folder[folder.length - 1] !== '/')
folder += '/';
eachSeries(['git', 'hg', 'svn'],
function(type, callback) {
fs.exists(folder+'.'+type, function(exists) {
if (exists)
return callback(type);
else
return callback();
});
},
function(final) {
return cb(final ? final : 'No versioning system found', folder);
});
};

131
api.hyungi.net/node_modules/vizion/lib/svn/svn.js generated vendored Normal file
View File

@@ -0,0 +1,131 @@
var fs = require('fs');
var waterfall = require('async/waterfall');
var exec = require('child_process').exec;
var cliCommand = require('../cliCommand.js');
var svn = {};
svn.parse = function(folder, cb) {
var getMeta = function(cb) {
exec(cliCommand(folder, "svn info"), function(err, stdout, stderr) {
if(err !== null)
return cb(err);
var data = {};
data.type = 'svn';
data.url = stdout.match(/Repository Root: ([^\n]+)/);
if (data.url && typeof(data.url) === 'object') {
data.url = data.url[1];
}
var match = stdout.match(/Relative URL: \^\/([^\n]+)/);
if (match) {
var relativeUrl = match[1];
if (relativeUrl.match(/^trunk/)) {
data.branch = 'trunk';
} else if (relativeUrl.match(/^branch/)) {
match = relativeUrl.match(/^branch(?:es)?\/([^/]+)(?:\/|$)/);
if (match) {
data.branch = match[1];
}
}
}
match = stdout.match(/Last Changed Rev: ([^\n]+)/);
if (match) {
data.revision = match[1];
}
match = stdout.match(/Last Changed Date: ([^\n]+)/);
if (match) {
var date = new Date(match[1]);
data.update_time = date;
}
return cb(null, data);
});
}
var getRevComment = function(data, cb) {
var rev = data.revision || "BASE";
exec(cliCommand(folder, "svn log -r " + rev), function(err, stdout, stderr) {
if(err !== null)
return cb(err);
if (rev === "BASE") {
data.revision = stdout.match(/^(r[0-9]+)\s\|/m);
if (data.revision) data.revision = data.revision[1];
}
data.comment = stdout.match(/lines?\s*\n((.|\n)*)\n-{72}\n$/);
if (data.comment) data.comment = data.comment[1].replace(/\n/g, '');
if (!data.update_time) {
data.update_time = stdout.match(/-+\n(.*?)\n/);
if (data.update_time) data.update_time = new Date(
data.update_time[1].split(" | ")[2]
);
}
cb(null, data);
});
}
var getDate = function(data, cb) {
if (data.update_time)
return cb(null, data);
fs.stat(folder+".svn", function(err, stats) {
if(err !== null)
return cb(err);
data.update_time = stats.mtime;
return cb(null, data);
});
}
waterfall([getMeta, getRevComment, getDate],
function(err, data) {
if (err !== null)
return cb(err);
return cb(null, data);
});
}
svn.isUpdated = function(folder, cb) {
var res = {};
var getRev = function(str) {
var matches = str.match(/Changed Rev: ([^\n]+)/);
if (matches) matches = matches[1];
return matches;
}
exec(cliCommand(folder, "svn info"), function(err, stdout, stderr) {
if(err !== null)
return cb(err);
var current_rev = getRev(stdout);
exec(cliCommand(folder, "svn info -r HEAD"), function(err, stdout, stderr) {
if(err !== null)
return cb(err);
var recent_rev = getRev(stdout);
res.is_up_to_date = (recent_rev === current_rev);
res.new_revision = recent_rev;
res.current_revision = current_rev;
return cb(null, res);
});
});
}
svn.update = function(folder, cb) {
var res = {};
exec(cliCommand(folder, "svn update"), function(err, stdout, stderr) {
if(err !== null)
return cb(err);
var new_rev = stdout.match(/Updated to revision ([^\.]+)/);
if (new_rev === null)
{
res.success = false;
var old_rev = stdout.match(/At revision ([^\.]+)/);
res.current_revision = (old_rev) ? old_rev[1] : null;
}
else {
res.success = true;
res.current_revision = new_rev[1];
}
return cb(null, res);
});
}
module.exports = svn;

81
api.hyungi.net/node_modules/vizion/lib/vizion.js generated vendored Normal file
View File

@@ -0,0 +1,81 @@
var ALL = {};
var vizion = {};
ALL.hg = require('./hg/hg.js');
ALL.git = require('./git/git.js');
ALL.svn = require('./svn/svn.js');
// Add more revision control tools here
var identify = require('./identify.js');
vizion.analyze = function(argv, cb) {
var _folder = (argv.folder != undefined) ? argv.folder : '.';
identify(_folder, function(type, folder) {
if (ALL[type])
return ALL[type].parse(folder, cb);
else
return cb('Error vizion::analyze() for given folder: '+folder);
});
};
vizion.isUpToDate = function(argv, cb) {
var _folder = (argv.folder != undefined) ? argv.folder : '.';
identify(_folder, function(type, folder) {
if (ALL[type])
return ALL[type].isUpdated(folder, cb);
else
return cb('Error vizion::isUpToDate() for given folder: '+folder);
});
};
vizion.update = function(argv, cb) {
var _folder = (argv.folder != undefined) ? argv.folder : '.';
identify(_folder, function(type, folder) {
if (ALL[type])
return ALL[type].update(folder, cb);
else
return cb('Error vizion::update() for given folder: '+folder);
});
};
vizion.revertTo = function(argv, cb) {
var revision = (argv.revision) ? argv.revision : false;
var _folder = (argv.folder != undefined) ? argv.folder : '.';
if (!(revision && /^[A-Fa-f0-9]+$/.test(revision))) return cb({msg: 'Cannot revert to an invalid commit revision', path: _folder});
identify(_folder, function(type, folder) {
if (ALL[type])
return ALL[type].revert({folder: folder, revision: revision}, cb);
else
return cb('Error vizion::analyze() for given folder: '+folder);
});
};
vizion.prev = function(argv, cb) {
var _folder = (argv.folder != undefined) ? argv.folder : '.';
identify(_folder, function(type, folder) {
if (ALL[type])
return ALL[type].prev(folder, cb);
else
return cb('Error vizion::prev() for given folder: '+folder);
});
};
vizion.next = function(argv, cb) {
var _folder = (argv.folder != undefined) ? argv.folder : '.';
identify(_folder, function(type, folder) {
if (ALL[type])
return ALL[type].next(folder, cb);
else
return cb('Error vizion::next() for given folder: '+folder);
});
};
module.exports = vizion;