aboutsummaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
authorMartin Fischer <martin@push-f.com>2021-06-23 22:46:31 +0200
committerMartin Fischer <martin@push-f.com>2021-06-23 22:50:55 +0200
commit43b4b8693890a85f24eb358bc5545232ebf8e796 (patch)
treec83bbcacae18b034037399c197e1976346c40eb9 /src/main.rs
parentca074febae4cd56ad5443c110a15662fa110dd81 (diff)
make single-user mode operate on HEAD branch
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs85
1 files changed, 22 insertions, 63 deletions
diff --git a/src/main.rs b/src/main.rs
index d521087..30f018b 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,6 +1,5 @@
use clap::Clap;
use controller::Controller;
-use git2::BranchType;
use git2::Commit;
use git2::ObjectType;
use git2::Oid;
@@ -103,7 +102,19 @@ async fn main() {
if args.multiuser {
serve(MultiUserController::new(&repo), args).await;
} else {
- serve(SoloController, args).await;
+ serve(
+ SoloController(Branch(
+ repo.find_reference("HEAD")
+ .unwrap()
+ .symbolic_target()
+ .unwrap()
+ .strip_prefix("refs/heads/")
+ .unwrap()
+ .to_owned(),
+ )),
+ args,
+ )
+ .await;
}
}
@@ -195,7 +206,7 @@ pub enum Error {
// TODO: use Redirect instead
/// Missing trailing slash.
- MissingTrailingSlash(Parts),
+ MissingTrailingSlash(String),
}
impl From<Utf8Error> for Error {
@@ -223,10 +234,10 @@ async fn service<C: Controller>(
Error::Forbidden(msg) => (403, msg),
Error::NotFound(msg) => (404, msg),
Error::Internal(msg) => (500, msg),
- Error::MissingTrailingSlash(parts) => {
+ Error::MissingTrailingSlash(path) => {
return Builder::new()
.status(StatusCode::FOUND)
- .header("location", format!("{}/", parts.uri.path()))
+ .header("location", format!("{}/", path))
.body("redirecting".into())
.unwrap();
}
@@ -321,11 +332,6 @@ impl From<git2::Error> for Error {
}
}
-/// Builds a URL path from a given Git revision and filepath.
-fn build_url_path(rev: &Branch, path: &str) -> String {
- format!("/~{}/{}", rev.0, path)
-}
-
#[derive(Eq, PartialEq, Hash, Clone)]
pub struct Branch(String);
@@ -341,7 +347,6 @@ async fn build_response<C: Controller>(
parts: Parts,
body: Body,
) -> Result<Response, Error> {
- controller.before_route(&parts)?;
let unsanitized_path = percent_decode_str(parts.uri.path())
.decode_utf8()
.map_err(|_| Error::BadRequest("failed to percent-decode path as UTF-8".into()))?
@@ -349,58 +354,11 @@ async fn build_response<C: Controller>(
let repo = Repository::open_bare(env::current_dir().unwrap()).unwrap();
- if parts.uri.path() == "/" {
- // TODO: add domain name to title?
- let mut page = Page {
- title: "GitPad".into(),
- controller,
- parts: &parts,
- body: String::new(),
- header: None,
- };
-
- let branches: Vec<_> = repo.branches(Some(BranchType::Local))?.collect();
-
- page.body.push_str("This GitPad instance has ");
-
- if branches.is_empty() {
- page.body.push_str("no branches yet.");
-
- if !args.multiuser {
- page.body.push_str("<p>Start by creating for example <a href='/~main/todo.md'>/~main/todo.md</a>.</p>");
- }
- } else {
- page.body.push_str("the following branches:");
- page.body.push_str("<ul>");
- for (branch, _) in repo.branches(Some(BranchType::Local))?.flatten() {
- page.body.push_str(&format!(
- "<li><a href='~{0}/'>~{0}</a></li>",
- html_escape(branch.name()?.unwrap())
- ));
- }
- page.body.push_str("</ul>");
- }
-
- return Ok(page.into());
+ if let Some(resp) = controller.before_route(&parts, &repo) {
+ return resp;
}
- let mut iter = unsanitized_path.splitn(3, '/');
- iter.next();
- let rev = iter.next().unwrap();
- if !rev.starts_with('~') {
- return Err(Error::NotFound(
- "branch name must be prefixed a tilde (~)".into(),
- ));
- }
- let rev = &rev[1..];
- if rev.trim().is_empty() {
- return Err(Error::NotFound("invalid branch name".into()));
- }
- let rev = Branch(rev.to_owned());
- let unsanitized_path = match iter.next() {
- Some(value) => value,
- None => return Err(Error::MissingTrailingSlash(parts)),
- };
+ let (rev, unsanitized_path) = controller.parse_url_path(&unsanitized_path)?;
let mut comps = Vec::new();
@@ -478,7 +436,8 @@ async fn build_response<C: Controller>(
.status(StatusCode::FOUND)
.header(
"location",
- build_url_path(&ctx.branch, unsanitized_path.trim_end_matches('/')),
+ controller
+ .build_url_path(&ctx.branch, unsanitized_path.trim_end_matches('/')),
)
.body("redirecting".into())
.unwrap());
@@ -488,7 +447,7 @@ async fn build_response<C: Controller>(
tree = ctx.repo.find_tree(entr.id());
if !unsanitized_path.ends_with('/') {
- return Err(Error::MissingTrailingSlash(ctx.parts));
+ return Err(Error::MissingTrailingSlash(ctx.parts.uri.path().to_owned()));
}
}