Class: BB::BBSpecManager

Inherits:
Object
  • Object
show all
Defined in:
lib/cocoapods-privacy/common/BBSpecManager.rb

Instance Method Summary collapse

Constructor Details

#initialize(type) ⇒ BBSpecManager

Returns a new instance of BBSpecManager.



5
6
7
# File 'lib/cocoapods-privacy/common/BBSpecManager.rb', line 5

def initialize(type)
    @type = type
end

Instance Method Details

#check(podspec_file_path) ⇒ Object



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/cocoapods-privacy/common/BBSpecManager.rb', line 10

def check(podspec_file_path)
    # Step 1: 读取podspec
    lines = read_podspec(podspec_file_path)
    
    # Step 2: 逐行解析并转位BBRow 模型
    rows = parse_row(lines)

    # Step 3.1:如果Row 是属于Spec 内,那么聚拢成BBSpec,
    # Step 3.2:BBSpec 内使用数组存储其Spec 内的行
    # Step 3.3 在合适位置给每个有效的spec都创建一个 隐私模版,并修改其podspec 引用
    combin_sepcs_and_rows = combin_sepc_if_need(rows,podspec_file_path)

    # Step 4: 展开修改后的Spec,重新转换成 BBRow
    rows = unfold_sepc_if_need(combin_sepcs_and_rows)

    # Step 5: 打开隐私模版,并修改其podspec文件,并逐行写入
    File.open(podspec_file_path, 'w') do |file|
    # 逐行写入 rows
    rows.each do |row|
        file.puts(row.content)
    end
    end


    # Step 6: 获取privacy 相关信息,传递给后续处理
    hash = fetch_hash(combin_sepcs_and_rows,podspec_file_path).compact
    filtered_hash = hash.reject { |_, value| value.empty? }
    filtered_hash
end

#combin_sepc_if_need(rows, podspec_file_path) ⇒ Object

数据格式:[

BBRow
BBRow
BBSpec
  rows
      [
         BBRow
         BBSpec 
         BBRow
         BBRow
      ] 
BBRow
......

] 合并Row -> Spec(会存在部分行不在Spec中:Spec new 之前的注释)



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/cocoapods-privacy/common/BBSpecManager.rb', line 87

def combin_sepc_if_need(rows,podspec_file_path) 
    spec_stack = []
    result_rows = []
    default_name = File.basename(podspec_file_path, File.extname(podspec_file_path))

    rows.each do |row|
    if row.is_spec_start 
        # 获取父spec
        parent_spec = spec_stack.last 

        # 创建 spec
        name = row.content.split("'")[1]&.strip || default_name
        alias_name = row.content.split("|")[1]&.strip
        full_name = parent_spec ? parent_spec.uniq_full_name_in_parent(name) : name

        spec = BBSpec.new(name,alias_name,full_name,@type)
        spec.rows << row
        spec.parent = parent_spec

        # 当存在 spec 时,存储在 spec.rows 中;不存在时,直接存储在外层
        (parent_spec ? parent_spec.rows : result_rows ) << spec

        # spec 入栈
        spec_stack.push(spec)
    elsif row.is_spec_end
        # 当前 spec 的 rows 加入当前行
        spec_stack.last&.rows << row

        #执行隐私协议修改
        spec_stack.last.privacy_handle(podspec_file_path)

        # spec 出栈
        spec_stack.pop
    else
        # 当存在 spec 时,存储在 spec.rows 中;不存在时,直接存储在外层
        (spec_stack.empty? ? result_rows : spec_stack.last.rows) << row
    end
    end

    result_rows
end

#fetch_hash(rows, podspec_file_path) ⇒ Object



143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/cocoapods-privacy/common/BBSpecManager.rb', line 143

def fetch_hash(rows,podspec_file_path)
    hash = {}
    specs = rows.select { |row| row.is_a?(BBSpec) }
    specs.each do |spec|
        value = spec.sources_files ? {KSource_Files_Key => spec.sources_files,KExclude_Files_Key => spec.exclude_files || []} : {}
        if is_handle_privacy
            hash[File.join(File.dirname(podspec_file_path),spec.privacy_file)] = value
        elsif is_handle_confuse
            hash[File.join(File.dirname(podspec_file_path),spec.confuse_file)] = value
        end
        hash.merge!(fetch_hash(spec.rows,podspec_file_path))
    end
    hash
end

#is_handle_confuseObject



162
163
164
# File 'lib/cocoapods-privacy/common/BBSpecManager.rb', line 162

def is_handle_confuse
    @type.include?(KSpecTypeConfuse)
end

#is_handle_privacyObject



158
159
160
# File 'lib/cocoapods-privacy/common/BBSpecManager.rb', line 158

def is_handle_privacy
  @type.include?(KSpecTypePrivacy)
end

#parse_row(lines) ⇒ Object



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/cocoapods-privacy/common/BBSpecManager.rb', line 46

def parse_row(lines)
    rows = []  
    code_stack = [] #栈,用来排除if end 等对spec 的干扰

    lines.each do |line|
    content = line.strip
    is_comment = content.start_with?('#')
    is_spec_start = !is_comment && (content.include?('Pod::Spec.new') || content.include?('.subspec'))
    is_if = !is_comment && content.start_with?('if')  
    is_end = !is_comment && content.start_with?('end')

    # 排除if end 对spec_end 的干扰
    code_stack.push('spec') if is_spec_start 
    code_stack.push('if') if is_if 
    stack_last = code_stack.last 
    is_spec_end = is_end && stack_last && stack_last == 'spec'
    is_if_end = is_end && stack_last && stack_last == 'if'
    code_stack.pop if is_spec_end || is_if_end

    row = BBRow.new(line, is_comment, is_spec_start, is_spec_end)
    rows << row
    end
    rows
end

#read_podspec(file_path) ⇒ Object



41
42
43
44
# File 'lib/cocoapods-privacy/common/BBSpecManager.rb', line 41

def read_podspec(file_path)
    # puts "read_podspec = #{file_path}"
    File.readlines(file_path)
end

#unfold_sepc_if_need(rows) ⇒ Object

把所有的spec中的rows 全部展开,拼接成一级数组【BBRow】



130
131
132
133
134
135
136
137
138
139
140
# File 'lib/cocoapods-privacy/common/BBSpecManager.rb', line 130

def unfold_sepc_if_need(rows)
    result_rows = []
    rows.each do |row|
    if row.is_a?(BBSpec) 
        result_rows += unfold_sepc_if_need(row.rows)
    else
        result_rows << row
    end
    end
    result_rows
end