Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
motet-a committed Jul 8, 2017
0 parents commit 1be4cb4
Show file tree
Hide file tree
Showing 58 changed files with 9,394 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
client/node_modules
server/node_modules
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/client/node_modules
/client/dist
/server/node_modules
/server/var
/build-output
19 changes: 19 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
FROM node:8.1.3-slim

RUN apt-get update \
&& apt-get install -y --no-install-recommends git grep \
&& rm -rf /var/lib/apt/lists/*

ENV NODE_ENV=production

RUN mkdir -p /gs/client

COPY build-output/gs/client/dist /gs/client/dist
COPY client/index.html /gs/client/

COPY build-output/gs/server /gs/server
COPY server/src /gs/server/src

WORKDIR /gs/server

CMD ["node", "src/index.js"]
20 changes: 20 additions & 0 deletions Dockerfile.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
FROM node:8.1.3

RUN apt-get update \
&& apt-get install -y --no-install-recommends python \
&& rm -rf /var/lib/apt/lists/*

ENV NODE_ENV=production

RUN mkdir -p /gs/server /gs/client
WORKDIR /gs

COPY server/package.json server/yarn.lock server/
RUN cd server && yarn

COPY client/package.json client/yarn.lock client/
RUN cd client && yarn install --production=false

COPY client/src client/src
COPY client/.babelrc client/webpack.config.js client/
RUN cd client && yarn run build
20 changes: 20 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Copyright 2017 Antoine Motet <[email protected]>

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.
45 changes: 45 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@

# gtsearch

This is a web server and web client for GNU grep and Git
repositories. It is a kind of a much simpler [Hound] or [Livegrep],
which does not require to index files.

[Here](http://gtsearch.3.141.ovh/) is a running demo instance.

# Is it slow?

Yes and no. `grep` on Linux is blazing fast on small
repositories. Moreover, the `gtsearch` server streams results via
WebSockets to the client in order to show the first matches instantly.

`gtsearch` starts one `grep` process per search. When some results
doesn't fit on the client screen, the `grep` process is paused (with
`kill(SIGTSTP)`). When the user scrolls down the result list, the
server resumes the `grep` process (with `kill(SIGCONT)`). When the
user starts a new search, the previous `grep` process is killed (with
`kill(SIGTERM)`). It’s a bit tricky but it works.

However, `grep` is much slower with specific queries on very large
repositories. Consider using [Hound] or [Livegrep] instead.

# Regexps?

Currently no, but it’s really easy to implement since `grep` supports
them. Please send PRs.

# Deploy

```sh
docker run --d -p 8080:8080 -e GTSEARCH_ADDRESS=0.0.0.0 moteta/gtsearch:0.2
```

It listens on `localhost` by default.

The repositories and the SQLite files are stored in `/gs/server/var/`
in the container. Feel free to create a volume.

That’s it.

[Hound]: https://github.com/etsy/hound
[livegrep]: https://github.com/livegrep/livegrep
13 changes: 13 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/sh -e

cd "$(dirname "$0")"

rm -Rf build-output
docker build -t gtsearch-build -f Dockerfile.build .
docker run -d --name gtsearch-build-1 gtsearch-build /bin/sh
mkdir build-output
docker cp gtsearch-build-1:/gs build-output
docker stop gtsearch-build-1
docker rm gtsearch-build-1

docker build -t gtsearch .
15 changes: 15 additions & 0 deletions client/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"plugins": [
"transform-object-rest-spread",
"transform-class-properties"
],
"env": {
"production": {
"presets": ["es2017", "es2016", "es2015"],
"plugins": [
"transform-object-rest-spread",
"transform-class-properties"
]
}
}
}
14 changes: 14 additions & 0 deletions client/Dockerfile.dev
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
FROM node:8.1.3-alpine

RUN mkdir -p /gs/client
WORKDIR /gs/client

COPY package.json yarn.lock ./

ENV NODE_ENV=development

RUN yarn

COPY .babelrc webpack.config.js ./

CMD ["yarn", "run", "watch"]
17 changes: 17 additions & 0 deletions client/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!DOCTYPE html>

<html>
<head>
<meta charset="UTF-8"/>
<title>gtsearch</title>

<link rel="stylesheet" href="/static/main.css"/>
</head>

<body>
<div id="react-root">
</div>

<script src="/static/main.js"></script>
</body>
</html>
40 changes: 40 additions & 0 deletions client/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"name": "gtsearch-client",
"private": true,
"version": "0.0.1",
"main": "index.js",
"author": "Antoine Motet",
"license": "MIT",
"scripts": {
"build": "webpack --config webpack.config.js",
"watch": "webpack --config webpack.config.js --watch"
},
"devDependencies": {
"babel-core": "^6.25.0",
"babel-loader": "^7.1.0",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-plugin-transform-object-rest-spread": "^6.23.0",
"babel-preset-es2015": "^6.24.1",
"babel-preset-es2016": "^6.24.1",
"babel-preset-es2017": "^6.24.1",
"css-loader": "^0.28.4",
"extract-text-webpack-plugin": "3.0.0-beta.3",
"node-sass": "^4.5.3",
"sass-loader": "^6.0.6",
"style-loader": "^0.18.2",
"uglifyjs-webpack-plugin": "^0.4.6",
"webpack": "^3.0.0"
},
"dependencies": {
"classnames": "^2.2.5",
"lodash": "^4.17.4",
"react": "^15.6.1",
"react-dom": "^15.6.1",
"react-redux": "^5.0.5",
"react-router5": "^4.3.0",
"react-waypoint": "^7.0.4",
"redux": "^3.7.0",
"redux-thunk": "^2.2.0",
"router5": "^4.7.1"
}
}
173 changes: 173 additions & 0 deletions client/src/actions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@

import {send as wsSend} from './ws'



const requestLogin = plaintextPassword => dispatch => {
dispatch({type: 'wsRequestLogin'})
wsSend({type: 'login', plaintextPassword})
}

const receiveLogin = () => ({
type: 'wsReceiveLogin',
})

const receiveLoginError = error => ({
type: 'wsReceiveLoginError',
error,
})



const requestLogout = () => dispatch => {
dispatch({type: 'wsRequestLogout'})
wsSend({type: 'logout'})
}



const requestRepos = () => dispatch => {
dispatch({type: 'wsRequestRepos'})
wsSend({type: 'fetchRepos'})
}

const receiveRepos = repos => ({
type: 'wsReceiveRepos',
repos,
})



const requestRepo = name => dispatch => {
dispatch({type: 'wsRequestRepo', name})
wsSend({type: 'fetchRepo', name})
}

const receiveRepo = repo => ({
type: 'wsReceiveRepo',
repo,
})

const receiveRepoNotFound = name => ({
type: 'wsReceiveRepoNotFound',
name,
})



const requestCreateRepo = repo => dispatch => {
dispatch({type: 'wsRequestCreateRepo', repo})
wsSend({type: 'createRepo', ...repo})
}

const receiveCreateRepo = name => ({
type: 'wsReceiveCreateRepo',
name,
})

const receiveCreateRepoError = error => ({
type: 'wsReceiveCreateRepoError',
error,
})



const requestDeleteRepo = name => dispatch => {
dispatch({type: 'wsRequestDeleteRepo', name})
wsSend({type: 'deleteRepo', name})
}

const receiveDeleteRepo = name => ({
type: 'wsReceiveDeleteRepo',
name,
})

const receiveDeleteRepoError = error => ({
type: 'wsReceiveDeleteRepoError',
error,
})



const requestPullRepo = name => dispatch => {
dispatch({type: 'wsRequestPullRepo', name})
wsSend({type: 'pullRepo', name})
}

const receivePullRepo = name => ({
type: 'wsReceivePullRepo',
name,
})

const receivePullRepoError = error => ({
type: 'wsReceivePullRepoError',
error,
})



const requestSearch = ({repoName, query}) => dispatch => {
dispatch({type: 'wsRequestSearch', repoName, query})
if (query) {
wsSend({type: 'search', repoName, query})
} else {
dispatch(receiveSearchEnd({repoName, query}))
}
}

const requestSearchLoadMore = () => dispatch => {
wsSend({type: 'searchLoadMore'})
}

const receiveSearchResults = ({repoName, query, results}) => ({
type: 'wsReceiveSearchResults',
repoName,
query,
results,
})

const receiveSearchEnd = ({repoName, query}) => ({
type: 'wsReceiveSearchEnd',
repoName,
query,
})


const boostrap = () => ({
type: 'wsConnected',
})


export default {
requestLogin,
receiveLogin,
receiveLoginError,

requestRepos,
receiveRepos,

requestRepo,
receiveRepo,
receiveRepoNotFound,

requestCreateRepo,
receiveCreateRepo,
receiveCreateRepoError,

requestDeleteRepo,
receiveDeleteRepo,
receiveDeleteRepoError,

requestPullRepo,
receivePullRepo,
receivePullRepoError,

requestLogout,

requestSearch,
requestSearchLoadMore,
receiveSearchResults,
receiveSearchEnd,

boostrap,
}
Loading

0 comments on commit 1be4cb4

Please sign in to comment.