You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

169 lines
3.5 KiB

8 years ago
  1. "use strict";
  2. var NodeGit = require("nodegit"),
  3. Promise = require('bluebird'),
  4. path = require('path'),
  5. os = require('os'),
  6. fs = Promise.promisifyAll(require("fs")),
  7. _ = require('lodash');
  8. /**
  9. * Git Model
  10. */
  11. module.exports = {
  12. _git: null,
  13. _repo: {
  14. path: '',
  15. exists: false,
  16. inst: null
  17. },
  18. /**
  19. * Initialize Git model
  20. *
  21. * @param {Object} appconfig The application config
  22. * @return {Object} Git model instance
  23. */
  24. init(appconfig) {
  25. let self = this;
  26. //-> Build repository path
  27. if(_.isEmpty(appconfig.git.path) || appconfig.git.path === 'auto') {
  28. self._repo.path = path.join(ROOTPATH, 'repo');
  29. } else {
  30. self._repo.path = appconfig.git.path;
  31. }
  32. //-> Initialize repository
  33. self._initRepo(appconfig).then((repo) => {
  34. self._repo.inst = repo;
  35. });
  36. return self;
  37. },
  38. /**
  39. * Initialize Git repository
  40. *
  41. * @param {Object} appconfig The application config
  42. * @return {Object} Promise
  43. */
  44. _initRepo(appconfig) {
  45. let self = this;
  46. winston.info('[GIT] Initializing Git repository...');
  47. //-> Check if path is accessible
  48. return fs.mkdirAsync(self._repo.path).catch((err) => {
  49. if(err.code !== 'EEXIST') {
  50. winston.error('Invalid Git repository path or missing permissions.');
  51. }
  52. }).then(() => {
  53. //-> Check if path already contains a git working folder
  54. return fs.statAsync(path.join(self._repo.path, '.git')).then((stat) => {
  55. self._repo.exists = stat.isDirectory();
  56. }).catch((err) => {
  57. self._repo.exists = false;
  58. });
  59. }).then(() => {
  60. //-> Init repository
  61. let repoInitOperation = null;
  62. if(self._repo.exists) {
  63. winston.info('[GIT] Using existing repository...');
  64. repoInitOperation = NodeGit.Repository.open(self._repo.path);
  65. } else if(appconfig.git.mode === 'remote') {
  66. winston.info('[GIT] Cloning remote repository for first time...');
  67. let cloneOptions = self._generateCloneOptions(appconfig);
  68. repoInitOperation = NodeGit.Clone(appconfig.git.url, self._repo.path, cloneOptions);
  69. } else {
  70. winston.info('[GIT] Using offline local repository...');
  71. repoInitOperation = NodeGit.Repository.init(self._repo.path, 0);
  72. }
  73. return repoInitOperation;
  74. }).catch((err) => {
  75. winston.error('Unable to open or clone Git repository!');
  76. winston.error(err);
  77. }).then((repo) => {
  78. self._repo.inst = repo;
  79. winston.info('[GIT] Git repository is now ready.');
  80. });
  81. },
  82. /**
  83. * Generate Clone Options object
  84. *
  85. * @param {Object} appconfig The application configuration
  86. * @return {Object} CloneOptions object
  87. */
  88. _generateCloneOptions(appconfig) {
  89. let cloneOptions = {};
  90. cloneOptions.fetchOpts = {
  91. callbacks: {
  92. credentials: () => {
  93. let cred = null;
  94. switch(appconfig.git.auth.type) {
  95. case 'basic':
  96. cred = NodeGit.Cred.userpassPlaintextNew(
  97. appconfig.git.auth.user,
  98. appconfig.git.auth.pass
  99. );
  100. break;
  101. case 'oauth':
  102. cred = NodeGit.Cred.userpassPlaintextNew(
  103. appconfig.git.auth.token,
  104. "x-oauth-basic"
  105. );
  106. break;
  107. case 'ssh':
  108. cred = NodeGit.Cred.sshKeyNew(
  109. appconfig.git.auth.user,
  110. appconfig.git.auth.publickey,
  111. appconfig.git.auth.privatekey,
  112. appconfig.git.auth.passphrase
  113. );
  114. break;
  115. default:
  116. cred = NodeGit.Cred.defaultNew();
  117. break;
  118. }
  119. return cred;
  120. }
  121. }
  122. };
  123. if(os.type() === 'Darwin') {
  124. cloneOptions.fetchOpts.callbacks.certificateCheck = () => { return 1; }; // Bug in OS X, bypass certs check workaround
  125. }
  126. return cloneOptions;
  127. }
  128. };