Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 18 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ on: [push, pull_request]
jobs:
ubuntu-gcc:
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- name: Checkout V
uses: actions/checkout@v4
Expand All @@ -26,7 +27,8 @@ jobs:
cd gitly
v -cc gcc .

- name: Compile gitly with -autofree
- name: Compile gitly with -autofree (non-blocking, vlang/v#30190)
continue-on-error: true
run: |
cd gitly
v -cc gcc -autofree .
Expand Down Expand Up @@ -54,6 +56,7 @@ jobs:

macos-clang:
runs-on: macos-latest
timeout-minutes: 60
steps:
- name: Checkout V
uses: actions/checkout@v4
Expand All @@ -71,7 +74,8 @@ jobs:
run: |
cd gitly
v -cc clang .
- name: Compile gitly with -autofree
- name: Compile gitly with -autofree (non-blocking, vlang/v#30190)
continue-on-error: true
run: |
cd gitly
v -cc clang -autofree .
Expand All @@ -95,6 +99,7 @@ jobs:

windows-gcc:
runs-on: windows-latest
timeout-minutes: 60
env:
VFLAGS: -cc gcc
steps:
Expand All @@ -107,21 +112,23 @@ jobs:
with:
path: gitly
- name: Build V
shell: cmd
run: |
./make.bat -gcc

# Must come after "Build V": this used to run first, when neither `v`
# nor `v.exe` existed, so the referenced script could not work at all.
make.bat -gcc
# Must run after "Build V": the script shells out to `v.exe`, which
# does not exist until V is built.
- name: Install SQLite
run: .\gitly\.github\workflows\windows-install-sqlite.bat

shell: cmd
run: |
gitly\.github\workflows\windows-install-sqlite.bat
- name: Compile gitly
run: |
dir
.\v.exe -cc gcc gitly
.\v.exe -cc gcc -d sqlite gitly

ubuntu-tcc:
runs-on: ubuntu-latest
timeout-minutes: 60
env:
VFLAGS: -cc tcc -d no_backtrace -d no_segfault_handler
steps:
Expand All @@ -141,7 +148,8 @@ jobs:
make
sudo ./v symlink

- name: Compile gitly with -autofree
- name: Compile gitly with -autofree (non-blocking, vlang/v#30190)
continue-on-error: true
run: |
cd gitly
v -autofree .
Expand Down
1 change: 1 addition & 0 deletions fork.v
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ fn (mut app App) create_fork(source Repo, owner_name string, owner_user_id int,
disable_projects: source.disable_projects
disable_milestones: source.disable_milestones
disable_wiki: source.disable_wiki
topics: source.topics
}
app.add_repo(row) or {
os.rmdir_all(target_path) or {}
Expand Down
1 change: 1 addition & 0 deletions gitly.v
Original file line number Diff line number Diff line change
Expand Up @@ -740,6 +740,7 @@ fn (mut app App) migrate_tables() ! {
app.add_missing_column('Repo', 'require_signed_commits', db_bool_column_type())!
app.add_missing_column('Repo', 'service_desk_enabled', db_bool_column_type())!
app.add_missing_column('Repo', 'service_desk_token_hash', "TEXT NOT NULL DEFAULT ''")!
app.add_missing_column('Repo', 'topics', "TEXT NOT NULL DEFAULT ''")!
app.add_missing_column('Issue', 'status', 'INTEGER NOT NULL DEFAULT 0')!
app.add_missing_column('Release', 'created_by', 'INTEGER NOT NULL DEFAULT 0')!
app.add_missing_column('Release', 'is_manual', db_bool_column_type())!
Expand Down
71 changes: 39 additions & 32 deletions repo/repo.v
Original file line number Diff line number Diff line change
Expand Up @@ -16,33 +16,34 @@ struct Repo {
user_id int
user_name string
description string
topics string
is_public bool
is_deleted bool
users_contributed []string @[skip]
users_authorized []string @[skip]
nr_topics int @[skip]
nr_topics int @[skip]
views_count int
latest_update_hash string @[skip]
latest_update_hash string @[skip]
latest_activity time.Time @[skip]
mut:
clone_url string @[skip]
primary_branch string
webhook_secret string
tags_count int
nr_open_issues int @[orm: 'open_issues_count']
nr_open_prs int @[orm: 'open_prs_count']
nr_releases int @[orm: 'releases_count']
nr_branches int @[orm: 'branches_count']
nr_open_issues int @[sql: 'open_issues_count']
nr_open_prs int @[sql: 'open_prs_count']
nr_releases int @[sql: 'releases_count']
nr_branches int @[sql: 'branches_count']
nr_tags int
nr_stars int @[orm: 'stars_count']
nr_stars int @[sql: 'stars_count']
lang_stats []LangStat @[skip]
created_at int
nr_contributors int
labels []Label @[skip]
status RepoStatus
msg_cache map[string]string @[skip]
latest_commit_at int @[skip]
activity_buckets []int @[skip]
latest_commit_at int @[skip]
activity_buckets []int @[skip]
disable_discussions bool
disable_projects bool
disable_milestones bool
Expand Down Expand Up @@ -370,6 +371,12 @@ fn (mut app App) update_repo_features(repo_id int, disable_discussions bool, dis
}!
}

fn (mut app App) update_repo_topics(repo_id int, new_topics string) ! {
sql app.db {
update Repo set topics = new_topics where id == repo_id
}!
}

fn (mut app App) update_repo_general_settings(repo_id int, description string, is_public bool, primary_branch string) ! {
if repo_id <= 0 || description.len > max_repo_description_len || !is_safe_ref(primary_branch) {
return error('invalid repository settings')
Expand Down Expand Up @@ -904,7 +911,7 @@ fn (mut app App) update_repo_after_ref_changes(repo_id int, updates []git.GitRef
// handle is not safe for concurrent use across threads.
fn bg_recompute_lang_stats(repo_id int, conf config.Config) {
mut app := &App{
db: connect_db(conf) or {
db: connect_db(conf) or {
eprintln('bg_recompute_lang_stats: cannot open ${db_backend_name()} db: ${err}')
return
}
Expand Down Expand Up @@ -965,10 +972,10 @@ fn (r &Repo) analyze_lang(app &App) ! {
}
lang_data := langs[lang]
d_lang_stats << LangStat{
repo_id: r.id
name: lang_data.name
pct: pct
color: lang_data.color
repo_id: r.id
name: lang_data.name
pct: pct
color: lang_data.color
lines_count: amount
}
}
Expand Down Expand Up @@ -1103,12 +1110,12 @@ fn (r &Repo) parse_ls(ls_line string, branch string) ?File {
}

return File{
name: item_name
parent_path: parent_path
repo_id: r.id
branch: branch
is_dir: item_type == 'tree'
size: if item_type == 'blob' { item_size.int() } else { 0 }
name: item_name
parent_path: parent_path
repo_id: r.id
branch: branch
is_dir: item_type == 'tree'
size: if item_type == 'blob' { item_size.int() } else { 0 }
is_size_calculated: item_type == 'blob'
}
}
Expand Down Expand Up @@ -1145,12 +1152,12 @@ fn (r &Repo) parse_top_file_line(line string, branch string) ?File {
parent_path := if parent_path_raw == '.' { '' } else { parent_path_raw }

return File{
name: item_name
parent_path: parent_path
repo_id: r.id
branch: branch
is_dir: false
size: meta_parts[3].int()
name: item_name
parent_path: parent_path
repo_id: r.id
branch: branch
is_dir: false
size: meta_parts[3].int()
is_size_calculated: true
}
}
Expand All @@ -1176,12 +1183,12 @@ fn (r &Repo) lookup_file_via_git(branch string, path string) ?File {
parent_path_raw := os.dir(item_path)
parent_path := if parent_path_raw == '.' { '' } else { parent_path_raw }
return File{
name: item_name
parent_path: parent_path
repo_id: r.id
branch: branch
is_dir: false
size: meta_parts[3].int()
name: item_name
parent_path: parent_path
repo_id: r.id
branch: branch
is_dir: false
size: meta_parts[3].int()
is_size_calculated: true
}
}
Expand Down
49 changes: 31 additions & 18 deletions repo/repo_routes.v
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,19 @@ pub fn (mut app App) handle_update_repo_features(mut ctx Context, username strin
return ctx.redirect('/${username}/${repo_name}/settings')
}

@['/:username/:repo_name/settings/topics'; post]
pub fn (mut app App) handle_update_repo_topics(mut ctx Context, username string, repo_name string) veb.Result {
repo := app.find_repo_by_name_and_username(repo_name, username) or {
return ctx.redirect_to_repository(username, repo_name)
}
if !app.can_admin_repo(ctx, repo) {
return ctx.redirect_to_repository(username, repo_name)
}
topics := ctx.form['topics'] or { '' }
app.update_repo_topics(repo.id, topics) or { app.info(err.str()) }
return ctx.redirect('/${username}/${repo_name}/settings')
}

@['/:user/:repo_name/delete'; post]
pub fn (mut app App) handle_repo_delete(mut ctx Context, username string, repo_name string) veb.Result {
repo := app.find_repo_by_name_and_username(repo_name, username) or {
Expand Down Expand Up @@ -456,15 +469,15 @@ pub fn (mut app App) handle_new_repo(mut ctx Context, name string, clone_url str
}
repo_path := os.join_path(owner_dir, name)
mut new_repo := &Repo{
name: name
description: description
git_dir: repo_path
user_id: ctx.user.id
name: name
description: description
git_dir: repo_path
user_id: ctx.user.id
primary_branch: default_primary_branch
user_name: owner_name
clone_url: valid_clone_url
is_public: is_public
created_at: int(time.now().unix())
user_name: owner_name
clone_url: valid_clone_url
is_public: is_public
created_at: int(time.now().unix())
}
import_issues := ctx.form['import_issues'] == '1'
import_prs := ctx.form['import_prs'] == '1'
Expand Down Expand Up @@ -544,7 +557,7 @@ pub fn (mut app App) handle_new_repo(mut ctx Context, name string, clone_url str
fn bg_fetch_files_info(repo_ Repo, branch string, path string, conf config.Config) {
mut repo := repo_
mut app := &App{
db: connect_db(conf) or {
db: connect_db(conf) or {
eprintln('cannot open ${db_backend_name()} db connection for bg_fetch thread: ${err}')
return
}
Expand Down Expand Up @@ -575,7 +588,7 @@ fn clone_repo(new_repo Repo, conf config.Config, import_issues bool, import_prs
// Use a dedicated DB connection for the clone thread to avoid
// sharing a connection across threads.
mut app := &App{
db: connect_db(conf) or {
db: connect_db(conf) or {
eprintln('cannot open ${db_backend_name()} db connection for clone thread: ${err}')
return
}
Expand Down Expand Up @@ -636,7 +649,7 @@ fn clone_repo(new_repo Repo, conf config.Config, import_issues bool, import_prs
fn bg_import_github_repo_info(repo_id int, clone_url string, existing_description string, conf config.Config) {
eprintln('[github-info] spawned thread for repo_id=${repo_id}')
mut app := &App{
db: connect_db(conf) or {
db: connect_db(conf) or {
eprintln('[github-info] cannot open db connection: ${err}')
return
}
Expand All @@ -661,7 +674,7 @@ fn bg_import_github_repo_info(repo_id int, clone_url string, existing_descriptio
fn bg_import_github_issues(repo_id int, clone_url string, owner_user_id int, conf config.Config) {
eprintln('[github-import] spawned thread for repo_id=${repo_id}')
mut app := &App{
db: connect_db(conf) or {
db: connect_db(conf) or {
eprintln('[github-import] cannot open db connection for import thread: ${err}')
return
}
Expand Down Expand Up @@ -981,7 +994,7 @@ pub fn (mut app App) handle_api_repo_star(mut ctx Context, repo_id_str string) v

return ctx.json(api.ApiSuccessResponse[bool]{
success: true
result: is_repo_starred
result: is_repo_starred
})
}

Expand All @@ -1002,7 +1015,7 @@ pub fn (mut app App) handle_api_repo_watch(mut ctx Context, repo_id_str string)

return ctx.json(api.ApiSuccessResponse[bool]{
success: true
result: is_watching
result: is_watching
})
}

Expand Down Expand Up @@ -1031,17 +1044,17 @@ pub fn (mut app App) handle_api_repo_files(mut ctx Context, repo_id_str string)
mut result := []RepoFileInfo{}
for item in items {
result << RepoFileInfo{
name: item.name
last_msg: item.last_msg
name: item.name
last_msg: item.last_msg
last_hash: item.last_hash
last_time: item.pretty_last_time()
size: item.pretty_tree_size()
size: item.pretty_tree_size()
}
}

return ctx.json(api.ApiSuccessResponse[[]RepoFileInfo]{
success: true
result: result
result: result
})
}

Expand Down
9 changes: 9 additions & 0 deletions templates/repo/settings.html
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,15 @@ <h2 class="settings-section__title">%features_section_title</h2>
</label>
<input type="submit" class="settings-form__submit" value="%save_features">
</form>

<section class="settings-section">
<h2 class="settings-section__title">Topics</h2>
<form class="settings-form" action="/@repo.user_name/@repo.name/settings/topics" method="post">
<label class="settings-form__label" for="topics">Topics (comma separated)</label>
<input type="text" id="topics" name="topics" class="settings-form__input" value="@repo.topics">
<input type="submit" class="settings-form__submit" value="Save topics">
</form>
</section>
</section>

<section class="settings-section">
Expand Down
7 changes: 7 additions & 0 deletions templates/tree.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@
<div class="content">
<div class="repo-header-area">
@include 'layout/repo_menu.html'
@if repo.topics != ''
<div class="repo-topics">
@for topic in repo.topics.split(',')
<span class="repo-topic">@topic.trim_space()</span>
@end
</div>
@end
@if is_top_directory
<div class="fork-summary">
@if upstream_repo.id > 0
Expand Down
Loading