dev_forge
SylorHuang 5 years ago
commit ba4813ccee

@ -248,6 +248,9 @@ curl -X POST \
-d "repository_name=gorails" \
-d "project_category_id=1" \
-d "project_language_id=2" \
-d "ignore_id=2000" \
-d "license_id=1" \
-d "private=true"
http://localhost:3000/api/projects/ | jq
```
*请求参数说明:*
@ -273,6 +276,54 @@ http://localhost:3000/api/projects/ | jq
|name |string|项目名称|
返回值
```
{
"id": 3240,
"name": "好项目"
}
```
---
#### 新建镜像项目
```
POST api/projects/migrate
```
*示例*
```
curl -X POST \
-d "user_id=36401" \
-d "clone_addr=https://gitea.com/CasperVector/slew.git"
-d "name=好项目" \
-d "description=my first project" \
-d "repository_name=gorails" \
-d "project_category_id=1" \
-d "project_language_id=2" \
-d "private=true"
http://localhost:3000/api/projects/ | jq
```
*请求参数说明:*
|参数名|必选|类型|说明|
-|-|-|-
|user_id |是|int |用户id或者组织id |
|name |是|string |项目名称 |
|clone_addr |是|string |镜像项目clone地址 |
|description |否|string |项目描述 |
|repository_name |是|string |仓库名称, 只含有数字、字母、下划线不能以下划线开头和结尾,且唯一 |
|project_category_id|是|int |项目类别id |
|project_language_id|是|int |项目语言id |
|private |否|boolean|项目是否私有, true为私有false: 公开,默认为公开 |
*返回参数说明:*
|参数名|类型|说明|
-|-|-
|id |int |id |
|name |string|项目名称|
返回值
```
{

@ -14,9 +14,24 @@ class ProjectsController < ApplicationController
tip_exception(e.message)
end
def migrate
ActiveRecord::Base.transaction do
Projects::MigrateForm.new(mirror_params).validate!
@project = Projects::MigrateService.new(current_user, mirror_params).call
end
rescue Exception => e
uid_logger_error(e.message)
tip_exception(e.message)
end
private
def project_params
params.permit(:user_id, :name, :description, :repository_name,
:project_category_id, :project_language_id, :license_id, :ignore_id)
end
def mirror_params
params.permit(:user_id, :name, :description, :repository_name,
:project_category_id, :project_language_id, :clone_addr, :private)
end
end

@ -1,3 +1,19 @@
class BaseForm
include ActiveModel::Model
def check_project_category(project_category_id)
raise "project_category_id参数值无效." if (ProjectCategory.find_by_id project_category_id).blank?
end
def check_project_language(project_language_id)
raise "project_language_id参数值无效." if (ProjectLanguage.find_by_id project_language_id).blank?
end
def check_repository_name(user_id, repository_name)
raise "仓库名称已被使用." if Repository.where(user_id: user_id, identifier: repository_name.strip).exists?
end
def check_project_name(user_id, project_name)
raise "项目名称已被使用." if Project.where(user_id: user_id, name: project_name.strip).exists?
end
end

@ -5,11 +5,13 @@ class Projects::CreateForm < BaseForm
validates :user_id, :name, :description,:repository_name,
:project_category_id, :project_language_id, presence: true
# validates_format_of :repository_name, with: REPOSITORY_NAME_REGEX, multiline: true
validates :repository_name, format: { with: REPOSITORY_NAME_REGEX, multiline: true,
message: "只能含有数字、字母、下划线且不能以下划线开头和结尾" }
validates :repository_name, format: { with: REPOSITORY_NAME_REGEX, multiline: true, message: "只能含有数字、字母、下划线且不能以下划线开头和结尾" }
validate :check_ignore, :check_license
validate do
check_project_category(project_category_id)
check_project_language(project_language_id)
end
def check_license
raise "license_id值无效. " if license_id && License.find_by(id: license_id).blank?

@ -0,0 +1,17 @@
class Projects::MigrateForm < BaseForm
REPOSITORY_NAME_REGEX = /^(?!_)(?!.*?_$)[a-zA-Z0-9_-]+$/ #只含有数字、字母、下划线不能以下划线开头和结尾
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
attr_accessor :user_id, :name, :description, :repository_name, :project_category_id, :project_language_id, :clone_addr, :private
validates :user_id, :name, :description,:repository_name, :project_category_id, :project_language_id, presence: true
validates :repository_name, format: { with: REPOSITORY_NAME_REGEX, multiline: true, message: "只能含有数字、字母、下划线且不能以下划线开头和结尾" }
validates :clone_addr, format: { with: URL_REGEX, multiline: true, message: "地址格式不正确" }
validate do
check_project_name(user_id, name)
check_repository_name(user_id, repository_name)
check_project_category(project_category_id)
check_project_language(project_language_id)
end
end

@ -1,6 +1,7 @@
class Repository < ApplicationRecord
self.inheritance_column = nil # FIX The single-table inheritance mechanism failed
belongs_to :project
belongs_to :user
validates :identifier, presence: true, uniqueness: true
end

@ -146,6 +146,9 @@ class User < ApplicationRecord
# 项目
has_many :applied_projects, dependent: :destroy
has_many :projects, dependent: :destroy
has_many :repositories, dependent: :destroy
# 教学案例
has_many :libraries, dependent: :destroy

@ -0,0 +1,47 @@
class Gitea::Repository::MigrateService < Gitea::ClientService
attr_reader :token, :params
# params description:
# {
# auth_username string
# clone_addr* string #clone地址
# description string
# issues boolean
# labels boolean
# milestones boolean
# mirror boolean
# private boolean
# pull_requests boolean
# releases boolean
# repo_name* string #仓库名称
# uid* integer($int64) #gitea用户id或组织id
# wiki boolean
# }
# EX:
# params = {
# clone_addr: 'xxx.com',
# repo_name: 'repo_name',
# uid: 2,
# private: false
# }
def initialize(token, params)
@token = token
@params = params
end
def call
post(url, request_params)
end
private
def request_params
Hash.new.merge(token: token, data: params)
end
def url
"/repos/migrate".freeze
end
end

@ -0,0 +1,49 @@
class Projects::MigrateService < ApplicationService
attr_reader :user, :params
def initialize(user, params)
@user = user
@params = params
end
def call
@project = Project.new(project_params)
ActiveRecord::Base.transaction do
if @project.save!
Repositories::MigrateService.new(user, @project, repository_params).call
else
#
end
end
@project
rescue => e
puts "create mirror project service error: #{e.message}"
raise Error, e.message
end
private
def project_params
{
name: params[:name],
user_id: params[:user_id],
description: params[:description],
project_category_id: params[:project_category_id],
project_language_id: params[:project_language_id],
is_public: get_is_public
}
end
def repository_params
{
hidden: get_is_public,
identifier: params[:repository_name],
mirror_url: params[:clone_addr],
user_id: user.id
}
end
def get_is_public
params[:private] || false
end
end

@ -0,0 +1,51 @@
class Repositories::MigrateService < ApplicationService
attr_reader :user, :project, :params
def initialize(user, project, params)
@project = project
@user = user
@params = params
end
def call
@repository = Repository.new(repository_params)
ActiveRecord::Base.transaction do
if @repository.save!
gitea_repository = Gitea::Repository::MigrateService.new(user.gitea_token, gitea_repository_params).call
sync_project(gitea_repository)
sync_repository(@repository, gitea_repository)
end
@repository
end
rescue => e
puts "create mirror repository service error: #{e.message}"
raise Error, e.message
end
private
def sync_project(gitea_repository)
project.update_columns(gpid: gitea_repository["id"]) if gitea_repository
end
def sync_repository(repository, gitea_repository)
repository.update_columns(url: remote_repository_url) if gitea_repository
end
def remote_repository_url
[Gitea.gitea_config[:domain], '/', user.login, '/', params[:identifier], ".git"].join("")
end
def repository_params
params.merge(project_id: project.id,)
end
def gitea_repository_params
{
clone_addr: params[:mirror_url],
repo_name: params[:identifier],
uid: user.gitea_uid,
private: params[:hidden]
}
end
end

@ -0,0 +1 @@
json.extract! @project, :id, :name

@ -32,7 +32,11 @@ Rails.application.routes.draw do
resources :ignores, only: [:index, :show]
resources :licenses, only: [:index, :show]
resources :projects, only: [:index, :create]
resources :projects, only: [:index, :create, :show] do
collection do
post :migrate
end
end
# resources :memos do
# member do

@ -0,0 +1,10 @@
class AddUserRefToRepository < ActiveRecord::Migration[5.2]
def change
add_column :repositories, :user_id, :integer
add_index :repositories, :user_id
Project.joins(:repository).find_each do |project|
project&.repository&.update_column(:user_id, project&.user_id) unless project&.repository.blank?
end
end
end

@ -0,0 +1,5 @@
class AddGiteaUidToUsers < ActiveRecord::Migration[5.2]
def change
add_column :users, :gitea_uid, :integer
end
end

@ -0,0 +1,5 @@
class AddMirrorUrlToRepositories < ActiveRecord::Migration[5.2]
def change
add_column :repositories, :mirror_url, :string
end
end
Loading…
Cancel
Save