Merge branch 'feature_optimize_project_creation_process' into develop
This commit is contained in:
commit
29ec3bed09
|
@ -338,10 +338,10 @@ http://localhost:3000/api/projects/ | jq
|
||||||
|-|-|-|-|
|
|-|-|-|-|
|
||||||
|user_id |是|int |用户id或者组织id |
|
|user_id |是|int |用户id或者组织id |
|
||||||
|name |是|string |项目名称 |
|
|name |是|string |项目名称 |
|
||||||
|description |是|string |项目描述 |
|
|description |否|string |项目描述 |
|
||||||
|repository_name |是|string |仓库名称, 只含有数字、字母、下划线不能以下划线开头和结尾,且唯一 |
|
|repository_name |是|string |仓库名称, 只含有数字、字母、下划线不能以下划线开头和结尾,且唯一 |
|
||||||
|project_category_id|是|int |项目类别id |
|
|project_category_id|否|int |项目类别id |
|
||||||
|project_language_id|是|int |项目语言id |
|
|project_language_id|否|int |项目语言id |
|
||||||
|ignore_id |否|int |gitignore相关id |
|
|ignore_id |否|int |gitignore相关id |
|
||||||
|license_id |否|int |开源许可证id |
|
|license_id |否|int |开源许可证id |
|
||||||
|private |否|boolean|项目是否私有, true:为私有,false: 公开,默认为公开 |
|
|private |否|boolean|项目是否私有, true:为私有,false: 公开,默认为公开 |
|
||||||
|
@ -374,9 +374,7 @@ curl -X POST \
|
||||||
-d "user_id=36408" \
|
-d "user_id=36408" \
|
||||||
-d "clone_addr=https://gitea.com/mx8090alex/golden.git" \
|
-d "clone_addr=https://gitea.com/mx8090alex/golden.git" \
|
||||||
-d "name=golden_mirror1" \
|
-d "name=golden_mirror1" \
|
||||||
-d "description=golden_mirror" \
|
-d "repository_name=golden_mirror1" \
|
||||||
-d "project_category_id=1" \
|
|
||||||
-d "project_language_id=2" \
|
|
||||||
http://localhost:3000/api/projects/migrate.json | jq
|
http://localhost:3000/api/projects/migrate.json | jq
|
||||||
```
|
```
|
||||||
*请求参数说明:*
|
*请求参数说明:*
|
||||||
|
@ -388,8 +386,8 @@ http://localhost:3000/api/projects/migrate.json | jq
|
||||||
|clone_addr |是|string |镜像项目clone地址 |
|
|clone_addr |是|string |镜像项目clone地址 |
|
||||||
|description |否|string |项目描述 |
|
|description |否|string |项目描述 |
|
||||||
|repository_name |是|string |仓库名称, 只含有数字、字母、下划线不能以下划线开头和结尾,且唯一 |
|
|repository_name |是|string |仓库名称, 只含有数字、字母、下划线不能以下划线开头和结尾,且唯一 |
|
||||||
|project_category_id|是|int |项目类别id |
|
|project_category_id|否|int |项目类别id |
|
||||||
|project_language_id|是|int |项目语言id |
|
|project_language_id|否|int |项目语言id |
|
||||||
|is_mirror |否|boolean|是否设置为镜像, true:是, false:否,默认为否 |
|
|is_mirror |否|boolean|是否设置为镜像, true:是, false:否,默认为否 |
|
||||||
|auth_username |否|string|镜像源仓库的登录用户名 |
|
|auth_username |否|string|镜像源仓库的登录用户名 |
|
||||||
|auth_password |否|string|镜像源仓库的登录秘密 |
|
|auth_password |否|string|镜像源仓库的登录秘密 |
|
||||||
|
|
|
@ -41,7 +41,7 @@ module LaboratoryHelper
|
||||||
my_courses: "https://www.trustie.net/users/#{current_user.try(:login)}/user_courselist",
|
my_courses: "https://www.trustie.net/users/#{current_user.try(:login)}/user_courselist",
|
||||||
my_projects: "/users/#{current_user.try(:login)}/projects",
|
my_projects: "/users/#{current_user.try(:login)}/projects",
|
||||||
my_organ: "https://www.trustie.net/users/#{current_user.try(:login)}/user_organizations",
|
my_organ: "https://www.trustie.net/users/#{current_user.try(:login)}/user_organizations",
|
||||||
default_url: "https://www.trustie.net/",
|
default_url: Rails.application.config_for(:configuration)['platform_url'],
|
||||||
tiding_url: "https://www.trustie.net/users/#{current_user.try(:login)}/user_messages",
|
tiding_url: "https://www.trustie.net/users/#{current_user.try(:login)}/user_messages",
|
||||||
register_url: "https://www.trustie.net/login?login=false"
|
register_url: "https://www.trustie.net/login?login=false"
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,6 @@ class ProjectsController < ApplicationController
|
||||||
|
|
||||||
def create
|
def create
|
||||||
ActiveRecord::Base.transaction do
|
ActiveRecord::Base.transaction do
|
||||||
tip_exception("无法使用以下关键词:#{project_params[:repository_name]},请重新命名") if ReversedKeyword.is_reversed(project_params[:repository_name]).present?
|
|
||||||
Projects::CreateForm.new(project_params).validate!
|
Projects::CreateForm.new(project_params).validate!
|
||||||
@project = Projects::CreateService.new(current_user, project_params).call
|
@project = Projects::CreateService.new(current_user, project_params).call
|
||||||
|
|
||||||
|
@ -57,7 +56,6 @@ class ProjectsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def migrate
|
def migrate
|
||||||
tip_exception("无法使用以下关键词:#{mirror_params[:repository_name]},请重新命名") if ReversedKeyword.is_reversed(mirror_params[:repository_name]).present?
|
|
||||||
Projects::MigrateForm.new(mirror_params).validate!
|
Projects::MigrateForm.new(mirror_params).validate!
|
||||||
|
|
||||||
@project =
|
@project =
|
||||||
|
|
|
@ -2,18 +2,24 @@ class BaseForm
|
||||||
include ActiveModel::Model
|
include ActiveModel::Model
|
||||||
|
|
||||||
def check_project_category(project_category_id)
|
def check_project_category(project_category_id)
|
||||||
raise "project_category_id参数值无效." if (ProjectCategory.find_by_id project_category_id).blank?
|
raise "project_category_id参数值无效." if project_category_id && !ProjectCategory.exists?(project_category_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_project_language(project_language_id)
|
def check_project_language(project_language_id)
|
||||||
raise "project_language_id参数值无效." if (ProjectLanguage.find_by_id project_language_id).blank?
|
raise "project_language_id参数值无效." if project_language_id && !ProjectLanguage.exists?(project_language_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_repository_name(user_id, repository_name)
|
def check_repository_name(user_id, repository_name)
|
||||||
raise "仓库名称已被使用." if Repository.where(user_id: user_id, identifier: repository_name.strip).exists?
|
check_reversed_keyword(repository_name)
|
||||||
|
raise "项目标识已被使用." if Repository.where(user_id: user_id, identifier: repository_name.strip).exists?
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_project_name(user_id, project_name)
|
def check_project_name(user_id, project_name)
|
||||||
raise "项目名称已被使用." if Project.where(user_id: user_id, name: project_name.strip).exists?
|
raise "项目名称已被使用." if Project.where(user_id: user_id, name: project_name.strip).exists?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def check_reversed_keyword(repository_name)
|
||||||
|
raise "项目标识已被占用." if ReversedKeyword.is_reversed(repository_name).exists?
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
class Projects::CreateForm < BaseForm
|
class Projects::CreateForm < BaseForm
|
||||||
REPOSITORY_NAME_REGEX = /^(?!_)(?!.*?_$)[a-zA-Z0-9_-]+$/ #只含有数字、字母、下划线不能以下划线开头和结尾
|
|
||||||
attr_accessor :user_id, :name, :description, :repository_name, :project_category_id,
|
attr_accessor :user_id, :name, :description, :repository_name, :project_category_id,
|
||||||
:project_language_id, :ignore_id, :license_id, :private, :owner
|
:project_language_id, :ignore_id, :license_id, :private, :owner
|
||||||
|
|
||||||
validates :user_id, :name, :description,:repository_name,
|
validates :user_id, :name, :repository_name, presence: true
|
||||||
:project_category_id, :project_language_id, presence: true
|
validates :repository_name, format: { with: CustomRegexp::REPOSITORY_NAME_REGEX, multiline: true, message: "只能含有数字、字母、下划线且不能以下划线开头和结尾" }
|
||||||
validates :repository_name, format: { with: REPOSITORY_NAME_REGEX, multiline: true, message: "只能含有数字、字母、下划线且不能以下划线开头和结尾" }
|
|
||||||
|
|
||||||
validates :name, length: { maximum: 50 }
|
validates :name, length: { maximum: 50 }
|
||||||
validates :repository_name, length: { maximum: 100 }
|
validates :repository_name, length: { maximum: 100 }
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
class Projects::MigrateForm < BaseForm
|
class Projects::MigrateForm < BaseForm
|
||||||
REPOSITORY_NAME_REGEX = /^(?!_)(?!.*?_$)[a-zA-Z0-9_-]+$/ #只含有数字、字母、下划线不能以下划线开头和结尾
|
attr_accessor :user_id, :name, :repository_name, :project_category_id, :description,
|
||||||
URL_REGEX = /\A(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?\z/i
|
:project_language_id, :clone_addr, :private, :is_mirror, :auth_username, :auth_password, :owner
|
||||||
|
|
||||||
attr_accessor :user_id, :name, :description, :repository_name, :project_category_id, :project_language_id, :clone_addr, :private, :is_mirror, :auth_username, :auth_password, :owner
|
validates :user_id, :name, :repository_name, :clone_addr, presence: true
|
||||||
|
validates :repository_name, format: { with: CustomRegexp::REPOSITORY_NAME_REGEX, multiline: true, message: "只能含有数字、字母、下划线且不能以下划线开头和结尾" }
|
||||||
validates :user_id, :name, :description,:repository_name, :project_category_id, :project_language_id, presence: true
|
validates :clone_addr, format: { with: CustomRegexp::URL_REGEX, multiline: true, message: "地址格式不正确" }
|
||||||
validates :repository_name, format: { with: REPOSITORY_NAME_REGEX, multiline: true, message: "只能含有数字、字母、下划线且不能以下划线开头和结尾" }
|
validates :name, length: { maximum: 50 }
|
||||||
validates :clone_addr, format: { with: URL_REGEX, multiline: true, message: "地址格式不正确" }
|
validates :repository_name, length: { maximum: 100 }
|
||||||
|
validates :description, length: { maximum: 200 }
|
||||||
validate do
|
validate do
|
||||||
check_project_name(user_id, name) unless name.blank?
|
check_project_name(user_id, name) unless name.blank?
|
||||||
check_repository_name(user_id, repository_name) unless repository_name.blank?
|
check_repository_name(user_id, repository_name) unless repository_name.blank?
|
||||||
|
|
|
@ -6,4 +6,8 @@ module CustomRegexp
|
||||||
PASSWORD = /\A[a-z_A-Z0-9\-\.!@#\$%\\\^&\*\)\(\+=\{\}\[\]\/",'_<>~\·`\?:;|]{8,16}\z/
|
PASSWORD = /\A[a-z_A-Z0-9\-\.!@#\$%\\\^&\*\)\(\+=\{\}\[\]\/",'_<>~\·`\?:;|]{8,16}\z/
|
||||||
URL = /\Ahttps?:\/\/[-A-Za-z0-9+&@#\/%?=~_|!:,.;]+[-A-Za-z0-9+&@#\/%=~_|]\z/
|
URL = /\Ahttps?:\/\/[-A-Za-z0-9+&@#\/%?=~_|!:,.;]+[-A-Za-z0-9+&@#\/%=~_|]\z/
|
||||||
IP = /^((\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.){3}(\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])$/
|
IP = /^((\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.){3}(\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])$/
|
||||||
|
|
||||||
|
URL_REGEX = /\A(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?\z/i
|
||||||
|
REPOSITORY_NAME_REGEX = /^(?!_)(?!.*?_$)[a-zA-Z0-9_-]+$/ #只含有数字、字母、下划线不能以下划线开头和结尾
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -15,8 +15,8 @@ class Gitea::Organization::Repository::CreateService < Gitea::ClientService
|
||||||
private
|
private
|
||||||
|
|
||||||
def request_params
|
def request_params
|
||||||
create_params = params.merge(readme: "readme")
|
# create_params = params.merge(readme: "readme")
|
||||||
Hash.new.merge(token: token, data: create_params)
|
Hash.new.merge(token: token, data: params)
|
||||||
end
|
end
|
||||||
|
|
||||||
def url
|
def url
|
||||||
|
|
|
@ -25,8 +25,8 @@ class Gitea::Repository::CreateService < Gitea::ClientService
|
||||||
private
|
private
|
||||||
|
|
||||||
def request_params
|
def request_params
|
||||||
create_params = params.merge(readme: "readme")
|
# create_params = params.merge(readme: "readme")
|
||||||
Hash.new.merge(token: token, data: create_params)
|
Hash.new.merge(token: token, data: params)
|
||||||
end
|
end
|
||||||
|
|
||||||
def url
|
def url
|
||||||
|
|
|
@ -43,7 +43,7 @@ class Projects::CreateService < ApplicationService
|
||||||
ignore_id: params[:ignore_id],
|
ignore_id: params[:ignore_id],
|
||||||
license_id: params[:license_id],
|
license_id: params[:license_id],
|
||||||
website: params[:website],
|
website: params[:website],
|
||||||
identifier: params[:repository_name] #新增,hs
|
identifier: params[:repository_name]
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ class Repositories::MigrateService < ApplicationService
|
||||||
private: params[:hidden],
|
private: params[:hidden],
|
||||||
mirror: wrapper_mirror || false,
|
mirror: wrapper_mirror || false,
|
||||||
auth_username: params[:login],
|
auth_username: params[:login],
|
||||||
auth_password: Base64.decode64(params[:password])
|
auth_password: Base64.decode64(params[:password] || "")
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -3,18 +3,18 @@ json.login @user.login
|
||||||
json.name @user.full_name
|
json.name @user.full_name
|
||||||
json.location @user.location
|
json.location @user.location
|
||||||
json.image_url url_to_avatar(@user)
|
json.image_url url_to_avatar(@user)
|
||||||
json.url "#{request.base_url }/users/#{@user.login}"
|
json.url "#{request.base_url }/#{@user.login}"
|
||||||
json.followers_count @user.followers_count
|
json.followers_count @user.followers_count
|
||||||
json.followers_url "#{base_url}/users/#{@user.login}/fan_users"
|
json.followers_url "#{base_url}/#{@user.login}/fan_users"
|
||||||
json.following_count @user.following_count
|
json.following_count @user.following_count
|
||||||
json.following_url "#{base_url}/users/#{@user.login}/watchers"
|
json.following_url "#{base_url}/#{@user.login}/watchers"
|
||||||
json.projects_count @user.projects_count
|
json.projects_count @user.projects_count
|
||||||
json.projects_url "#{base_url}/users/#{@user.login}"
|
json.projects_url "#{base_url}/#{@user.login}"
|
||||||
json.projects_count @user.projects_count
|
json.projects_count @user.projects_count
|
||||||
json.is_watch current_user&.watched?(@user)
|
json.is_watch current_user&.watched?(@user)
|
||||||
json.organizations @user.organizations do |organization|
|
json.organizations @user.organizations do |organization|
|
||||||
json.login organization.login
|
json.login organization.login
|
||||||
json.name organization.real_name
|
json.name organization.real_name
|
||||||
json.image_url url_to_avatar(organization)
|
json.image_url url_to_avatar(organization)
|
||||||
json.url "#{base_url}/organize/#{organization.login}"
|
json.url "#{base_url}/#{organization.login}"
|
||||||
end
|
end
|
|
@ -1,51 +0,0 @@
|
||||||
# 新版Git测试说明
|
|
||||||
统一:
|
|
||||||
参考实训:http://47.96.87.25:48080/shixuns/ca9fvobr/repository
|
|
||||||
请求方式:POST
|
|
||||||
参数{repo_path: "educoder/ca9fvobr.git"}
|
|
||||||
公共方法:
|
|
||||||
['add_repository', 'fork_repository', 'delete_repository', 'file_tree', 'update_file',
|
|
||||||
'file_content', 'commits']
|
|
||||||
|
|
||||||
1、仓库目录接口
|
|
||||||
测试方法:模拟1000个用户同时去访问接口,访问方式
|
|
||||||
http://121.199.19.206:9000/api/file_tree
|
|
||||||
参数:
|
|
||||||
{repo_path: "educoder/ca9fvobr.git", path: ''} // 如:{path: 'step1'}
|
|
||||||
|
|
||||||
2、创建版本库
|
|
||||||
访问地址:http://121.199.19.206:9000/api/add_repository
|
|
||||||
参数:
|
|
||||||
{repo_path: 比如:"Hjqreturn/aaass1.git"}
|
|
||||||
|
|
||||||
3、fork版本库
|
|
||||||
http://121.199.19.206:9000/api/fork_repository
|
|
||||||
参数:
|
|
||||||
{repo_path: 'Hjqreturn/aaass1.git', fork_repository_path: 'educoder/ca9fvobr.git'}
|
|
||||||
说明:fork_repository_path是新项目的repo_path, repo_path是源项目的
|
|
||||||
|
|
||||||
|
|
||||||
4、更新文件
|
|
||||||
测试方法:
|
|
||||||
1、更新同一个文件,并发量可以不用很大,可以用同一个用户并发10-100
|
|
||||||
2、更新不同的文件:可以依据创建的版本库去更新
|
|
||||||
访问地址:http://121.199.19.206:9000/api/update_file
|
|
||||||
参数:
|
|
||||||
{repo_path: "educoder/ca9fvobr.git",
|
|
||||||
file_path: 'step1/main.py',
|
|
||||||
message: 'commit by test',
|
|
||||||
content: 'afdjadsjfj1111',
|
|
||||||
author_name: 'guange',
|
|
||||||
author_email: '8863824@gmil.com'}
|
|
||||||
|
|
||||||
5、获取文件内容
|
|
||||||
访问地址:http://121.199.19.206:9000/api/file_content
|
|
||||||
参数:
|
|
||||||
{repo_path: "educoder/ca9fvobr.git", path: 'step1/main.py',}
|
|
||||||
|
|
||||||
6、获取提交记录
|
|
||||||
访问地址:http://121.199.19.206:9000/api/commits
|
|
||||||
参数:
|
|
||||||
{repo_path: 比如:"educoder/ca9fvobr.git"}
|
|
||||||
|
|
||||||
|
|
|
@ -1,72 +0,0 @@
|
||||||
mbtclufr
|
|
||||||
9op3hs4j
|
|
||||||
96ctv7yr
|
|
||||||
rtmzxfke
|
|
||||||
ofqxthrf
|
|
||||||
czu9w4gj
|
|
||||||
9fpzj6et
|
|
||||||
pwhc865b
|
|
||||||
maozpx4l
|
|
||||||
y5wh2ofx
|
|
||||||
b5rzhpf3
|
|
||||||
bs243nrl
|
|
||||||
47fn2yfb
|
|
||||||
kwotfxey
|
|
||||||
w5468sbp
|
|
||||||
fyekprio
|
|
||||||
q6ze5fih
|
|
||||||
b5hjq9zm
|
|
||||||
ky8pbqux
|
|
||||||
53phc7nq
|
|
||||||
b9j2yuix
|
|
||||||
9t3uphwk
|
|
||||||
iokm8ah2
|
|
||||||
qlsy6xb4
|
|
||||||
345bqhfi
|
|
||||||
v728fqia
|
|
||||||
4euftvf2
|
|
||||||
f23sef5m
|
|
||||||
nhqis8m9
|
|
||||||
qp72tb5x
|
|
||||||
gt3anszw
|
|
||||||
tng6heyf
|
|
||||||
nb9keawo
|
|
||||||
elgnbkp9
|
|
||||||
4neslomg
|
|
||||||
lh35s6ma
|
|
||||||
xmc4rpay
|
|
||||||
qrpaxi6b
|
|
||||||
9fla2zry
|
|
||||||
efuibzrm
|
|
||||||
fzp3iu4w
|
|
||||||
pligsyn8
|
|
||||||
glbksr29
|
|
||||||
kfm7ghyc
|
|
||||||
p6hk3svf
|
|
||||||
p539gjhm
|
|
||||||
am5o73er
|
|
||||||
4x3qwrbe
|
|
||||||
fqosyl8g
|
|
||||||
of5z3fci
|
|
||||||
tb7hw62n
|
|
||||||
ie6zxg7r
|
|
||||||
4q2bmy9h
|
|
||||||
fpm3u5yb
|
|
||||||
nikx3ojt
|
|
||||||
vt82s9bq
|
|
||||||
ma59fefo
|
|
||||||
lxa39tfq
|
|
||||||
4gnockxf
|
|
||||||
nxwg84ey
|
|
||||||
fmie8nzb
|
|
||||||
w5nsr24v
|
|
||||||
4hn3efwc
|
|
||||||
h9ljfbq7
|
|
||||||
nuv54t8b
|
|
||||||
2te9fmfq
|
|
||||||
vihnsayz
|
|
||||||
qhlyn82s
|
|
||||||
vw74kmfr
|
|
||||||
vcta36bz
|
|
||||||
henz425l
|
|
||||||
g529v38z
|
|
Loading…
Reference in New Issue