首页
ARTS 04 - 使用 Gitlab + Generic Webhook Trigger 触发 Jenkins 自动化构建

ARTS左耳朵耗子 提出来的一个打卡任务。每周一个 Algorithm,Review 一篇英文文章,总结一个工作中的技术 Tip,以及 Share 一个传递价值观的东西!我希望这个事可以给大家得到相应的算法、代码、技术和影响力的训练。

这是我的第四周打卡。标题为”使用 Gitlab + Generic Webhook Trigger 触发 Jenkins 自动化构建”。这周主要想分享的是使用 Jenkins 构建 CI/CD 流程中的一些心得。

🤖 Algorithm

环形链表

📖 Review

Using Functions in Elixir Guard Clauses

这篇文件介绍的是如何在 Elixir 的守卫语句中使用自定义函数的思路。默认情况下,在 Elixir 的守卫语句中是不允许使用自定义函数的,如果这么做,会报一个如下的错误。

> elixir guards.exs
** (CompileError) guards.exs:18: cannot invoke local kid?/1 inside guard
    guards.exs:18: (module)

作者解释了一下原因。Erlang 的创建者为了保证守卫语句的快速以及纯度,所以限制了守卫语句只能使用内建的函数。因为他没法确定用户自定的函数是否是快速的纯函数。

但是,这并不意味着我们没有选择的余地。我们可以把自定义的函数定义为宏来实现,这主要得益于 Elixir 的元编程。

最后的结论是,虽然可以这样实现,但是我们需要考虑为什么会有这种局限性。作者在设计语言的时候,会去权衡利弊,编程的很大一部分是权衡。所以一旦我们考虑了问题的局限性,就更容易理解作者为什么要做出他们的权衡。

💡 Tip

Elixir return eraly

这周在写Elixir的代码时,发现没有return关键字。之前使用的语言,包括JavaJavascriptphpc#都是有return关键字的。

在写代码时,我们都习惯先去判断错误的分支,然后return结束掉。在Elixir中没有return关键字怎么办,我们可以通过使用其它的一些手段来提前结束掉代码。这些手段如下:

  1. 流程语句:if/unlesscasecond
  2. 哨兵子句(Guard)
  3. with

一开始很不习惯,有点不明白作者设计的意图是为什么。尝试一段时间后,发现代码的整洁度比之前的return写法好多了,可以举个例子说明一下:

比如我们需要对一个业务做很多检查,如果使用return的写法,代码可能是这样的:

# 检查格式
if(!check_form_validation()){
    ...
    return
}
...
# 业务检查
if(!check_business1()){
    ...
    return
}
...
if(!check_business2()){
    ...
    return
}
...
if(...){
    return
}
...

甚至有些情况我们可能连check_form_validation()check_business1()这些检查的逻辑都直接写在方法体里,没有抽成一个方法。随着业务不断增加,到时候一个方法里面错误分支的代码越来越多,happy case 可能就是一两句代码。

这样导致的问题是,一方面助长程序员去写意大利面条式代码;另一方面,方法严重违背了单一职责的原则。

没有return后,我们就需要考虑怎么去组织代码的结构,整个代码的结构可能是下面的样子:

 with :ok <- check_form_validation(),
         :ok <- check_business1(),
         :ok <- check_business2() do
      # happy case 业务逻辑
      {:ok, %{file_url: full_path, file_name: file_name}}
    else
      # 错误分逻辑    
      {:error, msg} -> {:error, msg}

整个代码的逻辑变得十分清晰,如果以上条件都满足后需要干什么;当运行到某个函数时不满足就会走到错误分支。另一个好处是保证了我们函数返回的数据结构都是一致的。

另一种写法是哨兵子句,主要是针对某个具体的函数的。比如我们拿上传文件来举个例子,我们要检查文件的格式、大小等等。我们可以这样来写:

def upload_file(%{"file" => file} = params) when is_nil(file), do: "File can not empty"

def upload_file(%{"file" => file} = params) when file.size > 1000, do: "File size exceed"

def upload_file(%{"file" => file} = params) do
#上传文件
end

💎 Share

分享文章:使用 Gitlab + Generic Webhook Trigger 触发 Jenkins 自动化构建

这周在用 Jenkins 持续优化项目的 CI/CD 流程时,总结的一些心得。在 Jenkins 的使用过程中,我发现实践很重要,很多工具、比较好的实践都需要自己去查找一些资料,然后真正地去项目中实践才能掌握。