Skip to content

Commit

Permalink
Merge pull request #68 from gulliverhan/gitlab
Browse files Browse the repository at this point in the history
adds Gitlab support
  • Loading branch information
leonhartX authored Apr 9, 2018
2 parents 4b95a70 + 4e19b0b commit 6f1f1e9
Show file tree
Hide file tree
Showing 13 changed files with 449 additions and 34 deletions.
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
[![Chrome Web Store](https://img.shields.io/chrome-web-store/rating-count/lfjcgcmkmjjlieihflfhjopckgpelofo.svg)](https://chrome.google.com/webstore/detail/google-apps-script-github/lfjcgcmkmjjlieihflfhjopckgpelofo)
[![CircleCI](https://img.shields.io/circleci/project/github/leonhartX/gas-github.svg)](https://circleci.com/gh/leonhartX/gas-github)

Chrome-extension to manage Google Apps Script(GAS) code with your favorite SCM service(github/github enterprise/bitbucket).
Chrome-extension to manage Google Apps Script(GAS) code with your favorite SCM service(github/github enterprise/bitbucket/gitlab).

With this extension, you can manage your code in GAS editor, push code to a new created branch, pull from a repository/branch.

The extension does not use Google Drive API, so you don't need any google authentication. Moreover, this extension support **Bound scripts**.
The extension does not use the Google Drive API, so you don't need any google authentication. Moreover, this extension supports **Bound scripts**.

# **NOTICE**
This extension is a hack of the GAS IDE's internal RPC, so there's no guarantee of anything. This extension can broken **ANYTIME** if Google changed their api.
This extension is a hack of the GAS IDE's internal RPC, so there's no guarantee of anything. This extension can break at **ANYTIME** if Google changes their api.

# 1.Install
Install this extension from [chrome web store](https://chrome.google.com/webstore/detail/lfjcgcmkmjjlieihflfhjopckgpelofo).
Expand All @@ -21,7 +21,7 @@ Install this extension from [chrome web store](https://chrome.google.com/webstor
After install, when you open GAS editor, a new button will appear to allow you to login to Github/Github Enterprise/Bitbucket.

## 2.1.Login
Login to your Github/Github Enterprise/Bitbucket account, with Two-factor authentication support for Github/Github Enterprise.
Login to your Github/Github Enterprise/Bitbucket/Gitlab account, with Two-factor authentication support for Github/Github Enterprise.

Actually, this is not a login action, but to create the `access token` which will be used for the extension
>Note: the access token will be stored in `chrome.storage.sync`(password will not be stored), if you take this as a security hole, pleast **DO NOT** use this extension.
Expand All @@ -30,12 +30,12 @@ Actually, this is not a login action, but to create the `access token` which wil
After login, you can bind your GAS Project with repo and branch, or create a new one.

## 2.3.Manage
Manage your code with the similar `Push` and `Pull`.But there are something need to know before use it.
Manage your code with the similar `Push` and `Pull`.But there are somethings you need to know before you use it.

### 2.3.1.Create Repository/Branch
In `Repo` and `Branch` dropdown list, there is an option to Create new Repo and Branch.

New Repo will be created with init, mean's a default README.md.
New Repo will be created with an init, with a default README.md.

### 2.3.2.Pull and Push
The **PULL/PUSH** is not actually the same as Github/Bitbucket's **PULL/PUSH**, because GAS project does not have any git info, so what we can do is limited.
Expand Down Expand Up @@ -64,8 +64,8 @@ but you will need to delete the token or revoke Bitbucket's oauth yourself from

# 3.Features

- Manage code with Github, Github Enterprise and Bitbucket
- Support embedded script
- Manage code with Github, Github Enterprise, Bitbucket and Gitlab
- Support embedded scripts
- Push/Pull code between SCM and GAS
- Sync code to public/secret Gist
- Create repo, branch from GAS IDE
Expand All @@ -75,9 +75,9 @@ but you will need to delete the token or revoke Bitbucket's oauth yourself from
- Add Commit comment when push
- Support two-factor authentication(Github, Github Enterprise only)
- Work with directory(with slash in filename)
- Support Github Organization and Bitbucket Team.
- Support Github Organizations, Bitbucket Teams and Gitlab Groups.
- Google Apps Script native ui
- Option to change filetype from `.gs` to `.js` when upload to SCM
- Option to change filetype from `.gs` to `.js` when uploading to SCM
- Option to add ignore file pattern.

# 4.Support
Expand Down
2 changes: 1 addition & 1 deletion _locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
"message": "Google Apps Script Github Assistant"
},
"appDesc": {
"message": "Manage your gas code with github/github enterprise/bitbucket"
"message": "Manage your gas code with github/github enterprise/bitbucket/gitlab"
}
}
2 changes: 1 addition & 1 deletion _locales/fr/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
"message": "Google Apps Script Github Assistant"
},
"appDesc": {
"message": "Administrez votre code gas avec github/github enterprise/bitbucket"
"message": "Administrez votre code gas avec github/github enterprise/bitbucket/gitlab"
}
}
2 changes: 1 addition & 1 deletion _locales/ja/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
"message": "Google Apps Script Github アシスタント"
},
"appDesc": {
"message": "Github/Github Enterprise/BitbucketでGASのインラインコードを管理"
"message": "Github/Github Enterprise/Bitbucket/gitlabでGASのインラインコードを管理"
}
}
2 changes: 1 addition & 1 deletion _locales/ru_RU/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
"message": "Google Apps Script Github помощник"
},
"appDesc": {
"message": "Управляйте своим кодом gas чререз github/или github для предприятий/bitbucket"
"message": "Управляйте своим кодом gas чререз github/или github для предприятий/bitbucket/gitlab"
}
}
2 changes: 1 addition & 1 deletion _locales/zh_CN/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
"message": "Google Apps Script Github 助手"
},
"appDesc": {
"message": "使用Github/Github Enterprise/Bitbucket管理GAS的inline代码"
"message": "使用Github/Github Enterprise/Bitbucket/gitlab管理GAS的inline代码"
}
}
7 changes: 5 additions & 2 deletions manifest.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "3.3.7",
"version": "4.0.0",
"manifest_version": 2,
"default_locale": "en",
"name": "__MSG_appName__",
Expand Down Expand Up @@ -32,6 +32,7 @@
"src/util.js",
"src/scm/github.js",
"src/scm/bitbucket.js",
"src/scm/gitlab.js",
"src/gas-api.js",
"src/gas-hub.js"
],
Expand All @@ -57,6 +58,8 @@
"https://script.google.com/*",
"storage",
"declarativeContent",
"webRequest"
"webRequest",
"https://gitlab.com/*",
"https://*/*"
]
}
2 changes: 1 addition & 1 deletion options/options.css
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
.form .logout-container {
display: none;
}
.form .ghe-login-container, .form .bitbucket-login-container {
.form .ghe-login-container, .form .bitbucket-login-container, .form .gitlab-login-container {
display: none;
}
.form .error {
Expand Down
20 changes: 17 additions & 3 deletions options/options.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ <h2>Logged in as: <a target="_blank" id="login-user">XXX</a></h2>
</div>
<button id="login">github login</button>
<p class="label"><input type="checkbox" name="star" id="star">Star this extension on Github for support</p>
<p class="message">Switch to <a name="ghe" href="#">Github Enterprise</a> or <a name="bitbucket" href="#">Bitbucket</a></p>
<p class="message">Switch to <a name="ghe" href="#">Github Enterprise</a>, <a name="bitbucket" href="#">Bitbucket</a> or <a name="gitlab" href="#">GitLab</a></p>
<p class="error" style="display: none">Can not create access token, please check your username and password.</p>
</div>
<div class="login-container ghe-login-container">
Expand All @@ -43,7 +43,7 @@ <h2>Logged in as: <a target="_blank" id="login-user">XXX</a></h2>
</div>
<button id="ghe-login">github enterprise login</button>
<p class="message">Please star this extension on <a href="https://github.com/leonhartX/gas-github">Github</a> for support</p>
<p class="message">Switch to <a name="github" href="#">Github</a> or <a name="bitbucket" href="#">Bitbucket</a></p>
<p class="message">Switch to <a name="github" href="#">Github</a>, <a name="bitbucket" href="#">Bitbucket</a> or <a name="gitlab" href="#">GitLab</a></p>
<p class="error" style="display: none">Can not create access token, please check your GHE domain, username and password.</p>
</div>

Expand All @@ -54,9 +54,23 @@ <h2>Logged in as: <a target="_blank" id="login-user">XXX</a></h2>
</div>
<button id="bitbucket-login">bitbucket login</button>
<p class="message">Please star this extension on <a href="https://github.com/leonhartX/gas-github">Github</a> for support</p>
<p class="message">Switch to <a name="github" href="#">Github</a> or <a name="ghe" href="#">Github Enterprise</a></p>
<p class="message">Switch to <a name="github" href="#">Github</a>, <a name="ghe" href="#">Github Enterprise</a> or <a name="gitlab" href="#">GitLab</a></p>
<p class="error" style="display: none">Can not login, please check your username and password.</p>
</div>
<div class="login-container gitlab-login-container">
<div class="login-item login-item-basic">
<input id="gitlab-url" type="text" value="https://gitlab.com"/>
<input id="gitlab-email" type="email" placeholder="email"/>
<p class="label">login with password:</p>
<input id="gitlab-password" type="password" placeholder="password"/>
<p class="label">or personal accessToken(with <b>api</b> scope):</p>
<input id="gitlab-accesstoken" type="password" placeholder="access token"/>
</div>
<button id="gitlab-login">gitlab login</button>
<p class="message">Please star this extension on <a href="https://github.com/leonhartX/gas-github">Github</a> for support</p>
<p class="message">Switch to <a name="github" href="#">Github</a>, <a name="ghe" href="#">Github Enterprise</a> or <a name="bitbucket" href="#">Bitbucket</a></p>
<p class="error" style="display: none">Can not login, please check your username and password.</p>
</div>
</div>
</body>
</html>
145 changes: 132 additions & 13 deletions options/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ $(() => {
$('#bitbucket-login').click(e => {
addCred(getBitbucketParam());
});
$('#gitlab-login').click(e => {
addCred(getGitLabParam());
});
$('#logout').click(e => {
logout();
});
Expand All @@ -24,26 +27,46 @@ $(() => {
$('.login-container').hide();
$('.logout-container').show();
let user = item.user, domain, userLink, tokenLink;
if(item.scm !== 'bitbucket') {
domain = '@Github.com';
userLink = `https://github.com/${item.user}`;
tokenLink = 'https://github.com/settings/tokens';
if (item.baseUrl !== 'https://api.github.com') {
let match = item.baseUrl.match(/:\/\/(.*)\/api\/v3/);



if(item.scm === 'bitbucket') {
domain = '@Bitbucket.org';
userLink = `https://bitbucket.org/${user}`;
tokenLink = `https://bitbucket.org/account/user/${user}/api`;
} else if(item.scm === 'gitlab') {
if (item.baseUrl !== 'https://gitlab.com/api/v4') {
let match = item.baseUrl.match(/:\/\/(.*)\/api\/v4/);
if (!match || !match[1]) {
domain = '';
userLink = '';
tokenLink = '';
} else {
domain = `@${match[1]}`;
userLink = `https://${match[1]}/${item.user}`;
tokenLink = `https://${match[1]}/settings/tokens`;
userLink = `https://${match[1]}/${user}`;
tokenLink = `https://${match[1]}/profile/personal_access_tokens`;
}
} else {
domain = '@gitlab.com';
userLink = `https://gitlab.com/${user}`;
tokenLink = `https://gitlab.com/profile/personal_access_tokens`;
}
} else {
domain = '@Bitbucket.org';
userLink = `https://bitbucket.org/${user}`;
tokenLink = `https://bitbucket.org/account/user/${user}/api`;
domain = '@Github.com';
userLink = `https://github.com/${item.user}`;
tokenLink = 'https://github.com/settings/tokens';
if (item.baseUrl !== 'https://api.github.com') {
let match = item.baseUrl.match(/:\/\/(.*)\/api\/v3/);
if (!match || !match[1]) {
domain = '';
userLink = '';
tokenLink = '';
} else {
domain = `@${match[1]}`;
userLink = `https://${match[1]}/${item.user}`;
tokenLink = `https://${match[1]}/settings/tokens`;
}
}
}

$('#login-user').text(`${user}${domain}`).attr('href', userLink);
Expand All @@ -58,14 +81,14 @@ function getGithubParam() {
const scm = 'github';
const username = $('#username').val();
const password = $('#password').val();
const token = $('#accesstoken').val();
const personalToken = $('#accesstoken').val();
const baseUrl = `https://api.github.com`;
const otp = $('#otp').val();
return {
scm,
username,
password,
token,
personalToken,
baseUrl,
otp
};
Expand Down Expand Up @@ -101,6 +124,25 @@ function getBitbucketParam() {
}
}

function getGitLabParam() {
const scm = 'gitlab';
const username = $('#gitlab-email').val();
const password = $('#gitlab-password').val();
const personalToken = $('#gitlab-accesstoken').val();
const tokenType = (personalToken && personalToken.length > 0) ? 'personalToken' : 'oAuth';
const baseUrl = ($('#gitlab-url').val() || 'https://gitlab.com') + '/api/v4';
//const baseUrl = 'https://gitlab.com/api/v4';
return {
scm,
username,
password,
tokenType,
personalToken,
baseUrl
}
}


function addCred(param) {
if (param.username === '') {
return;
Expand All @@ -110,6 +152,8 @@ function addCred(param) {
}

if (param.scm === 'bitbucket') return loginBitbucket(param);
if (param.scm === 'gitlab' && param.tokenType ==='oAuth') return loginGitLabOauth(param);
if (param.scm === 'gitlab' && param.tokenType ==='personalToken') return loginGitLabToken(param);
if (param.password !== '' && param.scm === 'github') return loginGithub(param);

addStar(param.token)
Expand Down Expand Up @@ -221,6 +265,81 @@ function loginBitbucket(param) {
})
}

function loginGitLabOauth(param) {
const username = param.username;
const password = param.password;
const baseUrl = param.baseUrl;
const headers = {}
const domain = baseUrl.replace('/api/v4','');
$.ajax({
url: `${domain}/oauth/token`,
headers: headers,
method: 'POST',
dataType: 'json',
crossDomain: true,
contentType: 'application/x-www-form-urlencoded',
data: {
grant_type: 'password',
username: username,
password: password
}
})
.done(response => {
return $.getJSON(
`${baseUrl}/user`,
{ access_token: response.access_token }
)
.done(user => {
chrome.storage.sync.set({scm: param.scm, user: user.username, token: {type : 'oAuth', token :response.access_token}, baseUrl: baseUrl}, () => {
location.reload();
});
chrome.storage.local.get('tab', (item) => {
if(item.tab) {
chrome.tabs.reload(item.tab);
}
});
});
})
.fail(err => {
if (err.status == 401 &&
err.getResponseHeader('X-GitLab-OTP') !== null &&
$('.login-item-otp').filter(':visible').length == 0) {
$('.login-item').animate({height: 'toggle', opacity: 'toggle'}, 'slow');
} else {
$('.error').show();
}
})
}

function loginGitLabToken(param) {
const personalToken = param.personalToken;
const baseUrl = param.baseUrl;
const headers = {};
$.getJSON(
`${baseUrl}/user`,
{ private_token: personalToken }
)
.done(user => {
chrome.storage.sync.set({scm: param.scm, user: user.username, token: {type : 'personalToken', token :personalToken}, baseUrl: baseUrl}, () => {
location.reload();
});
chrome.storage.local.get('tab', (item) => {
if(item.tab) {
chrome.tabs.reload(item.tab);
}
});
})
.fail(err => {
if (err.status == 401 &&
err.getResponseHeader('X-GitLab-OTP') !== null &&
$('.login-item-otp').filter(':visible').length == 0) {
$('.login-item').animate({height: 'toggle', opacity: 'toggle'}, 'slow');
} else {
$('.error').show();
}
})
}

function logout() {
chrome.storage.sync.remove(['scm', 'token', 'user', 'baseUrl'], () => {
location.reload();
Expand Down
1 change: 1 addition & 0 deletions src/gas-hub.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ $(() => {
.then(updateGist)
.then(initPageEvent)
.catch((err) => {
debugger;
switch (err.message) {
case 'need login' :
initLoginContent();
Expand Down
Loading

0 comments on commit 6f1f1e9

Please sign in to comment.