mirror of
https://github.com/bendtherules/github-delete-unused-repos.git
synced 2026-08-18 13:52:59 +00:00
Initial commit
Contains basic working logic to find unused repos and show in console
This commit is contained in:
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"presets": [
|
||||||
|
[
|
||||||
|
"env",
|
||||||
|
{
|
||||||
|
"modules": false,
|
||||||
|
"targets": {
|
||||||
|
"browsers": [
|
||||||
|
"> 1%",
|
||||||
|
"last 2 versions",
|
||||||
|
"not ie <= 8"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stage-2"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
# http://editorconfig.org
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
trim_trailing_whitespace = false
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
coverage/
|
||||||
|
node_modules/
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
.nyc_output
|
||||||
|
lib
|
||||||
|
lib_test
|
||||||
|
dist
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
# gitignore
|
||||||
|
|
||||||
|
coverage/
|
||||||
|
node_modules/
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
.nyc_output
|
||||||
|
lib
|
||||||
|
lib_test
|
||||||
|
|
||||||
|
# npmignore
|
||||||
|
|
||||||
|
src/
|
||||||
|
__tests__/
|
||||||
|
.vscode/
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
language: node_js
|
||||||
|
node_js:
|
||||||
|
- 'node' # use latest stable nodejs version
|
||||||
|
script:
|
||||||
|
- npm run coverage # jest test with coverage flag does coverage too
|
||||||
|
after_script:
|
||||||
|
- 'cat coverage/lcov.info | ./node_modules/.bin/coveralls' # sends the coverage report to coveralls
|
||||||
Vendored
+34
@@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible Node.js debug attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"type": "node",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Debug file",
|
||||||
|
"program": "${workspaceRoot}/lib/${fileBasenameNoExtension}.js",
|
||||||
|
"cwd": "${workspaceRoot}",
|
||||||
|
"sourceMaps": true,
|
||||||
|
"smartStep": true,
|
||||||
|
"preLaunchTask": "build",
|
||||||
|
"outFiles": [
|
||||||
|
"${workspaceRoot}/lib/*.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "node",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Debug test",
|
||||||
|
"program": "${workspaceRoot}/node_modules/jest/bin/jest.js",
|
||||||
|
"args": [
|
||||||
|
"--findRelatedTests",
|
||||||
|
"${relativeFile}",
|
||||||
|
"--env",
|
||||||
|
"jest-environment-node-debug"
|
||||||
|
],
|
||||||
|
"cwd": "${workspaceRoot}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Vendored
+3
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"typescript.tsdk": "node_modules/typescript/lib/"
|
||||||
|
}
|
||||||
Vendored
+59
@@ -0,0 +1,59 @@
|
|||||||
|
{
|
||||||
|
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||||
|
// for the documentation about the tasks.json format
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"taskName": "Run current file",
|
||||||
|
"command": "ts-node ${relativeFile}",
|
||||||
|
"type": "shell",
|
||||||
|
"problemMatcher": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "npm",
|
||||||
|
"label": "clean",
|
||||||
|
"script": "clean",
|
||||||
|
"problemMatcher": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "npm",
|
||||||
|
"label": "build",
|
||||||
|
"script": "build",
|
||||||
|
"group": {
|
||||||
|
"kind": "build",
|
||||||
|
"isDefault": true
|
||||||
|
},
|
||||||
|
"problemMatcher":[]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "npm",
|
||||||
|
"label": "format",
|
||||||
|
"script": "format",
|
||||||
|
"problemMatcher": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "npm",
|
||||||
|
"label": "coverage",
|
||||||
|
"script": "coverage",
|
||||||
|
"problemMatcher": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "npm",
|
||||||
|
"label": "test",
|
||||||
|
"script": "test",
|
||||||
|
"group": {
|
||||||
|
"kind": "test",
|
||||||
|
"isDefault": true
|
||||||
|
},
|
||||||
|
"problemMatcher": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "npm",
|
||||||
|
"label": "lint",
|
||||||
|
"script": "lint",
|
||||||
|
"problemMatcher": [
|
||||||
|
"$eslint-stylish"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2018
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
[](https://travis-ci.org/{{github-user-name}}/{{github-app-name}}.svg?branch=master)
|
||||||
|
[](https://coveralls.io/github/{{github-user-name}}/{{github-app-name}}?branch=master)
|
||||||
|
[](http://opensource.org/licenses/MIT)
|
||||||
|
|
||||||
|
# Using this module in other modules
|
||||||
|
|
||||||
|
Here is a quick example of how this module can be used in other modules. The [TypeScript Module Resolution Logic](https://www.typescriptlang.org/docs/handbook/module-resolution.html) makes it quite easy. The file `src/index.ts` is a [barrel](https://basarat.gitbooks.io/typescript/content/docs/tips/barrel.html) that re-exports selected exports from other files. The _package.json_ file contains `main` attribute that points to the generated `lib/index.js` file and `typings` attribute that points to the generated `lib/index.d.ts` file.
|
||||||
|
|
||||||
|
> If you are planning to have code in multiple files (which is quite natural for a NodeJS module) that users can import, make sure you update `src/index.ts` file appropriately.
|
||||||
|
|
||||||
|
Now assuming you have published this amazing module to _npm_ with the name `my-amazing-lib`, and installed it in the module in which you need it -
|
||||||
|
|
||||||
|
- To use the `Greeter` class in a TypeScript file -
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { Greeter } from "my-amazing-lib";
|
||||||
|
|
||||||
|
const greeter = new Greeter("World!");
|
||||||
|
greeter.greet();
|
||||||
|
```
|
||||||
|
|
||||||
|
- To use the `Greeter` class in a JavaScript file -
|
||||||
|
|
||||||
|
```js
|
||||||
|
const Greeter = require('my-amazing-lib').Greeter;
|
||||||
|
|
||||||
|
const greeter = new Greeter('World!');
|
||||||
|
greeter.greet();
|
||||||
|
```
|
||||||
|
|
||||||
|
## Setting travis and coveralls badges
|
||||||
|
1. Sign in to [travis](https://travis-ci.org/) and activate the build for your project.
|
||||||
|
2. Sign in to [coveralls](https://coveralls.io/) and activate the build for your project.
|
||||||
|
3. Replace {{github-user-name}}/{{github-app-name}} with your repo details like: "ospatil/generator-node-typescript".
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
import { Greeter } from '../src/greeter';
|
||||||
|
|
||||||
|
test('Should greet with message', () => {
|
||||||
|
const greeter = new Greeter('friend');
|
||||||
|
expect(greeter.greet()).toBe('Bonjour, friend!');
|
||||||
|
});
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
const mockWind = jest.fn<Window>();
|
||||||
|
const anyGlobal = global as any;
|
||||||
|
anyGlobal.window = new mockWind();
|
||||||
|
|
||||||
|
import * as index from '../src/index';
|
||||||
|
|
||||||
|
test('Should have Greeter available', () => {
|
||||||
|
expect(index.Greeter).toBeTruthy();
|
||||||
|
});
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta content='width=device-width, initial-scale=1, minimum-scale=1.0, maximum-scale=1.0' name='viewport' />
|
||||||
|
<script src="index.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1> open dev tool and console logs</h1>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
{
|
||||||
|
"name": "github-delete-unused-repos",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"description": "github-delete-unused-repos",
|
||||||
|
"license": "MIT",
|
||||||
|
"repository": "",
|
||||||
|
"author": {
|
||||||
|
"name": "",
|
||||||
|
"email": "",
|
||||||
|
"url": ""
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"files": [
|
||||||
|
"lib"
|
||||||
|
],
|
||||||
|
"main": "lib/index.js",
|
||||||
|
"typings": "lib/index.d.ts",
|
||||||
|
"scripts": {
|
||||||
|
"clean": "rimraf lib && rimraf coverage",
|
||||||
|
"format": "prettier --write \"{src,__tests__}/**/*.ts\" --single-quote --trailing-comma es5",
|
||||||
|
"lint": "tslint --force --format verbose \"src/**/*.ts\"",
|
||||||
|
"prepare": "npm run build",
|
||||||
|
"prebuild": "npm run clean && npm run format && npm run lint && echo Using TypeScript && tsc --version",
|
||||||
|
"build": "tsc --pretty && webpack",
|
||||||
|
"dev": "webpack-dev-server --progress --open-page dist/",
|
||||||
|
"demo": "npm run build && http-server dist -o",
|
||||||
|
"test": "jest",
|
||||||
|
"coverage": "jest --coverage",
|
||||||
|
"watch": "npm run build -- --watch",
|
||||||
|
"watch:test": "jest --watch"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@octokit/rest": "^15.6.2",
|
||||||
|
"octonode": "^0.9.2"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/jest": "^22.0.1",
|
||||||
|
"@types/node": "^8.0.0",
|
||||||
|
"babel-loader": "^7.1.2",
|
||||||
|
"babel-preset-env": "^1.6.1",
|
||||||
|
"babel-preset-stage-2": "^6.24.1",
|
||||||
|
"copy-webpack-plugin": "^4.4.1",
|
||||||
|
"coveralls": "^2.0.0",
|
||||||
|
"http-server": "^0.11.1",
|
||||||
|
"jest": "^22.0.4",
|
||||||
|
"jest-environment-node-debug": "^2.0.0",
|
||||||
|
"prettier": "^1.5.2",
|
||||||
|
"rimraf": "^2.0.0",
|
||||||
|
"ts-jest": "^22.0.1",
|
||||||
|
"ts-loader": "^3.4.0",
|
||||||
|
"ts-node": "^3.2.0",
|
||||||
|
"tslint": "^5.0.0",
|
||||||
|
"tslint-config-prettier": "^1.1.0",
|
||||||
|
"typescript": "^2.3.0",
|
||||||
|
"webpack": "^3.10.0",
|
||||||
|
"webpack-dev-server": "^2.11.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.0.0"
|
||||||
|
},
|
||||||
|
"jest": {
|
||||||
|
"transform": {
|
||||||
|
".(ts)": "<rootDir>/node_modules/ts-jest/preprocessor.js"
|
||||||
|
},
|
||||||
|
"testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|js)$",
|
||||||
|
"moduleFileExtensions": [
|
||||||
|
"ts",
|
||||||
|
"js"
|
||||||
|
],
|
||||||
|
"testEnvironment": "node",
|
||||||
|
"mapCoverage": true
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,324 @@
|
|||||||
|
import rest = require('@octokit/rest');
|
||||||
|
import assert = require('assert');
|
||||||
|
|
||||||
|
const octokit = new rest();
|
||||||
|
octokit.authenticate({
|
||||||
|
type: 'oauth',
|
||||||
|
key: '05e5f5ec65387c49137b',
|
||||||
|
secret: '2228539a48032f0622d6c12a66f56253d0a30d60',
|
||||||
|
});
|
||||||
|
|
||||||
|
interface ResponseFromGetUserRepo {
|
||||||
|
data: RepoFromGetUserRepo[];
|
||||||
|
meta: {};
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ResponseFromGetBranches {
|
||||||
|
data: BranchFromGetBranches[];
|
||||||
|
meta: {};
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ResponseFromGetRepo {
|
||||||
|
data: RepoFromGetRepo;
|
||||||
|
meta: {};
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ResponseFromCompareCommits {
|
||||||
|
data: {
|
||||||
|
status: string;
|
||||||
|
ahead_by: number;
|
||||||
|
behind_by: number;
|
||||||
|
total_commits: number;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RepoFromGetUserRepo {
|
||||||
|
default_branch: string;
|
||||||
|
description: string;
|
||||||
|
fork: boolean;
|
||||||
|
full_name: string;
|
||||||
|
homepage: string;
|
||||||
|
id: number;
|
||||||
|
language: string;
|
||||||
|
name: string;
|
||||||
|
owner: OwnerFromGetUserRepo;
|
||||||
|
private: boolean;
|
||||||
|
pushed_at: string;
|
||||||
|
url: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface OwnerFromGetUserRepo {
|
||||||
|
avatar_url: string;
|
||||||
|
gravatar_id: string;
|
||||||
|
html_url: string;
|
||||||
|
id: number;
|
||||||
|
login: string;
|
||||||
|
repos_url: string;
|
||||||
|
type: UserType;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum UserType {
|
||||||
|
User = 'User',
|
||||||
|
}
|
||||||
|
|
||||||
|
interface BranchFromGetBranches {
|
||||||
|
name: string;
|
||||||
|
commit: CommitFromGetBranches;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CommitFromGetBranches {
|
||||||
|
sha: string;
|
||||||
|
url: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RepoFromGetRepo {
|
||||||
|
parent: RepoFromGetUserRepo;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RepoNameWithUnusedFlag {
|
||||||
|
repoName: string;
|
||||||
|
unused: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RepoNameWithBranches {
|
||||||
|
repoName: string;
|
||||||
|
branches: BranchFromGetBranches[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RepoNameWithParentRepo {
|
||||||
|
repoName: string;
|
||||||
|
parentRepo: RepoFromGetUserRepo;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RepoNameWithBranchesAndParent
|
||||||
|
extends RepoNameWithBranches,
|
||||||
|
RepoNameWithParentRepo {}
|
||||||
|
|
||||||
|
const username = 'rousan';
|
||||||
|
|
||||||
|
async function fetchRepoNameWithBranches(
|
||||||
|
repoName: string
|
||||||
|
): Promise<RepoNameWithBranches> {
|
||||||
|
const branchesResponse: ResponseFromGetBranches = await octokit.repos.getBranches(
|
||||||
|
{
|
||||||
|
owner: username,
|
||||||
|
repo: repoName,
|
||||||
|
per_page: 10, // change this
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
repoName,
|
||||||
|
branches: branchesResponse.data,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetchRepoNameWithParentRepo(
|
||||||
|
forkedRepoName: string
|
||||||
|
): Promise<RepoNameWithParentRepo> {
|
||||||
|
const responseRepoDetails: ResponseFromGetRepo = await octokit.repos.get({
|
||||||
|
owner: username,
|
||||||
|
repo: forkedRepoName,
|
||||||
|
});
|
||||||
|
|
||||||
|
const repoDetails = responseRepoDetails.data;
|
||||||
|
|
||||||
|
return {
|
||||||
|
repoName: forkedRepoName,
|
||||||
|
parentRepo: repoDetails.parent,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetchForkBranchIsNotAhead(
|
||||||
|
parentRepoOwner: string,
|
||||||
|
parentRepoName: string,
|
||||||
|
forkedRepoOwner: string,
|
||||||
|
forkedRepoName: string,
|
||||||
|
forkedBranchName: string,
|
||||||
|
parentBranchName?: string
|
||||||
|
): Promise<boolean> {
|
||||||
|
let commitObject: ResponseFromCompareCommits;
|
||||||
|
|
||||||
|
if (parentBranchName === undefined) {
|
||||||
|
parentBranchName = forkedBranchName;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
commitObject = ((await octokit.repos.compareCommits({
|
||||||
|
// both owner and repo can be either parent or forked, for this usecase
|
||||||
|
owner: parentRepoOwner,
|
||||||
|
repo: parentRepoName,
|
||||||
|
base: `${parentRepoOwner}:${parentBranchName}`,
|
||||||
|
head: `${forkedRepoOwner}:${forkedBranchName}`,
|
||||||
|
})) as any) as ResponseFromCompareCommits;
|
||||||
|
} catch {
|
||||||
|
const fallBackParentBranchName = 'master';
|
||||||
|
|
||||||
|
if (parentBranchName !== fallBackParentBranchName) {
|
||||||
|
return fetchForkBranchIsNotAhead(
|
||||||
|
parentRepoOwner,
|
||||||
|
parentRepoName,
|
||||||
|
forkedRepoOwner,
|
||||||
|
forkedRepoName,
|
||||||
|
forkedBranchName,
|
||||||
|
fallBackParentBranchName
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (commitObject.data.ahead_by === 0) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Async determine if parent repo contains all commits which are
|
||||||
|
// currently set as HEAD in each branch of the original repo
|
||||||
|
async function fetchNoneOfForkBranchesIsAhead(
|
||||||
|
repoInfo: RepoNameWithBranchesAndParent
|
||||||
|
): Promise<RepoNameWithUnusedFlag> {
|
||||||
|
const allPromiseBranchUnused = repoInfo.branches.map(tmpBranch => {
|
||||||
|
return fetchForkBranchIsNotAhead(
|
||||||
|
repoInfo.parentRepo.owner.login,
|
||||||
|
repoInfo.parentRepo.name,
|
||||||
|
username,
|
||||||
|
repoInfo.repoName,
|
||||||
|
tmpBranch.name
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
const allBranchUnused = await Promise.all(allPromiseBranchUnused);
|
||||||
|
|
||||||
|
const everyBranchUnused = allBranchUnused.every(
|
||||||
|
tmpBoolean => tmpBoolean === true
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
repoName: repoInfo.repoName,
|
||||||
|
unused: everyBranchUnused,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetchUnusedForkedRepos() {
|
||||||
|
const repos: ResponseFromGetUserRepo = await octokit.repos.getForUser({
|
||||||
|
// tslint:disable-next-line:object-literal-shorthand
|
||||||
|
username: username,
|
||||||
|
// type,
|
||||||
|
// sort,
|
||||||
|
// direction,
|
||||||
|
per_page: 100, // solve pagination // change this value // handle abuse detection
|
||||||
|
// page,
|
||||||
|
});
|
||||||
|
|
||||||
|
const forkedRepoNames = repos.data
|
||||||
|
.filter(repo => repo.fork)
|
||||||
|
.map(repo => repo.name);
|
||||||
|
|
||||||
|
// tslint:disable-next-line:no-console
|
||||||
|
console.log(forkedRepoNames);
|
||||||
|
|
||||||
|
const allPromiseRepoNameWithBranches = forkedRepoNames.map(repoName => {
|
||||||
|
return fetchRepoNameWithBranches(repoName);
|
||||||
|
});
|
||||||
|
|
||||||
|
const allPromiseRepoNameWithParentRepo = forkedRepoNames.map(
|
||||||
|
forkedRepoName => {
|
||||||
|
return fetchRepoNameWithParentRepo(forkedRepoName);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const allRepoNameWithBranches = await Promise.all(
|
||||||
|
allPromiseRepoNameWithBranches
|
||||||
|
);
|
||||||
|
const allRepoNameWithParentRepo = await Promise.all(
|
||||||
|
allPromiseRepoNameWithParentRepo
|
||||||
|
);
|
||||||
|
|
||||||
|
// Both the above list (of objects) have same number of items and
|
||||||
|
// items in the same index (of both lists) have same value for repoName key.
|
||||||
|
|
||||||
|
// So join them together into one list of objects (each object containing branches and parent repo)
|
||||||
|
|
||||||
|
assert.strictEqual(
|
||||||
|
allRepoNameWithBranches.length,
|
||||||
|
allRepoNameWithParentRepo.length,
|
||||||
|
'Length of `allRepoNameWithBranches` and `allRepoNameWithParentRepo` should be same'
|
||||||
|
);
|
||||||
|
|
||||||
|
const allRepoNameWithBranchesAndParent: RepoNameWithBranchesAndParent[] = [];
|
||||||
|
{
|
||||||
|
const tmpLength = allRepoNameWithBranches.length;
|
||||||
|
|
||||||
|
for (let index = 0; index < tmpLength; index++) {
|
||||||
|
const tmpRepoNameWithBranches = allRepoNameWithBranches[index];
|
||||||
|
const tmpRepoNameWithParentRepo = allRepoNameWithParentRepo[index];
|
||||||
|
|
||||||
|
assert.strictEqual(
|
||||||
|
tmpRepoNameWithBranches.repoName,
|
||||||
|
tmpRepoNameWithParentRepo.repoName,
|
||||||
|
'Reponame should be same for objects stored at same index in `allRepoNameWithBranches` and `allRepoNameWithParentRepo`'
|
||||||
|
);
|
||||||
|
|
||||||
|
const repoName = tmpRepoNameWithBranches.repoName;
|
||||||
|
|
||||||
|
const combinedObject: RepoNameWithBranchesAndParent = {
|
||||||
|
repoName,
|
||||||
|
branches: tmpRepoNameWithBranches.branches,
|
||||||
|
parentRepo: tmpRepoNameWithParentRepo.parentRepo,
|
||||||
|
};
|
||||||
|
|
||||||
|
allRepoNameWithBranchesAndParent.push(combinedObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const allPromiseRepoNameWithUnusedFlag = allRepoNameWithBranchesAndParent.map(
|
||||||
|
(repoInfo: RepoNameWithBranchesAndParent) => {
|
||||||
|
return fetchNoneOfForkBranchesIsAhead(repoInfo);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const allRepoNameWithUnusedFlag = await Promise.all(
|
||||||
|
allPromiseRepoNameWithUnusedFlag
|
||||||
|
);
|
||||||
|
|
||||||
|
const unusedRepoNames = allRepoNameWithUnusedFlag
|
||||||
|
.filter(tmp => tmp.unused)
|
||||||
|
.map(tmp => tmp.repoName);
|
||||||
|
|
||||||
|
return unusedRepoNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchUnusedForkedRepos().then(unusedRepoNames => {
|
||||||
|
// tslint:disable-next-line:no-console
|
||||||
|
console.log(unusedRepoNames);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Next steps
|
||||||
|
//
|
||||||
|
// 1. Get all forked repos for a user
|
||||||
|
// https://developer.github.com/v3/repos/#list-user-repositories
|
||||||
|
// https://octokit.github.io/rest.js/#api-Repos-getForUser
|
||||||
|
//
|
||||||
|
// 1.a. Also get (forked) repo's parent repo
|
||||||
|
//
|
||||||
|
// 2. For each forked repo, list all branches
|
||||||
|
// https://developer.github.com/v3/repos/branches/#list-branches
|
||||||
|
// https://octokit.github.io/rest.js/#api-Repos-getBranches
|
||||||
|
// Last commit sha is present in this object
|
||||||
|
//
|
||||||
|
// 3. Compare each branch in the forked repo to same branch in parent repo, and check if the fork one is ahead of the parent {Should not be}
|
||||||
|
// https://developer.github.com/v3/repos/commits/#compare-two-commits
|
||||||
|
// https://octokit.github.io/rest.js/#api-Repos-compareCommits
|
||||||
|
//
|
||||||
|
// 4. If parent contains, then check if user is in contributor list (of forked repo) {Should not contain}
|
||||||
|
// https://developer.github.com/v3/repos/#list-contributors
|
||||||
|
// https://octokit.github.io/rest.js/#api-Repos-getContributors
|
||||||
|
//
|
||||||
|
// 5. Show marked repo names for review
|
||||||
|
//
|
||||||
|
// 6. Delete those repos
|
||||||
|
// https://developer.github.com/v3/repos/#delete-a-repository
|
||||||
|
// https://octokit.github.io/rest.js/#api-Repos-delete
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
export class Greeter {
|
||||||
|
private greeting: string;
|
||||||
|
|
||||||
|
constructor(message: string) {
|
||||||
|
this.greeting = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public greet(): string {
|
||||||
|
return `Bonjour, ${this.greeting}!`;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import { Greeter } from './greeter';
|
||||||
|
export * from './greeter';
|
||||||
|
|
||||||
|
// tslint:disable-next-line:only-arrow-functions
|
||||||
|
(function(currentWindow: Window) {
|
||||||
|
// execute when load index.js
|
||||||
|
|
||||||
|
// tslint:disable-next-line:no-console
|
||||||
|
console.log('hello world');
|
||||||
|
|
||||||
|
// assign Greeter to global
|
||||||
|
const myWindow = currentWindow as any;
|
||||||
|
myWindow.Greeter = Greeter;
|
||||||
|
// we can use Greeter , execute following in console
|
||||||
|
// var greet = new Greeter('myName');
|
||||||
|
// greet.greet();
|
||||||
|
})(window);
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"declaration": true,
|
||||||
|
"module": "commonjs",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"lib": [
|
||||||
|
"esnext",
|
||||||
|
"dom"
|
||||||
|
],
|
||||||
|
"target": "es2015",
|
||||||
|
"strict": true,
|
||||||
|
"outDir": "./lib",
|
||||||
|
"preserveConstEnums": true,
|
||||||
|
"removeComments": true,
|
||||||
|
"inlineSourceMap": true,
|
||||||
|
"typeRoots": [
|
||||||
|
"./node_modules/@types"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"src/**/*"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules",
|
||||||
|
"**/*-spec.ts"
|
||||||
|
]
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"extends": [
|
||||||
|
"tslint:latest",
|
||||||
|
"tslint-config-prettier"
|
||||||
|
],
|
||||||
|
"rules": {
|
||||||
|
"only-arrow-functions": false,
|
||||||
|
"object-literal-sort-keys":false,
|
||||||
|
"interface-name":false
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
const webpack = require("webpack");
|
||||||
|
const CopyWebpackPlugin = require('copy-webpack-plugin');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
devtool: 'inline-source-map',
|
||||||
|
entry: {
|
||||||
|
"index": './src/index.ts',
|
||||||
|
"index.min": './src/index.ts',
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
filename: 'dist/[name].js'
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
// Add `.ts` and `.tsx` as a resolvable extension.
|
||||||
|
extensions: ['.ts', '.tsx', '.js']
|
||||||
|
},
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{ test: /\.js$/, loader: 'babel-loader' },
|
||||||
|
// all files with a `.ts` or `.tsx` extension will be handled by `ts-loader`
|
||||||
|
{ test: /\.tsx?$/, loader: 'babel-loader!ts-loader' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new webpack.optimize.UglifyJsPlugin({
|
||||||
|
include: /\.min\.js$/,
|
||||||
|
minimize: true
|
||||||
|
}) ,
|
||||||
|
new CopyWebpackPlugin([
|
||||||
|
{ from: 'demo/index.html', to: 'dist/' }
|
||||||
|
])
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user