git.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /**
  2. * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. 'use strict';
  6. const tools = require( './tools' );
  7. module.exports = {
  8. /**
  9. * Holds boilerplate repository Git URL.
  10. *
  11. * @private
  12. * @readonly
  13. * @type {String}
  14. */
  15. BOILERPLATE_REPOSITORY: 'git@github.com:ckeditor/ckeditor-boilerplate.git',
  16. /**
  17. * Holds boilerplate branch used in CKEditor5 projects.
  18. *
  19. * @private
  20. * @readonly
  21. * @type {String}
  22. */
  23. BOILERPLATE_BRANCH: 'ckeditor5',
  24. /**
  25. * Parses GitHub URL. Extracts used server, repository and branch.
  26. *
  27. * @param {String} url GitHub URL from package.json file.
  28. * @returns {Object} urlInfo
  29. * @returns {String} urlInfo.server
  30. * @returns {String} urlInfo.repository
  31. * @returns {String} urlInfo.branch
  32. */
  33. parseRepositoryUrl( url ) {
  34. const regexp = /^(git@github\.com:|https?:\/\/github\.com\/)?([^#]+)(?:#)?(.*)$/;
  35. const match = url.match( regexp );
  36. let server;
  37. let repository;
  38. let branch;
  39. if ( !match ) {
  40. return null;
  41. }
  42. server = match[ 1 ] || 'https://github.com/';
  43. repository = match[ 2 ] || '';
  44. branch = match[ 3 ] || 'master';
  45. if ( !repository ) {
  46. return null;
  47. }
  48. return {
  49. server: server,
  50. repository: repository,
  51. branch: branch
  52. };
  53. },
  54. /**
  55. * Clones repository to workspace.
  56. *
  57. * @param {Object} urlInfo Parsed URL object from {@link #parseRepositoryUrl}.
  58. * @param {String} workspacePath Path to the workspace location where repository will be cloned.
  59. */
  60. cloneRepository( urlInfo, workspacePath ) {
  61. const cloneCommands = [
  62. `cd ${ workspacePath }`,
  63. `git clone ${ urlInfo.server + urlInfo.repository }`
  64. ];
  65. tools.shExec( cloneCommands.join( ' && ' ) );
  66. },
  67. /**
  68. * Checks out branch on selected repository.
  69. *
  70. * @param {String} repositoryLocation Absolute path to repository.
  71. * @param {String} branchName Name of the branch to checkout.
  72. */
  73. checkout( repositoryLocation, branchName ) {
  74. const checkoutCommands = [
  75. `cd ${ repositoryLocation }`,
  76. `git checkout ${ branchName }`
  77. ];
  78. tools.shExec( checkoutCommands.join( ' && ' ) );
  79. },
  80. /**
  81. * Pulls specified branch from origin.
  82. *
  83. * @param {String} repositoryLocation Absolute path to repository.
  84. * @param {String} branchName Branch name to pull.
  85. */
  86. pull( repositoryLocation, branchName ) {
  87. const checkoutCommands = [
  88. `cd ${ repositoryLocation }`,
  89. `git pull origin ${ branchName }`
  90. ];
  91. tools.shExec( checkoutCommands.join( ' && ' ) );
  92. },
  93. /**
  94. * Initializes new repository, adds and merges CKEditor5 boilerplate project.
  95. *
  96. * @param {String} repositoryPath Absolute path where repository should be created.
  97. */
  98. initializeRepository( repositoryPath ) {
  99. const initializeCommands = [
  100. `git init ${ repositoryPath }`,
  101. `cd ${ repositoryPath }`,
  102. `git remote add boilerplate ${ this.BOILERPLATE_REPOSITORY }`,
  103. `git fetch boilerplate ${ this.BOILERPLATE_BRANCH }`,
  104. `git merge boilerplate/${ this.BOILERPLATE_BRANCH }`
  105. ];
  106. tools.shExec( initializeCommands.join( ' && ' ) );
  107. },
  108. /**
  109. * Returns Git status of repository stored under specified path. It runs `git status --porcelain -sb` command.
  110. *
  111. * @param {String} repositoryPath Absolute path to repository.
  112. * @returns {String} Executed command's result.
  113. */
  114. getStatus( repositoryPath ) {
  115. return tools.shExec( `cd ${ repositoryPath } && git status --porcelain -sb` );
  116. },
  117. /**
  118. * Updates boilerplate project in specified repository.
  119. * @param {String} repositoryPath Absolute path to repository.
  120. */
  121. updateBoilerplate( repositoryPath ) {
  122. const regexp = /boilerplate(\n|$)/;
  123. // Try to add boilerplate remote if one is not already added.
  124. if ( !regexp.test( tools.shExec( `cd ${ repositoryPath } && git remote` ) ) ) {
  125. tools.shExec( `cd ${ repositoryPath } && git remote add boilerplate ${ this.BOILERPLATE_REPOSITORY }` );
  126. }
  127. const updateCommands = [
  128. `cd ${ repositoryPath }`,
  129. `git fetch boilerplate ${ this.BOILERPLATE_BRANCH }`,
  130. `git merge boilerplate/${ this.BOILERPLATE_BRANCH }`
  131. ];
  132. tools.shExec( updateCommands.join( ' && ' ) );
  133. },
  134. /**
  135. * Creates initial commit on repository under specified path.
  136. *
  137. * @param {String} pluginName
  138. * @param {String} repositoryPath
  139. */
  140. initialCommit( pluginName, repositoryPath ) {
  141. const commitCommands = [
  142. `cd ${ repositoryPath }`,
  143. `git add .`,
  144. `git commit -m "Initial commit for ${ pluginName }."`
  145. ];
  146. tools.shExec( commitCommands.join( ' && ' ) );
  147. }
  148. };